hgbook
changeset 712:e8763d4b37b1
Merge with http://hg.serpentine.com/mercurial/book
author | Dongsheng Song <dongsheng.song@gmail.com> |
---|---|
date | Thu May 21 14:16:17 2009 +0800 (2009-05-21) |
parents | 364d2ce9e055 5225ec140003 |
children | f87515a4a3cf |
files | en/appA-cmdref.xml en/ch01-tour-basic.xml en/ch02-tour-merge.xml en/ch03-concepts.xml en/ch04-daily.xml en/ch05-collab.xml en/ch06-filenames.xml en/ch07-branch.xml en/ch08-undo.xml en/ch09-hook.xml en/ch10-template.xml en/ch11-mq.xml en/ch12-mq-collab.xml en/ch13-hgext.xml en/examples/data/check_whitespace.py en/examples/hook.ws |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgtags Thu May 21 14:16:17 2009 +0800 1.3 @@ -0,0 +1,1 @@ 1.4 +18131160f7ee3b81bf39ce2c58f762b8d671cef3 submitted
2.1 --- a/en/00book.xml Sat Apr 18 11:52:33 2009 +0800 2.2 +++ b/en/00book.xml Thu May 21 14:16:17 2009 +0800 2.3 @@ -8,20 +8,21 @@ 2.4 <!-- Chapters. --> 2.5 2.6 <!ENTITY ch00 SYSTEM "ch00-preface.xml"> 2.7 -<!ENTITY ch01 SYSTEM "ch01-tour-basic.xml"> 2.8 -<!ENTITY ch02 SYSTEM "ch02-tour-merge.xml"> 2.9 -<!ENTITY ch03 SYSTEM "ch03-concepts.xml"> 2.10 -<!ENTITY ch04 SYSTEM "ch04-daily.xml"> 2.11 -<!ENTITY ch05 SYSTEM "ch05-collab.xml"> 2.12 -<!ENTITY ch06 SYSTEM "ch06-filenames.xml"> 2.13 -<!ENTITY ch07 SYSTEM "ch07-branch.xml"> 2.14 -<!ENTITY ch08 SYSTEM "ch08-undo.xml"> 2.15 -<!ENTITY ch09 SYSTEM "ch09-hook.xml"> 2.16 -<!ENTITY ch10 SYSTEM "ch10-template.xml"> 2.17 -<!ENTITY ch11 SYSTEM "ch11-mq.xml"> 2.18 -<!ENTITY ch12 SYSTEM "ch12-mq-collab.xml"> 2.19 -<!ENTITY ch13 SYSTEM "ch13-hgext.xml"> 2.20 -<!ENTITY appA SYSTEM "appA-cmdref.xml"> 2.21 +<!ENTITY ch01 SYSTEM "ch01-intro.xml"> 2.22 +<!ENTITY ch02 SYSTEM "ch02-tour-basic.xml"> 2.23 +<!ENTITY ch03 SYSTEM "ch03-tour-merge.xml"> 2.24 +<!ENTITY ch04 SYSTEM "ch04-concepts.xml"> 2.25 +<!ENTITY ch05 SYSTEM "ch05-daily.xml"> 2.26 +<!ENTITY ch06 SYSTEM "ch06-collab.xml"> 2.27 +<!ENTITY ch07 SYSTEM "ch07-filenames.xml"> 2.28 +<!ENTITY ch08 SYSTEM "ch08-branch.xml"> 2.29 +<!ENTITY ch09 SYSTEM "ch09-undo.xml"> 2.30 +<!ENTITY ch10 SYSTEM "ch10-hook.xml"> 2.31 +<!ENTITY ch11 SYSTEM "ch11-template.xml"> 2.32 +<!ENTITY ch12 SYSTEM "ch12-mq.xml"> 2.33 +<!ENTITY ch13 SYSTEM "ch13-mq-collab.xml"> 2.34 +<!ENTITY ch14 SYSTEM "ch14-hgext.xml"> 2.35 +<!ENTITY appA SYSTEM "appA-svn.xml"> 2.36 <!ENTITY appB SYSTEM "appB-mq-ref.xml"> 2.37 <!ENTITY appC SYSTEM "appC-srcinstall.xml"> 2.38 <!ENTITY appD SYSTEM "appD-license.xml"> 2.39 @@ -96,6 +97,10 @@ 2.40 &ch12; 2.41 <!-- BEGIN ch13 --> 2.42 &ch13; 2.43 + <!-- BEGIN ch14 --> 2.44 + &ch14; 2.45 + <!-- BEGIN appA --> 2.46 + &appA; 2.47 <!-- BEGIN appB --> 2.48 &appB; 2.49 <!-- BEGIN appC -->
3.1 --- a/en/Makefile Sat Apr 18 11:52:33 2009 +0800 3.2 +++ b/en/Makefile Thu May 21 14:16:17 2009 +0800 3.3 @@ -35,7 +35,6 @@ 3.4 filenames \ 3.5 hook.msglen \ 3.6 hook.simple \ 3.7 - hook.ws \ 3.8 issue29 \ 3.9 mq.guards \ 3.10 mq.qinit-help \
4.1 --- a/en/appA-cmdref.xml Sat Apr 18 11:52:33 2009 +0800 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,224 +0,0 @@ 4.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 4.5 - 4.6 -<appendix id="cmdref"> 4.7 - <?dbhtml filename="command-reference.html"?> 4.8 -<title>Command reference</title> 4.9 - 4.10 -<para id="x_653">\cmdref{add}{add files at the next commit} 4.11 -\optref{add}{I}{include} 4.12 -\optref{add}{X}{exclude} 4.13 -\optref{add}{n}{dry-run}</para> 4.14 - 4.15 -<para id="x_654">\cmdref{diff}{print changes in history or working directory}</para> 4.16 - 4.17 -<para id="x_655">Show differences between revisions for the specified files or 4.18 -directories, using the unified diff format. For a description of the 4.19 -unified diff format, see <xref linkend="sec:mq:patch"/>.</para> 4.20 - 4.21 -<para id="x_656">By default, this command does not print diffs for files that Mercurial 4.22 -considers to contain binary data. To control this behavior, see the 4.23 -<option role="hg-opt-diff">-a</option> and <option role="hg-opt-diff">--git</option> options.</para> 4.24 - 4.25 -<sect2> 4.26 -<title>Options</title> 4.27 -x 4.28 -<para id="x_657">\loptref{diff}{nodates}</para> 4.29 - 4.30 -<para id="x_658">Omit date and time information when printing diff headers.</para> 4.31 - 4.32 -<para id="x_659">\optref{diff}{B}{ignore-blank-lines}</para> 4.33 - 4.34 -<para id="x_65a">Do not print changes that only insert or delete blank lines. A line 4.35 -that contains only whitespace is not considered blank. 4.36 -</para> 4.37 - 4.38 -<para id="x_65b">\optref{diff}{I}{include} 4.39 -</para> 4.40 - 4.41 -<para id="x_65c">Include files and directories whose names match the given patterns. 4.42 -</para> 4.43 - 4.44 -<para id="x_65d">\optref{diff}{X}{exclude} 4.45 -</para> 4.46 - 4.47 -<para id="x_65e">Exclude files and directories whose names match the given patterns. 4.48 -</para> 4.49 - 4.50 -<para id="x_65f">\optref{diff}{a}{text} 4.51 -</para> 4.52 - 4.53 -<para id="x_660">If this option is not specified, <command role="hg-cmd">hg diff</command> will refuse to print 4.54 -diffs for files that it detects as binary. Specifying <option role="hg-opt-diff">-a</option> 4.55 -forces <command role="hg-cmd">hg diff</command> to treat all files as text, and generate diffs for 4.56 -all of them. 4.57 -</para> 4.58 - 4.59 -<para id="x_661">This option is useful for files that are <quote>mostly text</quote> but have a 4.60 -few embedded NUL characters. If you use it on files that contain a 4.61 -lot of binary data, its output will be incomprehensible. 4.62 -</para> 4.63 - 4.64 -<para id="x_662">\optref{diff}{b}{ignore-space-change} 4.65 -</para> 4.66 - 4.67 -<para id="x_663">Do not print a line if the only change to that line is in the amount 4.68 -of white space it contains. 4.69 -</para> 4.70 - 4.71 -<para id="x_664">\optref{diff}{g}{git} 4.72 -</para> 4.73 - 4.74 -<para id="x_665">Print <command>git</command>-compatible diffs. XXX reference a format 4.75 -description. 4.76 -</para> 4.77 - 4.78 -<para id="x_666">\optref{diff}{p}{show-function} 4.79 -</para> 4.80 - 4.81 -<para id="x_667">Display the name of the enclosing function in a hunk header, using a 4.82 -simple heuristic. This functionality is enabled by default, so the 4.83 -<option role="hg-opt-diff">-p</option> option has no effect unless you change the value of 4.84 -the <envar role="rc-item-diff">showfunc</envar> config item, as in the following example.</para> 4.85 - 4.86 -<!-- &interaction.cmdref.diff-p; --> 4.87 - 4.88 -<para id="x_668">\optref{diff}{r}{rev} 4.89 -</para> 4.90 - 4.91 -<para id="x_669">Specify one or more revisions to compare. The <command role="hg-cmd">hg diff</command> command 4.92 -accepts up to two <option role="hg-opt-diff">-r</option> options to specify the revisions to 4.93 -compare. 4.94 -</para> 4.95 - 4.96 -<orderedlist> 4.97 -<listitem><para id="x_66a">Display the differences between the parent revision of the 4.98 - working directory and the working directory. 4.99 -</para> 4.100 -</listitem> 4.101 -<listitem><para id="x_66b">Display the differences between the specified changeset and the 4.102 - working directory. 4.103 -</para> 4.104 -</listitem> 4.105 -<listitem><para id="x_66c">Display the differences between the two specified changesets. 4.106 -</para> 4.107 -</listitem></orderedlist> 4.108 - 4.109 -<para id="x_66d">You can specify two revisions using either two <option role="hg-opt-diff">-r</option> 4.110 -options or revision range notation. For example, the two revision 4.111 -specifications below are equivalent. 4.112 -</para> 4.113 -<programlisting>hg diff -r 10 -r 20 4.114 -hg diff -r10:20</programlisting> 4.115 - 4.116 -<para id="x_66e">When you provide two revisions, Mercurial treats the order of those 4.117 -revisions as significant. Thus, <command role="hg-cmd">hg diff -r10:20</command> will 4.118 -produce a diff that will transform files from their contents as of 4.119 -revision 10 to their contents as of revision 20, while 4.120 -<command role="hg-cmd">hg diff -r20:10</command> means the opposite: the diff that will 4.121 -transform files from their revision 20 contents to their revision 10 4.122 -contents. You cannot reverse the ordering in this way if you are 4.123 -diffing against the working directory. 4.124 -</para> 4.125 - 4.126 -<para id="x_66f">\optref{diff}{w}{ignore-all-space} 4.127 -</para> 4.128 - 4.129 -<para id="x_670">\cmdref{version}{print version and copyright information} 4.130 -</para> 4.131 - 4.132 -<para id="x_671">This command displays the version of Mercurial you are running, and 4.133 -its copyright license. There are four kinds of version string that 4.134 -you may see. 4.135 -</para> 4.136 -<itemizedlist> 4.137 -<listitem><para id="x_672">The string <quote><literal>unknown</literal></quote>. This version of Mercurial was 4.138 - not built in a Mercurial repository, and cannot determine its own 4.139 - version. 4.140 -</para> 4.141 -</listitem> 4.142 -<listitem><para id="x_673">A short numeric string, such as <quote><literal>1.1</literal></quote>. This is a 4.143 - build of a revision of Mercurial that was identified by a specific 4.144 - tag in the repository where it was built. (This doesn't necessarily 4.145 - mean that you're running an official release; someone else could 4.146 - have added that tag to any revision in the repository where they 4.147 - built Mercurial.) 4.148 -</para> 4.149 -</listitem> 4.150 -<listitem><para id="x_674">A hexadecimal string, such as <quote><literal>875489e31abe</literal></quote>. This 4.151 - is a build of the given revision of Mercurial. 4.152 -</para> 4.153 -</listitem> 4.154 -<listitem><para id="x_675">A hexadecimal string followed by a date, such as 4.155 - <quote><literal>875489e31abe+20070205</literal></quote>. This is a build of the given 4.156 - revision of Mercurial, where the build repository contained some 4.157 - local changes that had not been committed. 4.158 -</para> 4.159 -</listitem></itemizedlist> 4.160 - 4.161 -</sect2> 4.162 -<sect2> 4.163 -<title>Tips and tricks</title> 4.164 - 4.165 -<sect3 id="cmdref:diff-vs-status"> 4.166 -<title>Why do the results of <command role="hg-cmd">hg diff</command> and <command role="hg-cmd">hg status</command> differ?</title> 4.167 - 4.168 -<para id="x_676">When you run the <command role="hg-cmd">hg status</command> command, you'll see a list of files 4.169 -that Mercurial will record changes for the next time you perform a 4.170 -commit. If you run the <command role="hg-cmd">hg diff</command> command, you may notice that it 4.171 -prints diffs for only a <emphasis>subset</emphasis> of the files that <command role="hg-cmd">hg status</command> 4.172 -listed. There are two possible reasons for this. 4.173 -</para> 4.174 - 4.175 -<para id="x_677">The first is that <command role="hg-cmd">hg status</command> prints some kinds of modifications 4.176 -that <command role="hg-cmd">hg diff</command> doesn't normally display. The <command role="hg-cmd">hg diff</command> command 4.177 -normally outputs unified diffs, which don't have the ability to 4.178 -represent some changes that Mercurial can track. Most notably, 4.179 -traditional diffs can't represent a change in whether or not a file is 4.180 -executable, but Mercurial records this information. 4.181 -</para> 4.182 - 4.183 -<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.184 -display <command>git</command>-compatible diffs that <emphasis>can</emphasis> display this 4.185 -extra information. 4.186 -</para> 4.187 - 4.188 -<para id="x_679">The second possible reason that <command role="hg-cmd">hg diff</command> might be printing diffs 4.189 -for a subset of the files displayed by <command role="hg-cmd">hg status</command> is that if you 4.190 -invoke it without any arguments, <command role="hg-cmd">hg diff</command> prints diffs against the 4.191 -first parent of the working directory. If you have run <command role="hg-cmd">hg merge</command> 4.192 -to merge two changesets, but you haven't yet committed the results of 4.193 -the merge, your working directory has two parents (use <command role="hg-cmd">hg parents</command> 4.194 -to see them). While <command role="hg-cmd">hg status</command> prints modifications relative to 4.195 -<emphasis>both</emphasis> parents after an uncommitted merge, <command role="hg-cmd">hg diff</command> still 4.196 -operates relative only to the first parent. You can get it to print 4.197 -diffs relative to the second parent by specifying that parent with the 4.198 -<option role="hg-opt-diff">-r</option> option. There is no way to print diffs relative to 4.199 -both parents. 4.200 -</para> 4.201 - 4.202 -</sect3> 4.203 -<sect3> 4.204 -<title>Generating safe binary diffs</title> 4.205 - 4.206 -<para id="x_67a">If you use the <option role="hg-opt-diff">-a</option> option to force Mercurial to print 4.207 -diffs of files that are either <quote>mostly text</quote> or contain lots of 4.208 -binary data, those diffs cannot subsequently be applied by either 4.209 -Mercurial's <command role="hg-cmd">hg import</command> command or the system's <command>patch</command> 4.210 -command. 4.211 -</para> 4.212 - 4.213 -<para id="x_67b">If you want to generate a diff of a binary file that is safe to use as 4.214 -input for <command role="hg-cmd">hg import</command>, use the <command role="hg-cmd">hg diff</command>{--git} option when you 4.215 -generate the patch. The system <command>patch</command> command cannot handle 4.216 -binary patches at all. 4.217 -</para> 4.218 - 4.219 -</sect3> 4.220 -</sect2> 4.221 -</appendix> 4.222 - 4.223 -<!-- 4.224 -local variables: 4.225 -sgml-parent-document: ("00book.xml" "book" "appendix") 4.226 -end: 4.227 --->
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/en/appA-svn.xml Thu May 21 14:16:17 2009 +0800 5.3 @@ -0,0 +1,540 @@ 5.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 5.5 + 5.6 +<appendix id="svn"> 5.7 + <?dbhtml filename="migrating-to-mercurial.html"?> 5.8 +<title>Migrating to Mercurial</title> 5.9 + 5.10 + <para id="x_6e1">A common way to test the waters with a new revision control 5.11 + tool is to experiment with switching an existing project, rather 5.12 + than starting a new project from scratch.</para> 5.13 + 5.14 + <para id="x_6e2">In this appendix, we discuss how to import a project's history 5.15 + into Mercurial, and what to look out for if you are used to a 5.16 + different revision control system.</para> 5.17 + 5.18 + <sect1> 5.19 + <title>Importing history from another system</title> 5.20 + 5.21 + <para id="x_6e3">Mercurial ships with an extension named 5.22 + <literal>convert</literal>, which can import project history 5.23 + from most popular revision control systems. At the time this 5.24 + book was written, it could import history from the following 5.25 + systems:</para> 5.26 + <itemizedlist> 5.27 + <listitem> 5.28 + <para id="x_6e4">Subversion</para> 5.29 + </listitem> 5.30 + <listitem> 5.31 + <para id="x_6e5">CVS</para> 5.32 + </listitem> 5.33 + <listitem> 5.34 + <para id="x_6e6">git</para> 5.35 + </listitem> 5.36 + <listitem> 5.37 + <para id="x_6e7">Darcs</para> 5.38 + </listitem> 5.39 + <listitem> 5.40 + <para id="x_6e8">Bazaar</para> 5.41 + </listitem> 5.42 + <listitem> 5.43 + <para id="x_6e9">Monotone</para> 5.44 + </listitem> 5.45 + <listitem> 5.46 + <para id="x_6ea">GNU Arch</para> 5.47 + </listitem> 5.48 + <listitem> 5.49 + <para id="x_6eb">Mercurial</para> 5.50 + </listitem> 5.51 + </itemizedlist> 5.52 + 5.53 + <para id="x_6ec">(To see why Mercurial itself is supported as a source, see 5.54 + <xref linkend="svn.filemap"/>.)</para> 5.55 + 5.56 + <para id="x_6ed">You can enable the extension in the usual way, by editing 5.57 + your <filename>~/.hgrc</filename> file.</para> 5.58 + 5.59 + <programlisting>[extensions] 5.60 +convert =</programlisting> 5.61 + 5.62 + <para id="x_6ee">This will make a <command>hg convert</command> command 5.63 + available. The command is easy to use. For instance, this 5.64 + command will import the Subversion history for the Nose unit 5.65 + testing framework into Mercurial.</para> 5.66 + 5.67 + <screen><prompt>$</prompt> <userinput>hg convert http://python-nose.googlecode.com/svn/trunk</userinput></screen> 5.68 + 5.69 + <para id="x_6ef">The <literal>convert</literal> extension operates 5.70 + incrementally. In other words, after you have run <command>hg 5.71 + convert</command> once, running it again will import any new 5.72 + revisions committed after the first run began. Incremental 5.73 + conversion will only work if you run <command>hg 5.74 + convert</command> in the same Mercurial repository that you 5.75 + originally used, because the <literal>convert</literal> 5.76 + extension saves some private metadata in a 5.77 + non-revision-controlled file named 5.78 + <filename>.hg/shamap</filename> inside the target 5.79 + repository.</para> 5.80 + 5.81 + <para id="x_707">When you want to start making changes using Mercurial, it's 5.82 + best to clone the tree in which you are doing your conversions, 5.83 + and leave the original tree for future incremental conversions. 5.84 + This is the safest way to let you pull and merge future commits 5.85 + from the source revision control system into your newly active 5.86 + Mercurial project.</para> 5.87 + 5.88 + <sect2> 5.89 + <title>Converting multiple branches</title> 5.90 + 5.91 + <para id="x_708">The <command>hg convert</command> command given above 5.92 + converts only the history of the <literal>trunk</literal> 5.93 + branch of the Subversion repository. If we instead use the 5.94 + URL <literal>http://python-nose.googlecode.com/svn</literal>, 5.95 + Mercurial will automatically detect the 5.96 + <literal>trunk</literal>, <literal>tags</literal> and 5.97 + <literal>branches</literal> layout that Subversion projects 5.98 + usually use, and it will import each as a separate Mercurial 5.99 + branch.</para> 5.100 + 5.101 + <para id="x_709">By default, each Subversion branch imported into Mercurial 5.102 + is given a branch name. After the conversion completes, you 5.103 + can get a list of the active branch names in the Mercurial 5.104 + repository using <command>hg branches -a</command>. If you 5.105 + would prefer to import the Subversion branches without names, 5.106 + pass the <option>--config 5.107 + convert.hg.usebranchnames=false</option> option to 5.108 + <command>hg convert</command>.</para> 5.109 + 5.110 + <para id="x_70a">Once you have converted your tree, if you want to follow 5.111 + the usual Mercurial practice of working in a tree that 5.112 + contains a single branch, you can clone that single branch 5.113 + using <command>hg clone -r mybranchname</command>.</para> 5.114 + </sect2> 5.115 + 5.116 + <sect2> 5.117 + <title>Mapping user names</title> 5.118 + 5.119 + <para id="x_6f0">Some revision control tools save only short usernames with 5.120 + commits, and these can be difficult to interpret. The norm 5.121 + with Mercurial is to save a committer's name and email 5.122 + address, which is much more useful for talking to them after 5.123 + the fact.</para> 5.124 + 5.125 + <para id="x_6f1">If you are converting a tree from a revision control 5.126 + system that uses short names, you can map those names to 5.127 + longer equivalents by passing a <option>--authors</option> 5.128 + option to <command>hg convert</command>. This option accepts 5.129 + a file name that should contain entries of the following 5.130 + form.</para> 5.131 + 5.132 + <programlisting>arist = Aristotle <aristotle@phil.example.gr> 5.133 +soc = Socrates <socrates@phil.example.gr></programlisting> 5.134 + 5.135 + <para id="x_6f2">Whenever <literal>convert</literal> encounters a commit 5.136 + with the username <literal>arist</literal> in the source 5.137 + repository, it will use the name <literal>Aristotle 5.138 + <aristotle@phil.example.gr></literal> in the converted 5.139 + Mercurial revision. If no match is found for a name, it is 5.140 + used verbatim.</para> 5.141 + </sect2> 5.142 + 5.143 + <sect2 id="svn.filemap"> 5.144 + <title>Tidying up the tree</title> 5.145 + 5.146 + <para id="x_6f3">Not all projects have pristine history. There may be a 5.147 + directory that should never have been checked in, a file that 5.148 + is too big, or a whole hierarchy that needs to be 5.149 + refactored.</para> 5.150 + 5.151 + <para id="x_6f4">The <literal>convert</literal> extension supports the idea 5.152 + of a <quote>file map</quote> that can reorganize the files and 5.153 + directories in a project as it imports the project's history. 5.154 + This is useful not only when importing history from other 5.155 + revision control systems, but also to prune or refactor a 5.156 + Mercurial tree.</para> 5.157 + 5.158 + <para id="x_6f5">To specify a file map, use the <option>--filemap</option> 5.159 + option and supply a file name. A file map contains lines of the 5.160 + following forms.</para> 5.161 + 5.162 + <programlisting># This is a comment. 5.163 +# Empty lines are ignored. 5.164 + 5.165 +include path/to/file 5.166 + 5.167 +exclude path/to/file 5.168 + 5.169 +rename from/some/path to/some/other/place 5.170 +</programlisting> 5.171 + 5.172 + <para id="x_6f6">The <literal>include</literal> directive causes a file, or 5.173 + all files under a directory, to be included in the destination 5.174 + repository. This also excludes all other files and dirs not 5.175 + explicitely included. The <literal>exclude</literal> 5.176 + directive causes files or directories to be omitted, and 5.177 + others not explicitly mentioned to be included.</para> 5.178 + 5.179 + <para id="x_6f7">To move a file or directory from one location to another, 5.180 + use the <literal>rename</literal> directive. If you need to 5.181 + move a file or directory from a subdirectory into the root of 5.182 + the repository, use <literal>.</literal> as the second 5.183 + argument to the <literal>rename</literal> directive.</para> 5.184 + </sect2> 5.185 + 5.186 + <sect2> 5.187 + <title>Improving Subversion conversion performance</title> 5.188 + 5.189 + <para id="x_70b">You will often need several attempts before you hit the 5.190 + perfect combination of user map, file map, and other 5.191 + conversion parameters. Converting a Subversion repository 5.192 + over an access protocol like <literal>ssh</literal> or 5.193 + <literal>http</literal> can proceed thousands of times more 5.194 + slowly than Mercurial is capable of actually operating, due to 5.195 + network delays. This can make tuning that perfect conversion 5.196 + recipe very painful.</para> 5.197 + 5.198 + <para id="x_70c">The <ulink 5.199 + url="http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt"><command>svnsync</command></ulink> 5.200 + command can greatly speed up the conversion of a Subversion 5.201 + repository. It is a read-only mirroring program for 5.202 + Subversion repositories. The idea is that you create a local 5.203 + mirror of your Subversion tree, then convert the mirror into a 5.204 + Mercurial repository.</para> 5.205 + 5.206 + <para id="x_70d">Suppose we want to convert the Subversion repository for 5.207 + the popular Memcached project into a Mercurial tree. First, 5.208 + we create a local Subversion repository.</para> 5.209 + 5.210 + <screen><prompt>$</prompt> <userinput>svnadmin create memcached-mirror</userinput></screen> 5.211 + 5.212 + <para id="x_70e">Next, we set up a Subversion hook that 5.213 + <command>svnsync</command> needs.</para> 5.214 + 5.215 + <screen><prompt>$</prompt> <userinput>echo '#!/bin/sh' > memcached-mirror/hooks/pre-revprop-change</userinput> 5.216 +<prompt>$</prompt> <userinput>chmod +x memcached-mirror/hooks/pre-revprop-change</userinput></screen> 5.217 + 5.218 + <para id="x_70f">We then initialize <command>svnsync</command> in this 5.219 + repository.</para> 5.220 + 5.221 + <screen><prompt>$</prompt> <userinput>svnsync --init file://`pwd`/memcached-mirror \ 5.222 + http://code.sixapart.com/svn/memcached</userinput></screen> 5.223 + 5.224 + <para id="x_710">Our next step is to begin the <command>svnsync</command> 5.225 + mirroring process.</para> 5.226 + 5.227 + <screen><prompt>$</prompt> <userinput>svnsync sync file://`pwd`/memcached-mirror</userinput></screen> 5.228 + 5.229 + <para id="x_711">Finally, we import the history of our local Subversion 5.230 + mirror into Mercurial.</para> 5.231 + 5.232 + <screen><prompt>$</prompt> <userinput>hg convert memcached-mirror</userinput></screen> 5.233 + 5.234 + <para id="x_712">We can use this process incrementally if the Subversion 5.235 + repository is still in use. We run <command>svnsync</command> 5.236 + to pull new changes into our mirror, then <command>hg 5.237 + convert</command> to import them into our Mercurial 5.238 + tree.</para> 5.239 + 5.240 + <para id="x_713">There are two advantages to doing a two-stage import with 5.241 + <command>svnsync</command>. The first is that it uses more 5.242 + efficient Subversion network syncing code than <command>hg 5.243 + convert</command>, so it transfers less data over the 5.244 + network. The second is that the import from a local 5.245 + Subversion tree is so fast that you can tweak your conversion 5.246 + setup repeatedly without having to sit through a painfully 5.247 + slow network-based conversion process each time.</para> 5.248 + </sect2> 5.249 + </sect1> 5.250 + 5.251 + <sect1> 5.252 + <title>Migrating from Subversion</title> 5.253 + 5.254 + <para id="x_6f8">Subversion is currently the most popular open source 5.255 + revision control system. Although there are many differences 5.256 + between Mercurial and Subversion, making the transition from 5.257 + Subversion to Mercurial is not particularly difficult. The two 5.258 + have similar command sets and generally uniform 5.259 + interfaces.</para> 5.260 + 5.261 + <sect2> 5.262 + <title>Philosophical differences</title> 5.263 + 5.264 + <para id="x_6f9">The fundamental difference between Subversion and 5.265 + Mercurial is of course that Subversion is centralized, while 5.266 + Mercurial is distributed. Since Mercurial stores all of a 5.267 + project's history on your local drive, it only needs to 5.268 + perform a network access when you want to explicitly 5.269 + communicate with another repository. In contrast, Subversion 5.270 + stores very little information locally, and the client must 5.271 + thus contact its server for many common operations.</para> 5.272 + 5.273 + <para id="x_6fa">Subversion more or less gets away without a well-defined 5.274 + notion of a branch: which portion of a server's namespace 5.275 + qualifies as a branch is a matter of convention, with the 5.276 + software providing no enforcement. Mercurial treats a 5.277 + repository as the unit of branch management.</para> 5.278 + 5.279 + <sect3> 5.280 + <title>Scope of commands</title> 5.281 + 5.282 + <para id="x_6fb">Since Subversion doesn't know what parts of its 5.283 + namespace are really branches, it treats most commands as 5.284 + requests to operate at and below whatever directory you are 5.285 + currently visiting. For instance, if you run <command>svn 5.286 + log</command>, you'll get the history of whatever part of 5.287 + the tree you're looking at, not the tree as a whole.</para> 5.288 + 5.289 + <para id="x_6fc">Mercurial's commands behave differently, by defaulting 5.290 + to operating over an entire repository. Run <command>hg 5.291 + log</command> and it will tell you the history of the 5.292 + entire tree, no matter what part of the working directory 5.293 + you're visiting at the time. If you want the history of 5.294 + just a particular file or directory, simply supply it by 5.295 + name, e.g. <command>hg log src</command>.</para> 5.296 + 5.297 + <para id="x_6fd">From my own experience, this difference in default 5.298 + behaviors is probably the most likely to trip you up if you 5.299 + have to switch back and forth frequently between the two 5.300 + tools.</para> 5.301 + </sect3> 5.302 + 5.303 + <sect3> 5.304 + <title>Multi-user operation and safety</title> 5.305 + 5.306 + <para id="x_6fe">With Subversion, it is normal (though slightly frowned 5.307 + upon) for multiple people to collaborate in a single branch. 5.308 + If Alice and Bob are working together, and Alice commits 5.309 + some changes to their shared branch, Bob must update his 5.310 + client's view of the branch before he can commit. Since at 5.311 + this time he has no permanent record of the changes he has 5.312 + made, he can corrupt or lose his modifications during and 5.313 + after his update.</para> 5.314 + 5.315 + <para id="x_6ff">Mercurial encourages a commit-then-merge model instead. 5.316 + Bob commits his changes locally before pulling changes from, 5.317 + or pushing them to, the server that he shares with Alice. 5.318 + If Alice pushed her changes before Bob tries to push his, he 5.319 + will not be able to push his changes until he pulls hers, 5.320 + merges with them, and commits the result of the merge. If 5.321 + he makes a mistake during the merge, he still has the option 5.322 + of reverting to the commit that recorded his changes.</para> 5.323 + 5.324 + <para id="x_700">It is worth emphasizing that these are the common ways 5.325 + of working with these tools. Subversion supports a safer 5.326 + work-in-your-own-branch model, but it is cumbersome enough 5.327 + in practice to not be widely used. Mercurial can support 5.328 + the less safe mode of allowing changes to be pulled in and 5.329 + merged on top of uncommitted edits, but this is considered 5.330 + highly unusual.</para> 5.331 + </sect3> 5.332 + 5.333 + <sect3> 5.334 + <title>Published vs local changes</title> 5.335 + 5.336 + <para id="x_701">A Subversion <command>svn commit</command> command 5.337 + immediately publishes changes to a server, where they can be 5.338 + seen by everyone who has read access.</para> 5.339 + 5.340 + <para id="x_702">With Mercurial, commits are always local, and must be 5.341 + published via a <command>hg push</command> command 5.342 + afterwards.</para> 5.343 + 5.344 + <para id="x_703">Each approach has its advantages and disadvantages. The 5.345 + Subversion model means that changes are published, and hence 5.346 + reviewable and usable, immediately. On the other hand, this 5.347 + means that a user must have commit access to a repository in 5.348 + order to use the software in a normal way, and commit access 5.349 + is not lightly given out by most open source 5.350 + projects.</para> 5.351 + 5.352 + <para id="x_704">The Mercurial approach allows anyone who can clone a 5.353 + repository to commit changes without the need for someone 5.354 + else's permission, and they can then publish their changes 5.355 + and continue to participate however they see fit. The 5.356 + distinction between committing and pushing does open up the 5.357 + possibility of someone committing changes to their laptop 5.358 + and walking away for a few days having forgotten to push 5.359 + them, which in rare cases might leave collaborators 5.360 + temporarily stuck.</para> 5.361 + </sect3> 5.362 + </sect2> 5.363 + 5.364 + <sect2> 5.365 + <title>Quick reference</title> 5.366 + 5.367 + <table> 5.368 + <title>Subversion commands and Mercurial equivalents</title> 5.369 + <tgroup cols="3"> 5.370 + <thead> 5.371 + <row> 5.372 + <entry>Subversion</entry> 5.373 + <entry>Mercurial</entry> 5.374 + <entry>Notes</entry> 5.375 + </row> 5.376 + </thead> 5.377 + <tbody> 5.378 + <row> 5.379 + <entry><command>svn add</command></entry> 5.380 + <entry><command>hg add</command></entry> 5.381 + <entry></entry> 5.382 + </row> 5.383 + <row> 5.384 + <entry><command>svn blame</command></entry> 5.385 + <entry><command>hg annotate</command></entry> 5.386 + <entry></entry> 5.387 + </row> 5.388 + <row> 5.389 + <entry><command>svn cat</command></entry> 5.390 + <entry><command>hg cat</command></entry> 5.391 + <entry></entry> 5.392 + </row> 5.393 + <row> 5.394 + <entry><command>svn checkout</command></entry> 5.395 + <entry><command>hg clone</command></entry> 5.396 + <entry></entry> 5.397 + </row> 5.398 + <row> 5.399 + <entry><command>svn cleanup</command></entry> 5.400 + <entry>n/a</entry> 5.401 + <entry>No cleanup needed</entry> 5.402 + </row> 5.403 + <row> 5.404 + <entry><command>svn commit</command></entry> 5.405 + <entry><command>hg commit</command>; <command>hg 5.406 + push</command></entry> 5.407 + <entry><command>hg push</command> publishes after 5.408 + commit</entry> 5.409 + </row> 5.410 + <row> 5.411 + <entry><command>svn copy</command></entry> 5.412 + <entry><command>hg clone</command></entry> 5.413 + <entry>To create a new branch</entry> 5.414 + </row> 5.415 + <row> 5.416 + <entry><command>svn copy</command></entry> 5.417 + <entry><command>hg copy</command></entry> 5.418 + <entry>To copy files or directories</entry> 5.419 + </row> 5.420 + <row> 5.421 + <entry><command>svn delete</command> (<command>svn 5.422 + remove</command>)</entry> 5.423 + <entry><command>hg remove</command></entry> 5.424 + <entry></entry> 5.425 + </row> 5.426 + <row> 5.427 + <entry><command>svn diff</command></entry> 5.428 + <entry><command>hg diff</command></entry> 5.429 + <entry></entry> 5.430 + </row> 5.431 + <row> 5.432 + <entry><command>svn export</command></entry> 5.433 + <entry><command>hg archive</command></entry> 5.434 + <entry></entry> 5.435 + </row> 5.436 + <row> 5.437 + <entry><command>svn help</command></entry> 5.438 + <entry><command>hg help</command></entry> 5.439 + <entry></entry> 5.440 + </row> 5.441 + <row> 5.442 + <entry><command>svn import</command></entry> 5.443 + <entry><command>hg addremove</command>; <command>hg 5.444 + commit</command></entry> 5.445 + <entry></entry> 5.446 + </row> 5.447 + <row> 5.448 + <entry><command>svn info</command></entry> 5.449 + <entry><command>hg parents</command></entry> 5.450 + <entry>Shows what revision is checked out</entry> 5.451 + </row> 5.452 + <row> 5.453 + <entry><command>svn info</command></entry> 5.454 + <entry><command>hg showconfig 5.455 + paths.parent</command></entry> 5.456 + <entry>Shows what URL is checked out</entry> 5.457 + </row> 5.458 + <row> 5.459 + <entry><command>svn list</command></entry> 5.460 + <entry><command>hg manifest</command></entry> 5.461 + <entry></entry> 5.462 + </row> 5.463 + <row> 5.464 + <entry><command>svn log</command></entry> 5.465 + <entry><command>hg log</command></entry> 5.466 + <entry></entry> 5.467 + </row> 5.468 + <row> 5.469 + <entry><command>svn merge</command></entry> 5.470 + <entry><command>hg merge</command></entry> 5.471 + <entry></entry> 5.472 + </row> 5.473 + <row> 5.474 + <entry><command>svn mkdir</command></entry> 5.475 + <entry>n/a</entry> 5.476 + <entry>Mercurial does not track directories</entry> 5.477 + </row> 5.478 + <row> 5.479 + <entry><command>svn move</command> (<command>svn 5.480 + rename</command>)</entry> 5.481 + <entry><command>hg rename</command></entry> 5.482 + <entry></entry> 5.483 + </row> 5.484 + <row> 5.485 + <entry><command>svn resolved</command></entry> 5.486 + <entry><command>hg resolve -m</command></entry> 5.487 + <entry></entry> 5.488 + </row> 5.489 + <row> 5.490 + <entry><command>svn revert</command></entry> 5.491 + <entry><command>hg revert</command></entry> 5.492 + <entry></entry> 5.493 + </row> 5.494 + <row> 5.495 + <entry><command>svn status</command></entry> 5.496 + <entry><command>hg status</command></entry> 5.497 + <entry></entry> 5.498 + </row> 5.499 + <row> 5.500 + <entry><command>svn update</command></entry> 5.501 + <entry><command>hg pull -u</command></entry> 5.502 + <entry></entry> 5.503 + </row> 5.504 + </tbody> 5.505 + </tgroup> 5.506 + </table> 5.507 + </sect2> 5.508 + </sect1> 5.509 + 5.510 + <sect1> 5.511 + <title>Useful tips for newcomers</title> 5.512 + 5.513 + <para id="x_705">Under some revision control systems, printing a diff for a 5.514 + single committed revision can be painful. For instance, with 5.515 + Subversion, to see what changed in revision 104654, you must 5.516 + type <command>svn diff -r104653:104654</command>. Mercurial 5.517 + eliminates the need to type the revision ID twice in this common 5.518 + case. For a plain diff, <command>hg export 104654</command>. For 5.519 + a log message followed by a diff, <command>hg log -r104654 5.520 + -p</command>.</para> 5.521 + 5.522 + <para id="x_706">When you run <command>hg status</command> without any 5.523 + arguments, it prints the status of the entire tree, with paths 5.524 + relative to the root of the repository. This makes it tricky to 5.525 + copy a file name from the output of <command>hg status</command> 5.526 + into the command line. If you supply a file or directory name 5.527 + to <command>hg status</command>, it will print paths relative to 5.528 + your current location instead. So to get tree-wide status from 5.529 + <command>hg status</command>, with paths that are relative to 5.530 + your current directory and not the root of the repository, feed 5.531 + the output of <command>hg root</command> into <command>hg 5.532 + status</command>. You can easily do this as follows on a 5.533 + Unix-like system:</para> 5.534 + 5.535 + <screen><prompt>$</prompt> <userinput>hg status `hg root`</userinput></screen> 5.536 + </sect1> 5.537 +</appendix> 5.538 + 5.539 +<!-- 5.540 +local variables: 5.541 +sgml-parent-document: ("00book.xml" "book" "appendix") 5.542 +end: 5.543 +-->
6.1 --- a/en/appB-mq-ref.xml Sat Apr 18 11:52:33 2009 +0800 6.2 +++ b/en/appB-mq-ref.xml Thu May 21 14:16:17 2009 +0800 6.3 @@ -72,6 +72,16 @@ 6.4 6.5 </sect2> 6.6 <sect2> 6.7 + <title><command role="hg-ext-mq">qfold</command>&emdash;move 6.8 + applied patches into repository history</title> 6.9 + 6.10 + <para id="x_72d">The <command>hg qfinish</command> command converts the 6.11 + specified applied patches into permanent changes by moving 6.12 + them out of MQ's control so that they will be treated as 6.13 + normal repository history.</para> 6.14 + </sect2> 6.15 + 6.16 + <sect2> 6.17 <title><command role="hg-ext-mq">qfold</command>&emdash;merge 6.18 (<quote>fold</quote>) several patches into one</title> 6.19 6.20 @@ -328,8 +338,8 @@ 6.21 no such text, a default commit message is used that 6.22 identifies the name of the patch.</para> 6.23 </listitem></itemizedlist> 6.24 - <para id="x_615">If a patch contains a Mercurial patch header (XXX add 6.25 - link), the information in the patch header overrides these 6.26 + <para id="x_615">If a patch contains a Mercurial patch header, 6.27 + the information in the patch header overrides these 6.28 defaults.</para> 6.29 6.30 <para id="x_616">Options:</para> 6.31 @@ -435,21 +445,6 @@ 6.32 6.33 </sect2> 6.34 <sect2> 6.35 - <title><command 6.36 - role="hg-ext-mq">qrestore</command>&emdash;restore saved 6.37 - queue state</title> 6.38 - 6.39 - <para id="x_628">XXX No idea what this does.</para> 6.40 - 6.41 - </sect2> 6.42 - <sect2> 6.43 - <title><command role="hg-ext-mq">qsave</command>&emdash;save 6.44 - current queue state</title> 6.45 - 6.46 - <para id="x_629">XXX Likewise.</para> 6.47 - 6.48 - </sect2> 6.49 - <sect2> 6.50 <title><command role="hg-ext-mq">qseries</command>&emdash;print 6.51 the entire patch series</title> 6.52 6.53 @@ -501,9 +496,7 @@ 6.54 changesets in the backup bundle.</para> 6.55 </listitem> 6.56 <listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a 6.57 - branch has multiple heads, remove all heads. XXX This 6.58 - should be renamed, and use <literal>-f</literal> to strip 6.59 - revs when there are pending changes.</para> 6.60 + branch has multiple heads, remove all heads.</para> 6.61 </listitem> 6.62 <listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do 6.63 not save a backup bundle.</para>
7.1 --- a/en/ch00-preface.xml Sat Apr 18 11:52:33 2009 +0800 7.2 +++ b/en/ch00-preface.xml Thu May 21 14:16:17 2009 +0800 7.3 @@ -5,751 +5,256 @@ 7.4 <title>Preface</title> 7.5 7.6 <sect1> 7.7 - <title>Why revision control? Why Mercurial?</title> 7.8 - 7.9 - <para id="x_6d">Revision control is the process of managing multiple 7.10 - versions of a piece of information. In its simplest form, this 7.11 - is something that many people do by hand: every time you modify 7.12 - a file, save it under a new name that contains a number, each 7.13 - one higher than the number of the preceding version.</para> 7.14 - 7.15 - <para id="x_6e">Manually managing multiple versions of even a single file is 7.16 - an error-prone task, though, so software tools to help automate 7.17 - this process have long been available. The earliest automated 7.18 - revision control tools were intended to help a single user to 7.19 - manage revisions of a single file. Over the past few decades, 7.20 - the scope of revision control tools has expanded greatly; they 7.21 - now manage multiple files, and help multiple people to work 7.22 - together. The best modern revision control tools have no 7.23 - problem coping with thousands of people working together on 7.24 - projects that consist of hundreds of thousands of files.</para> 7.25 - 7.26 - <para id="x_6f">The arrival of distributed revision control is relatively 7.27 - recent, and so far this new field has grown due to people's 7.28 - willingness to explore ill-charted territory.</para> 7.29 - 7.30 - <para id="x_70">I am writing a book about distributed revision control 7.31 - because I believe that it is an important subject that deserves 7.32 - a field guide. I chose to write about Mercurial because it is 7.33 - the easiest tool to learn the terrain with, and yet it scales to 7.34 - the demands of real, challenging environments where many other 7.35 - revision control tools buckle.</para> 7.36 - 7.37 - <sect2> 7.38 - <title>Why use revision control?</title> 7.39 - 7.40 - <para id="x_71">There are a number of reasons why you or your team might 7.41 - want to use an automated revision control tool for a 7.42 - project.</para> 7.43 - 7.44 - <itemizedlist> 7.45 - <listitem><para id="x_72">It will track the history and evolution of 7.46 - your project, so you don't have to. For every change, 7.47 - you'll have a log of <emphasis>who</emphasis> made it; 7.48 - <emphasis>why</emphasis> they made it; 7.49 - <emphasis>when</emphasis> they made it; and 7.50 - <emphasis>what</emphasis> the change 7.51 - was.</para></listitem> 7.52 - <listitem><para id="x_73">When you're working with other people, 7.53 - revision control software makes it easier for you to 7.54 - collaborate. For example, when people more or less 7.55 - simultaneously make potentially incompatible changes, the 7.56 - software will help you to identify and resolve those 7.57 - conflicts.</para></listitem> 7.58 - <listitem><para id="x_74">It can help you to recover from mistakes. If 7.59 - you make a change that later turns out to be in error, you 7.60 - can revert to an earlier version of one or more files. In 7.61 - fact, a <emphasis>really</emphasis> good revision control 7.62 - tool will even help you to efficiently figure out exactly 7.63 - when a problem was introduced (see <xref 7.64 - linkend="sec:undo:bisect"/> for details).</para></listitem> 7.65 - <listitem><para id="x_75">It will help you to work simultaneously on, 7.66 - and manage the drift between, multiple versions of your 7.67 - project.</para></listitem> 7.68 - </itemizedlist> 7.69 - 7.70 - <para id="x_76">Most of these reasons are equally 7.71 - valid&emdash;at least in theory&emdash;whether you're working 7.72 - on a project by yourself, or with a hundred other 7.73 - people.</para> 7.74 - 7.75 - <para id="x_77">A key question about the practicality of revision control 7.76 - at these two different scales (<quote>lone hacker</quote> and 7.77 - <quote>huge team</quote>) is how its 7.78 - <emphasis>benefits</emphasis> compare to its 7.79 - <emphasis>costs</emphasis>. A revision control tool that's 7.80 - difficult to understand or use is going to impose a high 7.81 - cost.</para> 7.82 - 7.83 - <para id="x_78">A five-hundred-person project is likely to collapse under 7.84 - its own weight almost immediately without a revision control 7.85 - tool and process. In this case, the cost of using revision 7.86 - control might hardly seem worth considering, since 7.87 - <emphasis>without</emphasis> it, failure is almost 7.88 - guaranteed.</para> 7.89 - 7.90 - <para id="x_79">On the other hand, a one-person <quote>quick hack</quote> 7.91 - might seem like a poor place to use a revision control tool, 7.92 - because surely the cost of using one must be close to the 7.93 - overall cost of the project. Right?</para> 7.94 - 7.95 - <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of 7.96 - these scales of development. You can learn the basics in just 7.97 - a few minutes, and due to its low overhead, you can apply 7.98 - revision control to the smallest of projects with ease. Its 7.99 - simplicity means you won't have a lot of abstruse concepts or 7.100 - command sequences competing for mental space with whatever 7.101 - you're <emphasis>really</emphasis> trying to do. At the same 7.102 - time, Mercurial's high performance and peer-to-peer nature let 7.103 - you scale painlessly to handle large projects.</para> 7.104 - 7.105 - <para id="x_7b">No revision control tool can rescue a poorly run project, 7.106 - but a good choice of tools can make a huge difference to the 7.107 - fluidity with which you can work on a project.</para> 7.108 - 7.109 - </sect2> 7.110 - 7.111 - <sect2> 7.112 - <title>The many names of revision control</title> 7.113 - 7.114 - <para id="x_7c">Revision control is a diverse field, so much so that it is 7.115 - referred to by many names and acronyms. Here are a few of the 7.116 - more common variations you'll encounter:</para> 7.117 - <itemizedlist> 7.118 - <listitem><para id="x_7d">Revision control (RCS)</para></listitem> 7.119 - <listitem><para id="x_7e">Software configuration management (SCM), or 7.120 - configuration management</para></listitem> 7.121 - <listitem><para id="x_7f">Source code management</para></listitem> 7.122 - <listitem><para id="x_80">Source code control, or source 7.123 - control</para></listitem> 7.124 - <listitem><para id="x_81">Version control 7.125 - (VCS)</para></listitem></itemizedlist> 7.126 - <para id="x_82">Some people claim that these terms actually have different 7.127 - meanings, but in practice they overlap so much that there's no 7.128 - agreed or even useful way to tease them apart.</para> 7.129 - 7.130 - </sect2> 7.131 - </sect1> 7.132 - 7.133 - <sect1> 7.134 - <title>This book is a work in progress</title> 7.135 - 7.136 - <para id="x_83">I am releasing this book while I am still writing it, in the 7.137 - hope that it will prove useful to others. I am writing under an 7.138 - open license in the hope that you, my readers, will contribute 7.139 - feedback and perhaps content of your own.</para> 7.140 - 7.141 - </sect1> 7.142 - <sect1> 7.143 - <title>About the examples in this book</title> 7.144 - 7.145 - <para id="x_84">This book takes an unusual approach to code samples. Every 7.146 - example is <quote>live</quote>&emdash;each one is actually the result 7.147 - of a shell script that executes the Mercurial commands you see. 7.148 - Every time an image of the book is built from its sources, all 7.149 - the example scripts are automatically run, and their current 7.150 - results compared against their expected results.</para> 7.151 - 7.152 - <para id="x_85">The advantage of this approach is that the examples are 7.153 - always accurate; they describe <emphasis>exactly</emphasis> the 7.154 - behavior of the version of Mercurial that's mentioned at the 7.155 - front of the book. If I update the version of Mercurial that 7.156 - I'm documenting, and the output of some command changes, the 7.157 - build fails.</para> 7.158 - 7.159 - <para id="x_86">There is a small disadvantage to this approach, which is 7.160 - that the dates and times you'll see in examples tend to be 7.161 - <quote>squashed</quote> together in a way that they wouldn't be 7.162 - if the same commands were being typed by a human. Where a human 7.163 - can issue no more than one command every few seconds, with any 7.164 - resulting timestamps correspondingly spread out, my automated 7.165 - example scripts run many commands in one second.</para> 7.166 - 7.167 - <para id="x_87">As an instance of this, several consecutive commits in an 7.168 - example can show up as having occurred during the same second. 7.169 - You can see this occur in the <literal 7.170 - role="hg-ext">bisect</literal> example in <xref 7.171 - linkend="sec:undo:bisect"/>, for instance.</para> 7.172 - 7.173 - <para id="x_88">So when you're reading examples, don't place too much weight 7.174 - on the dates or times you see in the output of commands. But 7.175 - <emphasis>do</emphasis> be confident that the behavior you're 7.176 - seeing is consistent and reproducible.</para> 7.177 - 7.178 - </sect1> 7.179 - 7.180 - <sect1> 7.181 - <title>Trends in the field</title> 7.182 - 7.183 - <para id="x_89">There has been an unmistakable trend in the development and 7.184 - use of revision control tools over the past four decades, as 7.185 - people have become familiar with the capabilities of their tools 7.186 - and constrained by their limitations.</para> 7.187 - 7.188 - <para id="x_8a">The first generation began by managing single files on 7.189 - individual computers. Although these tools represented a huge 7.190 - advance over ad-hoc manual revision control, their locking model 7.191 - and reliance on a single computer limited them to small, 7.192 - tightly-knit teams.</para> 7.193 - 7.194 - <para id="x_8b">The second generation loosened these constraints by moving 7.195 - to network-centered architectures, and managing entire projects 7.196 - at a time. As projects grew larger, they ran into new problems. 7.197 - With clients needing to talk to servers very frequently, server 7.198 - scaling became an issue for large projects. An unreliable 7.199 - network connection could prevent remote users from being able to 7.200 - talk to the server at all. As open source projects started 7.201 - making read-only access available anonymously to anyone, people 7.202 - without commit privileges found that they could not use the 7.203 - tools to interact with a project in a natural way, as they could 7.204 - not record their changes.</para> 7.205 - 7.206 - <para id="x_8c">The current generation of revision control tools is 7.207 - peer-to-peer in nature. All of these systems have dropped the 7.208 - dependency on a single central server, and allow people to 7.209 - distribute their revision control data to where it's actually 7.210 - needed. Collaboration over the Internet has moved from 7.211 - constrained by technology to a matter of choice and consensus. 7.212 - Modern tools can operate offline indefinitely and autonomously, 7.213 - with a network connection only needed when syncing changes with 7.214 - another repository.</para> 7.215 - 7.216 - </sect1> 7.217 - <sect1> 7.218 - <title>A few of the advantages of distributed revision 7.219 - control</title> 7.220 - 7.221 - <para id="x_8d">Even though distributed revision control tools have for 7.222 - several years been as robust and usable as their 7.223 - previous-generation counterparts, people using older tools have 7.224 - not yet necessarily woken up to their advantages. There are a 7.225 - number of ways in which distributed tools shine relative to 7.226 - centralised ones.</para> 7.227 - 7.228 - <para id="x_8e">For an individual developer, distributed tools are almost 7.229 - always much faster than centralised tools. This is for a simple 7.230 - reason: a centralised tool needs to talk over the network for 7.231 - many common operations, because most metadata is stored in a 7.232 - single copy on the central server. A distributed tool stores 7.233 - all of its metadata locally. All else being equal, talking over 7.234 - the network adds overhead to a centralised tool. Don't 7.235 - underestimate the value of a snappy, responsive tool: you're 7.236 - going to spend a lot of time interacting with your revision 7.237 - control software.</para> 7.238 - 7.239 - <para id="x_8f">Distributed tools are indifferent to the vagaries of your 7.240 - server infrastructure, again because they replicate metadata to 7.241 - so many locations. If you use a centralised system and your 7.242 - server catches fire, you'd better hope that your backup media 7.243 - are reliable, and that your last backup was recent and actually 7.244 - worked. With a distributed tool, you have many backups 7.245 - available on every contributor's computer.</para> 7.246 - 7.247 - <para id="x_90">The reliability of your network will affect distributed 7.248 - tools far less than it will centralised tools. You can't even 7.249 - use a centralised tool without a network connection, except for 7.250 - a few highly constrained commands. With a distributed tool, if 7.251 - your network connection goes down while you're working, you may 7.252 - not even notice. The only thing you won't be able to do is talk 7.253 - to repositories on other computers, something that is relatively 7.254 - rare compared with local operations. If you have a far-flung 7.255 - team of collaborators, this may be significant.</para> 7.256 - 7.257 - <sect2> 7.258 - <title>Advantages for open source projects</title> 7.259 - 7.260 - <para id="x_91">If you take a shine to an open source project and decide 7.261 - that you would like to start hacking on it, and that project 7.262 - uses a distributed revision control tool, you are at once a 7.263 - peer with the people who consider themselves the 7.264 - <quote>core</quote> of that project. If they publish their 7.265 - repositories, you can immediately copy their project history, 7.266 - start making changes, and record your work, using the same 7.267 - tools in the same ways as insiders. By contrast, with a 7.268 - centralised tool, you must use the software in a <quote>read 7.269 - only</quote> mode unless someone grants you permission to 7.270 - commit changes to their central server. Until then, you won't 7.271 - be able to record changes, and your local modifications will 7.272 - be at risk of corruption any time you try to update your 7.273 - client's view of the repository.</para> 7.274 - 7.275 - <sect3> 7.276 - <title>The forking non-problem</title> 7.277 - 7.278 - <para id="x_92">It has been suggested that distributed revision control 7.279 - tools pose some sort of risk to open source projects because 7.280 - they make it easy to <quote>fork</quote> the development of 7.281 - a project. A fork happens when there are differences in 7.282 - opinion or attitude between groups of developers that cause 7.283 - them to decide that they can't work together any longer. 7.284 - Each side takes a more or less complete copy of the 7.285 - project's source code, and goes off in its own 7.286 - direction.</para> 7.287 - 7.288 - <para id="x_93">Sometimes the camps in a fork decide to reconcile their 7.289 - differences. With a centralised revision control system, the 7.290 - <emphasis>technical</emphasis> process of reconciliation is 7.291 - painful, and has to be performed largely by hand. You have 7.292 - to decide whose revision history is going to 7.293 - <quote>win</quote>, and graft the other team's changes into 7.294 - the tree somehow. This usually loses some or all of one 7.295 - side's revision history.</para> 7.296 - 7.297 - <para id="x_94">What distributed tools do with respect to forking is 7.298 - they make forking the <emphasis>only</emphasis> way to 7.299 - develop a project. Every single change that you make is 7.300 - potentially a fork point. The great strength of this 7.301 - approach is that a distributed revision control tool has to 7.302 - be really good at <emphasis>merging</emphasis> forks, 7.303 - because forks are absolutely fundamental: they happen all 7.304 - the time.</para> 7.305 - 7.306 - <para id="x_95">If every piece of work that everybody does, all the 7.307 - time, is framed in terms of forking and merging, then what 7.308 - the open source world refers to as a <quote>fork</quote> 7.309 - becomes <emphasis>purely</emphasis> a social issue. If 7.310 - anything, distributed tools <emphasis>lower</emphasis> the 7.311 - likelihood of a fork:</para> 7.312 - <itemizedlist> 7.313 - <listitem><para id="x_96">They eliminate the social distinction that 7.314 - centralised tools impose: that between insiders (people 7.315 - with commit access) and outsiders (people 7.316 - without).</para></listitem> 7.317 - <listitem><para id="x_97">They make it easier to reconcile after a 7.318 - social fork, because all that's involved from the 7.319 - perspective of the revision control software is just 7.320 - another merge.</para></listitem></itemizedlist> 7.321 - 7.322 - <para id="x_98">Some people resist distributed tools because they want 7.323 - to retain tight control over their projects, and they 7.324 - believe that centralised tools give them this control. 7.325 - However, if you're of this belief, and you publish your CVS 7.326 - or Subversion repositories publicly, there are plenty of 7.327 - tools available that can pull out your entire project's 7.328 - history (albeit slowly) and recreate it somewhere that you 7.329 - don't control. So while your control in this case is 7.330 - illusory, you are forgoing the ability to fluidly 7.331 - collaborate with whatever people feel compelled to mirror 7.332 - and fork your history.</para> 7.333 - 7.334 - </sect3> 7.335 - </sect2> 7.336 - <sect2> 7.337 - <title>Advantages for commercial projects</title> 7.338 - 7.339 - <para id="x_99">Many commercial projects are undertaken by teams that are 7.340 - scattered across the globe. Contributors who are far from a 7.341 - central server will see slower command execution and perhaps 7.342 - less reliability. Commercial revision control systems attempt 7.343 - to ameliorate these problems with remote-site replication 7.344 - add-ons that are typically expensive to buy and cantankerous 7.345 - to administer. A distributed system doesn't suffer from these 7.346 - problems in the first place. Better yet, you can easily set 7.347 - up multiple authoritative servers, say one per site, so that 7.348 - there's no redundant communication between repositories over 7.349 - expensive long-haul network links.</para> 7.350 - 7.351 - <para id="x_9a">Centralised revision control systems tend to have 7.352 - relatively low scalability. It's not unusual for an expensive 7.353 - centralised system to fall over under the combined load of 7.354 - just a few dozen concurrent users. Once again, the typical 7.355 - response tends to be an expensive and clunky replication 7.356 - facility. Since the load on a central server&emdash;if you have 7.357 - one at all&emdash;is many times lower with a distributed tool 7.358 - (because all of the data is replicated everywhere), a single 7.359 - cheap server can handle the needs of a much larger team, and 7.360 - replication to balance load becomes a simple matter of 7.361 - scripting.</para> 7.362 - 7.363 - <para id="x_9b">If you have an employee in the field, troubleshooting a 7.364 - problem at a customer's site, they'll benefit from distributed 7.365 - revision control. The tool will let them generate custom 7.366 - builds, try different fixes in isolation from each other, and 7.367 - search efficiently through history for the sources of bugs and 7.368 - regressions in the customer's environment, all without needing 7.369 - to connect to your company's network.</para> 7.370 - 7.371 - </sect2> 7.372 - </sect1> 7.373 - <sect1> 7.374 - <title>Why choose Mercurial?</title> 7.375 - 7.376 - <para id="x_9c">Mercurial has a unique set of properties that make it a 7.377 - particularly good choice as a revision control system.</para> 7.378 - <itemizedlist> 7.379 - <listitem><para id="x_9d">It is easy to learn and use.</para></listitem> 7.380 - <listitem><para id="x_9e">It is lightweight.</para></listitem> 7.381 - <listitem><para id="x_9f">It scales excellently.</para></listitem> 7.382 - <listitem><para id="x_a0">It is easy to 7.383 - customise.</para></listitem></itemizedlist> 7.384 - 7.385 - <para id="x_a1">If you are at all familiar with revision control systems, 7.386 - you should be able to get up and running with Mercurial in less 7.387 - than five minutes. Even if not, it will take no more than a few 7.388 - minutes longer. Mercurial's command and feature sets are 7.389 - generally uniform and consistent, so you can keep track of a few 7.390 - general rules instead of a host of exceptions.</para> 7.391 - 7.392 - <para id="x_a2">On a small project, you can start working with Mercurial in 7.393 - moments. Creating new changes and branches; transferring changes 7.394 - around (whether locally or over a network); and history and 7.395 - status operations are all fast. Mercurial attempts to stay 7.396 - nimble and largely out of your way by combining low cognitive 7.397 - overhead with blazingly fast operations.</para> 7.398 - 7.399 - <para id="x_a3">The usefulness of Mercurial is not limited to small 7.400 - projects: it is used by projects with hundreds to thousands of 7.401 - contributors, each containing tens of thousands of files and 7.402 - hundreds of megabytes of source code.</para> 7.403 - 7.404 - <para id="x_a4">If the core functionality of Mercurial is not enough for 7.405 - you, it's easy to build on. Mercurial is well suited to 7.406 - scripting tasks, and its clean internals and implementation in 7.407 - Python make it easy to add features in the form of extensions. 7.408 - There are a number of popular and useful extensions already 7.409 - available, ranging from helping to identify bugs to improving 7.410 - performance.</para> 7.411 - 7.412 - </sect1> 7.413 - <sect1> 7.414 - <title>Mercurial compared with other tools</title> 7.415 - 7.416 - <para id="x_a5">Before you read on, please understand that this section 7.417 - necessarily reflects my own experiences, interests, and (dare I 7.418 - say it) biases. I have used every one of the revision control 7.419 - tools listed below, in most cases for several years at a 7.420 - time.</para> 7.421 - 7.422 - 7.423 - <sect2> 7.424 - <title>Subversion</title> 7.425 - 7.426 - <para id="x_a6">Subversion is a popular revision control tool, developed 7.427 - to replace CVS. It has a centralised client/server 7.428 - architecture.</para> 7.429 - 7.430 - <para id="x_a7">Subversion and Mercurial have similarly named commands for 7.431 - performing the same operations, so if you're familiar with 7.432 - one, it is easy to learn to use the other. Both tools are 7.433 - portable to all popular operating systems.</para> 7.434 - 7.435 - <para id="x_a8">Prior to version 1.5, Subversion had no useful support for 7.436 - merges. At the time of writing, its merge tracking capability 7.437 - is new, and known to be <ulink 7.438 - url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 7.439 - and buggy</ulink>.</para> 7.440 - 7.441 - <para id="x_a9">Mercurial has a substantial performance advantage over 7.442 - Subversion on every revision control operation I have 7.443 - benchmarked. I have measured its advantage as ranging from a 7.444 - factor of two to a factor of six when compared with Subversion 7.445 - 1.4.3's <emphasis>ra_local</emphasis> file store, which is the 7.446 - fastest access method available. In more realistic 7.447 - deployments involving a network-based store, Subversion will 7.448 - be at a substantially larger disadvantage. Because many 7.449 - Subversion commands must talk to the server and Subversion 7.450 - does not have useful replication facilities, server capacity 7.451 - and network bandwidth become bottlenecks for modestly large 7.452 - projects.</para> 7.453 - 7.454 - <para id="x_aa">Additionally, Subversion incurs substantial storage 7.455 - overhead to avoid network transactions for a few common 7.456 - operations, such as finding modified files 7.457 - (<literal>status</literal>) and displaying modifications 7.458 - against the current revision (<literal>diff</literal>). As a 7.459 - result, a Subversion working copy is often the same size as, 7.460 - or larger than, a Mercurial repository and working directory, 7.461 - even though the Mercurial repository contains a complete 7.462 - history of the project.</para> 7.463 - 7.464 - <para id="x_ab">Subversion is widely supported by third party tools. 7.465 - Mercurial currently lags considerably in this area. This gap 7.466 - is closing, however, and indeed some of Mercurial's GUI tools 7.467 - now outshine their Subversion equivalents. Like Mercurial, 7.468 - Subversion has an excellent user manual.</para> 7.469 - 7.470 - <para id="x_ac">Because Subversion doesn't store revision history on the 7.471 - client, it is well suited to managing projects that deal with 7.472 - lots of large, opaque binary files. If you check in fifty 7.473 - revisions to an incompressible 10MB file, Subversion's 7.474 - client-side space usage stays constant The space used by any 7.475 - distributed SCM will grow rapidly in proportion to the number 7.476 - of revisions, because the differences between each revision 7.477 - are large.</para> 7.478 - 7.479 - <para id="x_ad">In addition, it's often difficult or, more usually, 7.480 - impossible to merge different versions of a binary file. 7.481 - Subversion's ability to let a user lock a file, so that they 7.482 - temporarily have the exclusive right to commit changes to it, 7.483 - can be a significant advantage to a project where binary files 7.484 - are widely used.</para> 7.485 - 7.486 - <para id="x_ae">Mercurial can import revision history from a Subversion 7.487 - repository. It can also export revision history to a 7.488 - Subversion repository. This makes it easy to <quote>test the 7.489 - waters</quote> and use Mercurial and Subversion in parallel 7.490 - before deciding to switch. History conversion is incremental, 7.491 - so you can perform an initial conversion, then small 7.492 - additional conversions afterwards to bring in new 7.493 - changes.</para> 7.494 - 7.495 - 7.496 - </sect2> 7.497 - <sect2> 7.498 - <title>Git</title> 7.499 - 7.500 - <para id="x_af">Git is a distributed revision control tool that was 7.501 - developed for managing the Linux kernel source tree. Like 7.502 - Mercurial, its early design was somewhat influenced by 7.503 - Monotone.</para> 7.504 - 7.505 - <para id="x_b0">Git has a very large command set, with version 1.5.0 7.506 - providing 139 individual commands. It has something of a 7.507 - reputation for being difficult to learn. Compared to Git, 7.508 - Mercurial has a strong focus on simplicity.</para> 7.509 - 7.510 - <para id="x_b1">In terms of performance, Git is extremely fast. In 7.511 - several cases, it is faster than Mercurial, at least on Linux, 7.512 - while Mercurial performs better on other operations. However, 7.513 - on Windows, the performance and general level of support that 7.514 - Git provides is, at the time of writing, far behind that of 7.515 - Mercurial.</para> 7.516 - 7.517 - <para id="x_b2">While a Mercurial repository needs no maintenance, a Git 7.518 - repository requires frequent manual <quote>repacks</quote> of 7.519 - its metadata. Without these, performance degrades, while 7.520 - space usage grows rapidly. A server that contains many Git 7.521 - repositories that are not rigorously and frequently repacked 7.522 - will become heavily disk-bound during backups, and there have 7.523 - been instances of daily backups taking far longer than 24 7.524 - hours as a result. A freshly packed Git repository is 7.525 - slightly smaller than a Mercurial repository, but an unpacked 7.526 - repository is several orders of magnitude larger.</para> 7.527 - 7.528 - <para id="x_b3">The core of Git is written in C. Many Git commands are 7.529 - implemented as shell or Perl scripts, and the quality of these 7.530 - scripts varies widely. I have encountered several instances 7.531 - where scripts charged along blindly in the presence of errors 7.532 - that should have been fatal.</para> 7.533 - 7.534 - <para id="x_b4">Mercurial can import revision history from a Git 7.535 - repository.</para> 7.536 - 7.537 - 7.538 - </sect2> 7.539 - <sect2> 7.540 - <title>CVS</title> 7.541 - 7.542 - <para id="x_b5">CVS is probably the most widely used revision control tool 7.543 - in the world. Due to its age and internal untidiness, it has 7.544 - been only lightly maintained for many years.</para> 7.545 - 7.546 - <para id="x_b6">It has a centralised client/server architecture. It does 7.547 - not group related file changes into atomic commits, making it 7.548 - easy for people to <quote>break the build</quote>: one person 7.549 - can successfully commit part of a change and then be blocked 7.550 - by the need for a merge, causing other people to see only a 7.551 - portion of the work they intended to do. This also affects 7.552 - how you work with project history. If you want to see all of 7.553 - the modifications someone made as part of a task, you will 7.554 - need to manually inspect the descriptions and timestamps of 7.555 - the changes made to each file involved (if you even know what 7.556 - those files were).</para> 7.557 - 7.558 - <para id="x_b7">CVS has a muddled notion of tags and branches that I will 7.559 - not attempt to even describe. It does not support renaming of 7.560 - files or directories well, making it easy to corrupt a 7.561 - repository. It has almost no internal consistency checking 7.562 - capabilities, so it is usually not even possible to tell 7.563 - whether or how a repository is corrupt. I would not recommend 7.564 - CVS for any project, existing or new.</para> 7.565 - 7.566 - <para id="x_b8">Mercurial can import CVS revision history. However, there 7.567 - are a few caveats that apply; these are true of every other 7.568 - revision control tool's CVS importer, too. Due to CVS's lack 7.569 - of atomic changes and unversioned filesystem hierarchy, it is 7.570 - not possible to reconstruct CVS history completely accurately; 7.571 - some guesswork is involved, and renames will usually not show 7.572 - up. Because a lot of advanced CVS administration has to be 7.573 - done by hand and is hence error-prone, it's common for CVS 7.574 - importers to run into multiple problems with corrupted 7.575 - repositories (completely bogus revision timestamps and files 7.576 - that have remained locked for over a decade are just two of 7.577 - the less interesting problems I can recall from personal 7.578 - experience).</para> 7.579 - 7.580 - <para id="x_b9">Mercurial can import revision history from a CVS 7.581 - repository.</para> 7.582 - 7.583 - 7.584 - </sect2> 7.585 - <sect2> 7.586 - <title>Commercial tools</title> 7.587 - 7.588 - <para id="x_ba">Perforce has a centralised client/server architecture, 7.589 - with no client-side caching of any data. Unlike modern 7.590 - revision control tools, Perforce requires that a user run a 7.591 - command to inform the server about every file they intend to 7.592 - edit.</para> 7.593 - 7.594 - <para id="x_bb">The performance of Perforce is quite good for small teams, 7.595 - but it falls off rapidly as the number of users grows beyond a 7.596 - few dozen. Modestly large Perforce installations require the 7.597 - deployment of proxies to cope with the load their users 7.598 - generate.</para> 7.599 - 7.600 - 7.601 - </sect2> 7.602 - <sect2> 7.603 - <title>Choosing a revision control tool</title> 7.604 - 7.605 - <para id="x_bc">With the exception of CVS, all of the tools listed above 7.606 - have unique strengths that suit them to particular styles of 7.607 - work. There is no single revision control tool that is best 7.608 - in all situations.</para> 7.609 - 7.610 - <para id="x_bd">As an example, Subversion is a good choice for working 7.611 - with frequently edited binary files, due to its centralised 7.612 - nature and support for file locking.</para> 7.613 - 7.614 - <para id="x_be">I personally find Mercurial's properties of simplicity, 7.615 - performance, and good merge support to be a compelling 7.616 - combination that has served me well for several years.</para> 7.617 - 7.618 - 7.619 - </sect2> 7.620 - </sect1> 7.621 - <sect1> 7.622 - <title>Switching from another tool to Mercurial</title> 7.623 - 7.624 - <para id="x_bf">Mercurial is bundled with an extension named <literal 7.625 - role="hg-ext">convert</literal>, which can incrementally 7.626 - import revision history from several other revision control 7.627 - tools. By <quote>incremental</quote>, I mean that you can 7.628 - convert all of a project's history to date in one go, then rerun 7.629 - the conversion later to obtain new changes that happened after 7.630 - the initial conversion.</para> 7.631 - 7.632 - <para id="x_c0">The revision control tools supported by <literal 7.633 - role="hg-ext">convert</literal> are as follows:</para> 7.634 - <itemizedlist> 7.635 - <listitem><para id="x_c1">Subversion</para></listitem> 7.636 - <listitem><para id="x_c2">CVS</para></listitem> 7.637 - <listitem><para id="x_c3">Git</para></listitem> 7.638 - <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist> 7.639 - 7.640 - <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can 7.641 - export changes from Mercurial to Subversion. This makes it 7.642 - possible to try Subversion and Mercurial in parallel before 7.643 - committing to a switchover, without risking the loss of any 7.644 - work.</para> 7.645 - 7.646 - <para id="x_c6">The <command role="hg-ext-convert">convert</command> command 7.647 - is easy to use. Simply point it at the path or URL of the 7.648 - source repository, optionally give it the name of the 7.649 - destination repository, and it will start working. After the 7.650 - initial conversion, just run the same command again to import 7.651 - new changes.</para> 7.652 - </sect1> 7.653 - 7.654 - <sect1> 7.655 - <title>A short history of revision control</title> 7.656 - 7.657 - <para id="x_c7">The best known of the old-time revision control tools is 7.658 - SCCS (Source Code Control System), which Marc Rochkind wrote at 7.659 - Bell Labs, in the early 1970s. SCCS operated on individual 7.660 - files, and required every person working on a project to have 7.661 - access to a shared workspace on a single system. Only one 7.662 - person could modify a file at any time; arbitration for access 7.663 - to files was via locks. It was common for people to lock files, 7.664 - and later forget to unlock them, preventing anyone else from 7.665 - modifying those files without the help of an 7.666 - administrator.</para> 7.667 - 7.668 - <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the 7.669 - early 1980s; he called his program RCS (Revision Control System). 7.670 - Like SCCS, RCS required developers to work in a single shared 7.671 - workspace, and to lock files to prevent multiple people from 7.672 - modifying them simultaneously.</para> 7.673 - 7.674 - <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block 7.675 - for a set of shell scripts he initially called cmt, but then 7.676 - renamed to CVS (Concurrent Versions System). The big innovation 7.677 - of CVS was that it let developers work simultaneously and 7.678 - somewhat independently in their own personal workspaces. The 7.679 - personal workspaces prevented developers from stepping on each 7.680 - other's toes all the time, as was common with SCCS and RCS. Each 7.681 - developer had a copy of every project file, and could modify 7.682 - their copies independently. They had to merge their edits prior 7.683 - to committing changes to the central repository.</para> 7.684 - 7.685 - <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote 7.686 - them in C, releasing in 1989 the code that has since developed 7.687 - into the modern version of CVS. CVS subsequently acquired the 7.688 - ability to operate over a network connection, giving it a 7.689 - client/server architecture. CVS's architecture is centralised; 7.690 - only the server has a copy of the history of the project. Client 7.691 - workspaces just contain copies of recent versions of the 7.692 - project's files, and a little metadata to tell them where the 7.693 - server is. CVS has been enormously successful; it is probably 7.694 - the world's most widely used revision control system.</para> 7.695 - 7.696 - <para id="x_cb">In the early 1990s, Sun Microsystems developed an early 7.697 - distributed revision control system, called TeamWare. A 7.698 - TeamWare workspace contains a complete copy of the project's 7.699 - history. TeamWare has no notion of a central repository. (CVS 7.700 - relied upon RCS for its history storage; TeamWare used 7.701 - SCCS.)</para> 7.702 - 7.703 - <para id="x_cc">As the 1990s progressed, awareness grew of a number of 7.704 - problems with CVS. It records simultaneous changes to multiple 7.705 - files individually, instead of grouping them together as a 7.706 - single logically atomic operation. It does not manage its file 7.707 - hierarchy well; it is easy to make a mess of a repository by 7.708 - renaming files and directories. Worse, its source code is 7.709 - difficult to read and maintain, which made the <quote>pain 7.710 - level</quote> of fixing these architectural problems 7.711 - prohibitive.</para> 7.712 - 7.713 - <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had 7.714 - worked on CVS, started a project to replace it with a tool that 7.715 - would have a better architecture and cleaner code. The result, 7.716 - Subversion, does not stray from CVS's centralised client/server 7.717 - model, but it adds multi-file atomic commits, better namespace 7.718 - management, and a number of other features that make it a 7.719 - generally better tool than CVS. Since its initial release, it 7.720 - has rapidly grown in popularity.</para> 7.721 - 7.722 - <para id="x_ce">More or less simultaneously, Graydon Hoare began working on 7.723 - an ambitious distributed revision control system that he named 7.724 - Monotone. While Monotone addresses many of CVS's design flaws 7.725 - and has a peer-to-peer architecture, it goes beyond earlier (and 7.726 - subsequent) revision control tools in a number of innovative 7.727 - ways. It uses cryptographic hashes as identifiers, and has an 7.728 - integral notion of <quote>trust</quote> for code from different 7.729 - sources.</para> 7.730 - 7.731 - <para id="x_cf">Mercurial began life in 2005. While a few aspects of its 7.732 - design are influenced by Monotone, Mercurial focuses on ease of 7.733 - use, high performance, and scalability to very large 7.734 + <title>Technical storytelling</title> 7.735 + 7.736 + <para id="x_72e">A few years ago, when I wanted to explain why I believed 7.737 + that distributed revision control is important, the field was 7.738 + then so new that there was almost no published literature to 7.739 + refer people to.</para> 7.740 + 7.741 + <para id="x_72f">Although at that time I spent some time working on the 7.742 + internals of Mercurial itself, I switched to writing this book 7.743 + because that seemed like the most effective way to help the 7.744 + software to reach a wide audience, along with the idea that 7.745 + revision control ought to be distributed in nature. I publish 7.746 + the book online under a liberal license for the same 7.747 + reason: to get the word out.</para> 7.748 + 7.749 + <para id="x_730">There's a familiar rhythm to a good software book that 7.750 + closely resembles telling a story: What is this thing? Why does 7.751 + it matter? How will it help me? How do I use it? In this 7.752 + book, I try to answer those questions for distributed revision 7.753 + control in general, and for Mercurial in particular.</para> 7.754 + </sect1> 7.755 + 7.756 + <sect1> 7.757 + <title>Thank you for supporting Mercurial</title> 7.758 + 7.759 + <para id="x_731">By purchasing a copy of this book, you are supporting the 7.760 + continued development and freedom of Mercurial in particular, 7.761 + and of open source and free software in general. O'Reilly Media 7.762 + and I are donating my royalties on the sales of this book to the 7.763 + Software Freedom Conservancy (<ulink 7.764 + url="http://www.softwarefreedom.org/">http://www.softwarefreedom.org/</ulink>) 7.765 + which provides clerical and legal support to Mercurial and a 7.766 + number of other prominent and worthy open source software 7.767 projects.</para> 7.768 - 7.769 - </sect1> 7.770 - 7.771 - <sect1> 7.772 - <title>Colophon&emdash;this book is Free</title> 7.773 - 7.774 - <para id="x_d0">This book is licensed under the Open Publication License, 7.775 - and is produced entirely using Free Software tools. It is 7.776 - typeset with DocBook XML. Illustrations are drawn and rendered with 7.777 - <ulink url="http://www.inkscape.org/">Inkscape</ulink>.</para> 7.778 - 7.779 - <para id="x_d1">The complete source code for this book is published as a 7.780 - Mercurial repository, at <ulink 7.781 - url="http://hg.serpentine.com/mercurial/book">http://hg.serpentine.com/mercurial/book</ulink>.</para> 7.782 - 7.783 + </sect1> 7.784 + 7.785 + <sect1> 7.786 + <title>Acknowledgments</title> 7.787 + 7.788 + <para id="x_732">This book would not exist were it not for the efforts of 7.789 + Matt Mackall, the author and project lead of Mercurial. He is 7.790 + ably assisted by hundreds of volunteer contributors across the 7.791 + world.</para> 7.792 + 7.793 + <para id="x_733">My children, Cian and Ruairi, always stood ready to help me 7.794 + to unwind with wonderful, madcap little-boy games. I'd also 7.795 + like to thank my ex-wife, Shannon, for her support.</para> 7.796 + 7.797 + <para id="x_734">My colleagues and friends provided help and support in 7.798 + innumerable ways. This list of people is necessarily very 7.799 + incomplete: Stephen Hahn, Karyn Ritter, Bonnie Corwin, James 7.800 + Vasile, Matt Norwood, Eben Moglen, Bradley Kuhn, Robert Walsh, 7.801 + Jeremy Fitzhardinge, Rachel Chalmers.</para> 7.802 + 7.803 + <para id="x_735">I developed this book in the open, posting drafts of 7.804 + chapters to the book web site as I completed them. Readers then 7.805 + submitted feedback using a web application that I developed. By 7.806 + the time I finished writing the book, more than 100 people had 7.807 + submitted comments, an amazing number considering that the 7.808 + comment system was live for only about two months towards the 7.809 + end of the writing process.</para> 7.810 + 7.811 + <para id="x_736">I would particularly like to recognize the following people, 7.812 + who between them contributed over a third of the total number of 7.813 + comments. I would like to thank them for their care and effort 7.814 + in providing so much detailed feedback.</para> 7.815 + 7.816 + <para id="x_737">Martin Geisler, Damien Cassou, Alexey Bakhirkin, Till Plewe, 7.817 + Dan Himes, Paul Sargent, Gokberk Hamurcu, Matthijs van der 7.818 + Vleuten, Michael Chermside, John Mulligan, Jordi Fita, Jon 7.819 + Parise.</para> 7.820 + 7.821 + <para id="x_738">I also want to acknowledge the help of the many people who 7.822 + caught errors and provided helpful suggestions throughout the 7.823 + book.</para> 7.824 + 7.825 + <para id="x_739">Jeremy W. Sherman, Brian Mearns, Vincent Furia, Iwan 7.826 + Luijks, Billy Edwards, Andreas Sliwka, Paweł Sołyga, Eric 7.827 + Hanchrow, Steve Nicolai, Michał Masłowski, Kevin Fitch, Johan 7.828 + Holmberg, Hal Wine, Volker Simonis, Thomas P Jakobsen, Ted 7.829 + Stresen-Reuter, Stephen Rasku, Raphael Das Gupta, Ned 7.830 + Batchelder, Lou Keeble, Li Linxiao, Kao Cardoso Félix, Joseph 7.831 + Wecker, Jon Prescot, Jon Maken, John Yeary, Jason Harris, 7.832 + Geoffrey Zheng, Fredrik Jonson, Ed Davies, David Zumbrunnen, 7.833 + David Mercer, David Cabana, Ben Karel, Alan Franzoni, Yousry 7.834 + Abdallah, Whitney Young, Vinay Sajip, Tom Towle, Tim Ottinger, 7.835 + Thomas Schraitle, Tero Saarni, Ted Mielczarek, Svetoslav 7.836 + Agafonkin, Shaun Rowland, Rocco Rutte, Polo-Francois Poli, 7.837 + Philip Jenvey, Petr Tesałék, Peter R. Annema, Paul Bonser, 7.838 + Olivier Scherler, Olivier Fournier, Nick Parker, Nick Fabry, 7.839 + Nicholas Guarracino, Mike Driscoll, Mike Coleman, Mietek Bák, 7.840 + Michael Maloney, László Nagy, Kent Johnson, Julio Nobrega, Jord 7.841 + Fita, Jonathan March, Jonas Nockert, Jim Tittsler, Jeduan 7.842 + Cornejo Legorreta, Jan Larres, James Murphy, Henri Wiechers, 7.843 + Hagen Möbius, Gábor Farkas, Fabien Engels, Evert Rol, Evan 7.844 + Willms, Eduardo Felipe Castegnaro, Dennis Decker Jensen, Deniz 7.845 + Dogan, David Smith, Daed Lee, Christine Slotty, Charles Merriam, 7.846 + Guillaume Catto, Brian Dorsey, Bob Nystrom, Benoit Boissinot, 7.847 + Avi Rosenschein, Andrew Watts, Andrew Donkin, Alexey Rodriguez, 7.848 + Ahmed Chaudhary.</para> 7.849 + </sect1> 7.850 + 7.851 + <sect1> 7.852 + <title>Conventions Used in This Book</title> 7.853 + 7.854 + <para id="x_73a">The following typographical conventions are used in this 7.855 + book:</para> 7.856 + 7.857 + <variablelist> 7.858 + <varlistentry> 7.859 + <term>Italic</term> 7.860 + 7.861 + <listitem> 7.862 + <para id="x_73b">Indicates new terms, URLs, email addresses, filenames, 7.863 + and file extensions.</para> 7.864 + </listitem> 7.865 + </varlistentry> 7.866 + 7.867 + <varlistentry> 7.868 + <term><literal>Constant width</literal></term> 7.869 + 7.870 + <listitem> 7.871 + <para id="x_73c">Used for program listings, as well as within 7.872 + paragraphs to refer to program elements such as variable 7.873 + or function names, databases, data types, environment 7.874 + variables, statements, and keywords.</para> 7.875 + </listitem> 7.876 + </varlistentry> 7.877 + 7.878 + <varlistentry> 7.879 + <term><userinput>Constant width bold</userinput></term> 7.880 + 7.881 + <listitem> 7.882 + <para id="x_73d">Shows commands or other text that should be typed 7.883 + literally by the user.</para> 7.884 + </listitem> 7.885 + </varlistentry> 7.886 + 7.887 + <varlistentry> 7.888 + <term><replaceable>Constant width italic</replaceable></term> 7.889 + 7.890 + <listitem> 7.891 + <para id="x_73e">Shows text that should be replaced with user-supplied 7.892 + values or by values determined by context.</para> 7.893 + </listitem> 7.894 + </varlistentry> 7.895 + </variablelist> 7.896 + 7.897 + <tip> 7.898 + <para id="x_73f">This icon signifies a tip, suggestion, or general 7.899 + note.</para> 7.900 + </tip> 7.901 + 7.902 + <caution> 7.903 + <para id="x_740">This icon indicates a warning or caution.</para> 7.904 + </caution> 7.905 + </sect1> 7.906 + 7.907 + <sect1> 7.908 + <title>Using Code Examples</title> 7.909 + 7.910 + <para id="x_741">This book is here to help you get your job done. In general, 7.911 + you may use the code in this book in your programs and 7.912 + documentation. You do not need to contact us for permission 7.913 + unless you’re reproducing a significant portion of the code. For 7.914 + example, writing a program that uses several chunks of code from 7.915 + this book does not require permission. Selling or distributing a 7.916 + CD-ROM of examples from O’Reilly books does require permission. 7.917 + Answering a question by citing this book and quoting example 7.918 + code does not require permission. Incorporating a significant 7.919 + amount of example code from this book into your product’s 7.920 + documentation does require permission.</para> 7.921 + 7.922 + <para id="x_742">We appreciate, but do not require, attribution. An 7.923 + attribution usually includes the title, author, publisher, and 7.924 + ISBN. For example: “<emphasis>Book Title</emphasis> by Some 7.925 + Author. Copyright 2008 O’Reilly Media, Inc., 7.926 + 978-0-596-xxxx-x.”</para> 7.927 + 7.928 + <para id="x_743">If you feel your use of code examples falls outside fair use 7.929 + or the permission given above, feel free to contact us at 7.930 + <email>permissions@oreilly.com</email>.</para> 7.931 + </sect1> 7.932 + 7.933 + <sect1> 7.934 + <title>Safari® Books Online</title> 7.935 + 7.936 + <note role="safarienabled"> 7.937 + <para id="x_744">When you see a Safari® Books Online icon on the cover of 7.938 + your favorite technology book, that means the book is 7.939 + available online through the O’Reilly Network Safari 7.940 + Bookshelf.</para> 7.941 + </note> 7.942 + 7.943 + <para id="x_745">Safari offers a solution that’s better than e-books. It’s a 7.944 + virtual library that lets you easily search thousands of top 7.945 + tech books, cut and paste code samples, download chapters, and 7.946 + find quick answers when you need the most accurate, current 7.947 + information. Try it for free at <ulink role="orm:hideurl:ital" 7.948 + url="http://my.safaribooksonline.com/?portal=oreilly">http://my.safaribooksonline.com</ulink>.</para> 7.949 + </sect1> 7.950 + 7.951 + <sect1> 7.952 + <title>How to Contact Us</title> 7.953 + 7.954 + <para id="x_746">Please address comments and questions concerning this book 7.955 + to the publisher:</para> 7.956 + 7.957 + <simplelist type="vert"> 7.958 + <member>O’Reilly Media, Inc.</member> 7.959 + 7.960 + <member>1005 Gravenstein Highway North</member> 7.961 + 7.962 + <member>Sebastopol, CA 95472</member> 7.963 + 7.964 + <member>800-998-9938 (in the United States or Canada)</member> 7.965 + 7.966 + <member>707-829-0515 (international or local)</member> 7.967 + 7.968 + <member>707 829-0104 (fax)</member> 7.969 + </simplelist> 7.970 + 7.971 + <para id="x_747">We have a web page for this book, where we list errata, 7.972 + examples, and any additional information. You can access this 7.973 + page at:</para> 7.974 + 7.975 + <simplelist type="vert"> 7.976 + <member><ulink url="http://www.oreilly.com/catalog/<catalog 7.977 + page>"></ulink></member> 7.978 + </simplelist> 7.979 + 7.980 + <remark>Don’t forget to update the <url> attribute, 7.981 + too.</remark> 7.982 + 7.983 + <para id="x_748">To comment or ask technical questions about this book, send 7.984 + email to:</para> 7.985 + 7.986 + <simplelist type="vert"> 7.987 + <member><email>bookquestions@oreilly.com</email></member> 7.988 + </simplelist> 7.989 + 7.990 + <para id="x_749">For more information about our books, conferences, Resource 7.991 + Centers, and the O’Reilly Network, see our web site at:</para> 7.992 + 7.993 + <simplelist type="vert"> 7.994 + <member><ulink url="http://www.oreilly.com"></ulink></member> 7.995 + </simplelist> 7.996 </sect1> 7.997 </preface> 7.998 + 7.999 <!-- 7.1000 local variables: 7.1001 sgml-parent-document: ("00book.xml" "book" "preface")
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/en/ch01-intro.xml Thu May 21 14:16:17 2009 +0800 8.3 @@ -0,0 +1,734 @@ 8.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 8.5 + 8.6 +<chapter id="chap:intro"> 8.7 + <?dbhtml filename="how-did-we-get-here.html"?> 8.8 + <title>How did we get here?</title> 8.9 + 8.10 + <sect1> 8.11 + <title>Why revision control? Why Mercurial?</title> 8.12 + 8.13 + <para id="x_6d">Revision control is the process of managing multiple 8.14 + versions of a piece of information. In its simplest form, this 8.15 + is something that many people do by hand: every time you modify 8.16 + a file, save it under a new name that contains a number, each 8.17 + one higher than the number of the preceding version.</para> 8.18 + 8.19 + <para id="x_6e">Manually managing multiple versions of even a single file is 8.20 + an error-prone task, though, so software tools to help automate 8.21 + this process have long been available. The earliest automated 8.22 + revision control tools were intended to help a single user to 8.23 + manage revisions of a single file. Over the past few decades, 8.24 + the scope of revision control tools has expanded greatly; they 8.25 + now manage multiple files, and help multiple people to work 8.26 + together. The best modern revision control tools have no 8.27 + problem coping with thousands of people working together on 8.28 + projects that consist of hundreds of thousands of files.</para> 8.29 + 8.30 + <para id="x_6f">The arrival of distributed revision control is relatively 8.31 + recent, and so far this new field has grown due to people's 8.32 + willingness to explore ill-charted territory.</para> 8.33 + 8.34 + <para id="x_70">I am writing a book about distributed revision control 8.35 + because I believe that it is an important subject that deserves 8.36 + a field guide. I chose to write about Mercurial because it is 8.37 + the easiest tool to learn the terrain with, and yet it scales to 8.38 + the demands of real, challenging environments where many other 8.39 + revision control tools buckle.</para> 8.40 + 8.41 + <sect2> 8.42 + <title>Why use revision control?</title> 8.43 + 8.44 + <para id="x_71">There are a number of reasons why you or your team might 8.45 + want to use an automated revision control tool for a 8.46 + project.</para> 8.47 + 8.48 + <itemizedlist> 8.49 + <listitem><para id="x_72">It will track the history and evolution of 8.50 + your project, so you don't have to. For every change, 8.51 + you'll have a log of <emphasis>who</emphasis> made it; 8.52 + <emphasis>why</emphasis> they made it; 8.53 + <emphasis>when</emphasis> they made it; and 8.54 + <emphasis>what</emphasis> the change 8.55 + was.</para></listitem> 8.56 + <listitem><para id="x_73">When you're working with other people, 8.57 + revision control software makes it easier for you to 8.58 + collaborate. For example, when people more or less 8.59 + simultaneously make potentially incompatible changes, the 8.60 + software will help you to identify and resolve those 8.61 + conflicts.</para></listitem> 8.62 + <listitem><para id="x_74">It can help you to recover from mistakes. If 8.63 + you make a change that later turns out to be in error, you 8.64 + can revert to an earlier version of one or more files. In 8.65 + fact, a <emphasis>really</emphasis> good revision control 8.66 + tool will even help you to efficiently figure out exactly 8.67 + when a problem was introduced (see <xref 8.68 + linkend="sec:undo:bisect"/> for details).</para></listitem> 8.69 + <listitem><para id="x_75">It will help you to work simultaneously on, 8.70 + and manage the drift between, multiple versions of your 8.71 + project.</para></listitem> 8.72 + </itemizedlist> 8.73 + 8.74 + <para id="x_76">Most of these reasons are equally 8.75 + valid&emdash;at least in theory&emdash;whether you're working 8.76 + on a project by yourself, or with a hundred other 8.77 + people.</para> 8.78 + 8.79 + <para id="x_77">A key question about the practicality of revision control 8.80 + at these two different scales (<quote>lone hacker</quote> and 8.81 + <quote>huge team</quote>) is how its 8.82 + <emphasis>benefits</emphasis> compare to its 8.83 + <emphasis>costs</emphasis>. A revision control tool that's 8.84 + difficult to understand or use is going to impose a high 8.85 + cost.</para> 8.86 + 8.87 + <para id="x_78">A five-hundred-person project is likely to collapse under 8.88 + its own weight almost immediately without a revision control 8.89 + tool and process. In this case, the cost of using revision 8.90 + control might hardly seem worth considering, since 8.91 + <emphasis>without</emphasis> it, failure is almost 8.92 + guaranteed.</para> 8.93 + 8.94 + <para id="x_79">On the other hand, a one-person <quote>quick hack</quote> 8.95 + might seem like a poor place to use a revision control tool, 8.96 + because surely the cost of using one must be close to the 8.97 + overall cost of the project. Right?</para> 8.98 + 8.99 + <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of 8.100 + these scales of development. You can learn the basics in just 8.101 + a few minutes, and due to its low overhead, you can apply 8.102 + revision control to the smallest of projects with ease. Its 8.103 + simplicity means you won't have a lot of abstruse concepts or 8.104 + command sequences competing for mental space with whatever 8.105 + you're <emphasis>really</emphasis> trying to do. At the same 8.106 + time, Mercurial's high performance and peer-to-peer nature let 8.107 + you scale painlessly to handle large projects.</para> 8.108 + 8.109 + <para id="x_7b">No revision control tool can rescue a poorly run project, 8.110 + but a good choice of tools can make a huge difference to the 8.111 + fluidity with which you can work on a project.</para> 8.112 + 8.113 + </sect2> 8.114 + 8.115 + <sect2> 8.116 + <title>The many names of revision control</title> 8.117 + 8.118 + <para id="x_7c">Revision control is a diverse field, so much so that it is 8.119 + referred to by many names and acronyms. Here are a few of the 8.120 + more common variations you'll encounter:</para> 8.121 + <itemizedlist> 8.122 + <listitem><para id="x_7d">Revision control (RCS)</para></listitem> 8.123 + <listitem><para id="x_7e">Software configuration management (SCM), or 8.124 + configuration management</para></listitem> 8.125 + <listitem><para id="x_7f">Source code management</para></listitem> 8.126 + <listitem><para id="x_80">Source code control, or source 8.127 + control</para></listitem> 8.128 + <listitem><para id="x_81">Version control 8.129 + (VCS)</para></listitem></itemizedlist> 8.130 + <para id="x_82">Some people claim that these terms actually have different 8.131 + meanings, but in practice they overlap so much that there's no 8.132 + agreed or even useful way to tease them apart.</para> 8.133 + 8.134 + </sect2> 8.135 + </sect1> 8.136 + 8.137 + <sect1> 8.138 + <title>About the examples in this book</title> 8.139 + 8.140 + <para id="x_84">This book takes an unusual approach to code samples. Every 8.141 + example is <quote>live</quote>&emdash;each one is actually the result 8.142 + of a shell script that executes the Mercurial commands you see. 8.143 + Every time an image of the book is built from its sources, all 8.144 + the example scripts are automatically run, and their current 8.145 + results compared against their expected results.</para> 8.146 + 8.147 + <para id="x_85">The advantage of this approach is that the examples are 8.148 + always accurate; they describe <emphasis>exactly</emphasis> the 8.149 + behavior of the version of Mercurial that's mentioned at the 8.150 + front of the book. If I update the version of Mercurial that 8.151 + I'm documenting, and the output of some command changes, the 8.152 + build fails.</para> 8.153 + 8.154 + <para id="x_86">There is a small disadvantage to this approach, which is 8.155 + that the dates and times you'll see in examples tend to be 8.156 + <quote>squashed</quote> together in a way that they wouldn't be 8.157 + if the same commands were being typed by a human. Where a human 8.158 + can issue no more than one command every few seconds, with any 8.159 + resulting timestamps correspondingly spread out, my automated 8.160 + example scripts run many commands in one second.</para> 8.161 + 8.162 + <para id="x_87">As an instance of this, several consecutive commits in an 8.163 + example can show up as having occurred during the same second. 8.164 + You can see this occur in the <literal 8.165 + role="hg-ext">bisect</literal> example in <xref 8.166 + linkend="sec:undo:bisect"/>, for instance.</para> 8.167 + 8.168 + <para id="x_88">So when you're reading examples, don't place too much weight 8.169 + on the dates or times you see in the output of commands. But 8.170 + <emphasis>do</emphasis> be confident that the behavior you're 8.171 + seeing is consistent and reproducible.</para> 8.172 + 8.173 + </sect1> 8.174 + 8.175 + <sect1> 8.176 + <title>Trends in the field</title> 8.177 + 8.178 + <para id="x_89">There has been an unmistakable trend in the development and 8.179 + use of revision control tools over the past four decades, as 8.180 + people have become familiar with the capabilities of their tools 8.181 + and constrained by their limitations.</para> 8.182 + 8.183 + <para id="x_8a">The first generation began by managing single files on 8.184 + individual computers. Although these tools represented a huge 8.185 + advance over ad-hoc manual revision control, their locking model 8.186 + and reliance on a single computer limited them to small, 8.187 + tightly-knit teams.</para> 8.188 + 8.189 + <para id="x_8b">The second generation loosened these constraints by moving 8.190 + to network-centered architectures, and managing entire projects 8.191 + at a time. As projects grew larger, they ran into new problems. 8.192 + With clients needing to talk to servers very frequently, server 8.193 + scaling became an issue for large projects. An unreliable 8.194 + network connection could prevent remote users from being able to 8.195 + talk to the server at all. As open source projects started 8.196 + making read-only access available anonymously to anyone, people 8.197 + without commit privileges found that they could not use the 8.198 + tools to interact with a project in a natural way, as they could 8.199 + not record their changes.</para> 8.200 + 8.201 + <para id="x_8c">The current generation of revision control tools is 8.202 + peer-to-peer in nature. All of these systems have dropped the 8.203 + dependency on a single central server, and allow people to 8.204 + distribute their revision control data to where it's actually 8.205 + needed. Collaboration over the Internet has moved from 8.206 + constrained by technology to a matter of choice and consensus. 8.207 + Modern tools can operate offline indefinitely and autonomously, 8.208 + with a network connection only needed when syncing changes with 8.209 + another repository.</para> 8.210 + 8.211 + </sect1> 8.212 + <sect1> 8.213 + <title>A few of the advantages of distributed revision 8.214 + control</title> 8.215 + 8.216 + <para id="x_8d">Even though distributed revision control tools have for 8.217 + several years been as robust and usable as their 8.218 + previous-generation counterparts, people using older tools have 8.219 + not yet necessarily woken up to their advantages. There are a 8.220 + number of ways in which distributed tools shine relative to 8.221 + centralised ones.</para> 8.222 + 8.223 + <para id="x_8e">For an individual developer, distributed tools are almost 8.224 + always much faster than centralised tools. This is for a simple 8.225 + reason: a centralised tool needs to talk over the network for 8.226 + many common operations, because most metadata is stored in a 8.227 + single copy on the central server. A distributed tool stores 8.228 + all of its metadata locally. All else being equal, talking over 8.229 + the network adds overhead to a centralised tool. Don't 8.230 + underestimate the value of a snappy, responsive tool: you're 8.231 + going to spend a lot of time interacting with your revision 8.232 + control software.</para> 8.233 + 8.234 + <para id="x_8f">Distributed tools are indifferent to the vagaries of your 8.235 + server infrastructure, again because they replicate metadata to 8.236 + so many locations. If you use a centralised system and your 8.237 + server catches fire, you'd better hope that your backup media 8.238 + are reliable, and that your last backup was recent and actually 8.239 + worked. With a distributed tool, you have many backups 8.240 + available on every contributor's computer.</para> 8.241 + 8.242 + <para id="x_90">The reliability of your network will affect distributed 8.243 + tools far less than it will centralised tools. You can't even 8.244 + use a centralised tool without a network connection, except for 8.245 + a few highly constrained commands. With a distributed tool, if 8.246 + your network connection goes down while you're working, you may 8.247 + not even notice. The only thing you won't be able to do is talk 8.248 + to repositories on other computers, something that is relatively 8.249 + rare compared with local operations. If you have a far-flung 8.250 + team of collaborators, this may be significant.</para> 8.251 + 8.252 + <sect2> 8.253 + <title>Advantages for open source projects</title> 8.254 + 8.255 + <para id="x_91">If you take a shine to an open source project and decide 8.256 + that you would like to start hacking on it, and that project 8.257 + uses a distributed revision control tool, you are at once a 8.258 + peer with the people who consider themselves the 8.259 + <quote>core</quote> of that project. If they publish their 8.260 + repositories, you can immediately copy their project history, 8.261 + start making changes, and record your work, using the same 8.262 + tools in the same ways as insiders. By contrast, with a 8.263 + centralised tool, you must use the software in a <quote>read 8.264 + only</quote> mode unless someone grants you permission to 8.265 + commit changes to their central server. Until then, you won't 8.266 + be able to record changes, and your local modifications will 8.267 + be at risk of corruption any time you try to update your 8.268 + client's view of the repository.</para> 8.269 + 8.270 + <sect3> 8.271 + <title>The forking non-problem</title> 8.272 + 8.273 + <para id="x_92">It has been suggested that distributed revision control 8.274 + tools pose some sort of risk to open source projects because 8.275 + they make it easy to <quote>fork</quote> the development of 8.276 + a project. A fork happens when there are differences in 8.277 + opinion or attitude between groups of developers that cause 8.278 + them to decide that they can't work together any longer. 8.279 + Each side takes a more or less complete copy of the 8.280 + project's source code, and goes off in its own 8.281 + direction.</para> 8.282 + 8.283 + <para id="x_93">Sometimes the camps in a fork decide to reconcile their 8.284 + differences. With a centralised revision control system, the 8.285 + <emphasis>technical</emphasis> process of reconciliation is 8.286 + painful, and has to be performed largely by hand. You have 8.287 + to decide whose revision history is going to 8.288 + <quote>win</quote>, and graft the other team's changes into 8.289 + the tree somehow. This usually loses some or all of one 8.290 + side's revision history.</para> 8.291 + 8.292 + <para id="x_94">What distributed tools do with respect to forking is 8.293 + they make forking the <emphasis>only</emphasis> way to 8.294 + develop a project. Every single change that you make is 8.295 + potentially a fork point. The great strength of this 8.296 + approach is that a distributed revision control tool has to 8.297 + be really good at <emphasis>merging</emphasis> forks, 8.298 + because forks are absolutely fundamental: they happen all 8.299 + the time.</para> 8.300 + 8.301 + <para id="x_95">If every piece of work that everybody does, all the 8.302 + time, is framed in terms of forking and merging, then what 8.303 + the open source world refers to as a <quote>fork</quote> 8.304 + becomes <emphasis>purely</emphasis> a social issue. If 8.305 + anything, distributed tools <emphasis>lower</emphasis> the 8.306 + likelihood of a fork:</para> 8.307 + <itemizedlist> 8.308 + <listitem><para id="x_96">They eliminate the social distinction that 8.309 + centralised tools impose: that between insiders (people 8.310 + with commit access) and outsiders (people 8.311 + without).</para></listitem> 8.312 + <listitem><para id="x_97">They make it easier to reconcile after a 8.313 + social fork, because all that's involved from the 8.314 + perspective of the revision control software is just 8.315 + another merge.</para></listitem></itemizedlist> 8.316 + 8.317 + <para id="x_98">Some people resist distributed tools because they want 8.318 + to retain tight control over their projects, and they 8.319 + believe that centralised tools give them this control. 8.320 + However, if you're of this belief, and you publish your CVS 8.321 + or Subversion repositories publicly, there are plenty of 8.322 + tools available that can pull out your entire project's 8.323 + history (albeit slowly) and recreate it somewhere that you 8.324 + don't control. So while your control in this case is 8.325 + illusory, you are forgoing the ability to fluidly 8.326 + collaborate with whatever people feel compelled to mirror 8.327 + and fork your history.</para> 8.328 + 8.329 + </sect3> 8.330 + </sect2> 8.331 + <sect2> 8.332 + <title>Advantages for commercial projects</title> 8.333 + 8.334 + <para id="x_99">Many commercial projects are undertaken by teams that are 8.335 + scattered across the globe. Contributors who are far from a 8.336 + central server will see slower command execution and perhaps 8.337 + less reliability. Commercial revision control systems attempt 8.338 + to ameliorate these problems with remote-site replication 8.339 + add-ons that are typically expensive to buy and cantankerous 8.340 + to administer. A distributed system doesn't suffer from these 8.341 + problems in the first place. Better yet, you can easily set 8.342 + up multiple authoritative servers, say one per site, so that 8.343 + there's no redundant communication between repositories over 8.344 + expensive long-haul network links.</para> 8.345 + 8.346 + <para id="x_9a">Centralised revision control systems tend to have 8.347 + relatively low scalability. It's not unusual for an expensive 8.348 + centralised system to fall over under the combined load of 8.349 + just a few dozen concurrent users. Once again, the typical 8.350 + response tends to be an expensive and clunky replication 8.351 + facility. Since the load on a central server&emdash;if you have 8.352 + one at all&emdash;is many times lower with a distributed tool 8.353 + (because all of the data is replicated everywhere), a single 8.354 + cheap server can handle the needs of a much larger team, and 8.355 + replication to balance load becomes a simple matter of 8.356 + scripting.</para> 8.357 + 8.358 + <para id="x_9b">If you have an employee in the field, troubleshooting a 8.359 + problem at a customer's site, they'll benefit from distributed 8.360 + revision control. The tool will let them generate custom 8.361 + builds, try different fixes in isolation from each other, and 8.362 + search efficiently through history for the sources of bugs and 8.363 + regressions in the customer's environment, all without needing 8.364 + to connect to your company's network.</para> 8.365 + 8.366 + </sect2> 8.367 + </sect1> 8.368 + <sect1> 8.369 + <title>Why choose Mercurial?</title> 8.370 + 8.371 + <para id="x_9c">Mercurial has a unique set of properties that make it a 8.372 + particularly good choice as a revision control system.</para> 8.373 + <itemizedlist> 8.374 + <listitem><para id="x_9d">It is easy to learn and use.</para></listitem> 8.375 + <listitem><para id="x_9e">It is lightweight.</para></listitem> 8.376 + <listitem><para id="x_9f">It scales excellently.</para></listitem> 8.377 + <listitem><para id="x_a0">It is easy to 8.378 + customise.</para></listitem></itemizedlist> 8.379 + 8.380 + <para id="x_a1">If you are at all familiar with revision control systems, 8.381 + you should be able to get up and running with Mercurial in less 8.382 + than five minutes. Even if not, it will take no more than a few 8.383 + minutes longer. Mercurial's command and feature sets are 8.384 + generally uniform and consistent, so you can keep track of a few 8.385 + general rules instead of a host of exceptions.</para> 8.386 + 8.387 + <para id="x_a2">On a small project, you can start working with Mercurial in 8.388 + moments. Creating new changes and branches; transferring changes 8.389 + around (whether locally or over a network); and history and 8.390 + status operations are all fast. Mercurial attempts to stay 8.391 + nimble and largely out of your way by combining low cognitive 8.392 + overhead with blazingly fast operations.</para> 8.393 + 8.394 + <para id="x_a3">The usefulness of Mercurial is not limited to small 8.395 + projects: it is used by projects with hundreds to thousands of 8.396 + contributors, each containing tens of thousands of files and 8.397 + hundreds of megabytes of source code.</para> 8.398 + 8.399 + <para id="x_a4">If the core functionality of Mercurial is not enough for 8.400 + you, it's easy to build on. Mercurial is well suited to 8.401 + scripting tasks, and its clean internals and implementation in 8.402 + Python make it easy to add features in the form of extensions. 8.403 + There are a number of popular and useful extensions already 8.404 + available, ranging from helping to identify bugs to improving 8.405 + performance.</para> 8.406 + 8.407 + </sect1> 8.408 + <sect1> 8.409 + <title>Mercurial compared with other tools</title> 8.410 + 8.411 + <para id="x_a5">Before you read on, please understand that this section 8.412 + necessarily reflects my own experiences, interests, and (dare I 8.413 + say it) biases. I have used every one of the revision control 8.414 + tools listed below, in most cases for several years at a 8.415 + time.</para> 8.416 + 8.417 + 8.418 + <sect2> 8.419 + <title>Subversion</title> 8.420 + 8.421 + <para id="x_a6">Subversion is a popular revision control tool, developed 8.422 + to replace CVS. It has a centralised client/server 8.423 + architecture.</para> 8.424 + 8.425 + <para id="x_a7">Subversion and Mercurial have similarly named commands for 8.426 + performing the same operations, so if you're familiar with 8.427 + one, it is easy to learn to use the other. Both tools are 8.428 + portable to all popular operating systems.</para> 8.429 + 8.430 + <para id="x_a8">Prior to version 1.5, Subversion had no useful support for 8.431 + merges. At the time of writing, its merge tracking capability 8.432 + is new, and known to be <ulink 8.433 + url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 8.434 + and buggy</ulink>.</para> 8.435 + 8.436 + <para id="x_a9">Mercurial has a substantial performance advantage over 8.437 + Subversion on every revision control operation I have 8.438 + benchmarked. I have measured its advantage as ranging from a 8.439 + factor of two to a factor of six when compared with Subversion 8.440 + 1.4.3's <emphasis>ra_local</emphasis> file store, which is the 8.441 + fastest access method available. In more realistic 8.442 + deployments involving a network-based store, Subversion will 8.443 + be at a substantially larger disadvantage. Because many 8.444 + Subversion commands must talk to the server and Subversion 8.445 + does not have useful replication facilities, server capacity 8.446 + and network bandwidth become bottlenecks for modestly large 8.447 + projects.</para> 8.448 + 8.449 + <para id="x_aa">Additionally, Subversion incurs substantial storage 8.450 + overhead to avoid network transactions for a few common 8.451 + operations, such as finding modified files 8.452 + (<literal>status</literal>) and displaying modifications 8.453 + against the current revision (<literal>diff</literal>). As a 8.454 + result, a Subversion working copy is often the same size as, 8.455 + or larger than, a Mercurial repository and working directory, 8.456 + even though the Mercurial repository contains a complete 8.457 + history of the project.</para> 8.458 + 8.459 + <para id="x_ab">Subversion is widely supported by third party tools. 8.460 + Mercurial currently lags considerably in this area. This gap 8.461 + is closing, however, and indeed some of Mercurial's GUI tools 8.462 + now outshine their Subversion equivalents. Like Mercurial, 8.463 + Subversion has an excellent user manual.</para> 8.464 + 8.465 + <para id="x_ac">Because Subversion doesn't store revision history on the 8.466 + client, it is well suited to managing projects that deal with 8.467 + lots of large, opaque binary files. If you check in fifty 8.468 + revisions to an incompressible 10MB file, Subversion's 8.469 + client-side space usage stays constant The space used by any 8.470 + distributed SCM will grow rapidly in proportion to the number 8.471 + of revisions, because the differences between each revision 8.472 + are large.</para> 8.473 + 8.474 + <para id="x_ad">In addition, it's often difficult or, more usually, 8.475 + impossible to merge different versions of a binary file. 8.476 + Subversion's ability to let a user lock a file, so that they 8.477 + temporarily have the exclusive right to commit changes to it, 8.478 + can be a significant advantage to a project where binary files 8.479 + are widely used.</para> 8.480 + 8.481 + <para id="x_ae">Mercurial can import revision history from a Subversion 8.482 + repository. It can also export revision history to a 8.483 + Subversion repository. This makes it easy to <quote>test the 8.484 + waters</quote> and use Mercurial and Subversion in parallel 8.485 + before deciding to switch. History conversion is incremental, 8.486 + so you can perform an initial conversion, then small 8.487 + additional conversions afterwards to bring in new 8.488 + changes.</para> 8.489 + 8.490 + 8.491 + </sect2> 8.492 + <sect2> 8.493 + <title>Git</title> 8.494 + 8.495 + <para id="x_af">Git is a distributed revision control tool that was 8.496 + developed for managing the Linux kernel source tree. Like 8.497 + Mercurial, its early design was somewhat influenced by 8.498 + Monotone.</para> 8.499 + 8.500 + <para id="x_b0">Git has a very large command set, with version 1.5.0 8.501 + providing 139 individual commands. It has something of a 8.502 + reputation for being difficult to learn. Compared to Git, 8.503 + Mercurial has a strong focus on simplicity.</para> 8.504 + 8.505 + <para id="x_b1">In terms of performance, Git is extremely fast. In 8.506 + several cases, it is faster than Mercurial, at least on Linux, 8.507 + while Mercurial performs better on other operations. However, 8.508 + on Windows, the performance and general level of support that 8.509 + Git provides is, at the time of writing, far behind that of 8.510 + Mercurial.</para> 8.511 + 8.512 + <para id="x_b2">While a Mercurial repository needs no maintenance, a Git 8.513 + repository requires frequent manual <quote>repacks</quote> of 8.514 + its metadata. Without these, performance degrades, while 8.515 + space usage grows rapidly. A server that contains many Git 8.516 + repositories that are not rigorously and frequently repacked 8.517 + will become heavily disk-bound during backups, and there have 8.518 + been instances of daily backups taking far longer than 24 8.519 + hours as a result. A freshly packed Git repository is 8.520 + slightly smaller than a Mercurial repository, but an unpacked 8.521 + repository is several orders of magnitude larger.</para> 8.522 + 8.523 + <para id="x_b3">The core of Git is written in C. Many Git commands are 8.524 + implemented as shell or Perl scripts, and the quality of these 8.525 + scripts varies widely. I have encountered several instances 8.526 + where scripts charged along blindly in the presence of errors 8.527 + that should have been fatal.</para> 8.528 + 8.529 + <para id="x_b4">Mercurial can import revision history from a Git 8.530 + repository.</para> 8.531 + 8.532 + 8.533 + </sect2> 8.534 + <sect2> 8.535 + <title>CVS</title> 8.536 + 8.537 + <para id="x_b5">CVS is probably the most widely used revision control tool 8.538 + in the world. Due to its age and internal untidiness, it has 8.539 + been only lightly maintained for many years.</para> 8.540 + 8.541 + <para id="x_b6">It has a centralised client/server architecture. It does 8.542 + not group related file changes into atomic commits, making it 8.543 + easy for people to <quote>break the build</quote>: one person 8.544 + can successfully commit part of a change and then be blocked 8.545 + by the need for a merge, causing other people to see only a 8.546 + portion of the work they intended to do. This also affects 8.547 + how you work with project history. If you want to see all of 8.548 + the modifications someone made as part of a task, you will 8.549 + need to manually inspect the descriptions and timestamps of 8.550 + the changes made to each file involved (if you even know what 8.551 + those files were).</para> 8.552 + 8.553 + <para id="x_b7">CVS has a muddled notion of tags and branches that I will 8.554 + not attempt to even describe. It does not support renaming of 8.555 + files or directories well, making it easy to corrupt a 8.556 + repository. It has almost no internal consistency checking 8.557 + capabilities, so it is usually not even possible to tell 8.558 + whether or how a repository is corrupt. I would not recommend 8.559 + CVS for any project, existing or new.</para> 8.560 + 8.561 + <para id="x_b8">Mercurial can import CVS revision history. However, there 8.562 + are a few caveats that apply; these are true of every other 8.563 + revision control tool's CVS importer, too. Due to CVS's lack 8.564 + of atomic changes and unversioned filesystem hierarchy, it is 8.565 + not possible to reconstruct CVS history completely accurately; 8.566 + some guesswork is involved, and renames will usually not show 8.567 + up. Because a lot of advanced CVS administration has to be 8.568 + done by hand and is hence error-prone, it's common for CVS 8.569 + importers to run into multiple problems with corrupted 8.570 + repositories (completely bogus revision timestamps and files 8.571 + that have remained locked for over a decade are just two of 8.572 + the less interesting problems I can recall from personal 8.573 + experience).</para> 8.574 + 8.575 + <para id="x_b9">Mercurial can import revision history from a CVS 8.576 + repository.</para> 8.577 + 8.578 + 8.579 + </sect2> 8.580 + <sect2> 8.581 + <title>Commercial tools</title> 8.582 + 8.583 + <para id="x_ba">Perforce has a centralised client/server architecture, 8.584 + with no client-side caching of any data. Unlike modern 8.585 + revision control tools, Perforce requires that a user run a 8.586 + command to inform the server about every file they intend to 8.587 + edit.</para> 8.588 + 8.589 + <para id="x_bb">The performance of Perforce is quite good for small teams, 8.590 + but it falls off rapidly as the number of users grows beyond a 8.591 + few dozen. Modestly large Perforce installations require the 8.592 + deployment of proxies to cope with the load their users 8.593 + generate.</para> 8.594 + 8.595 + 8.596 + </sect2> 8.597 + <sect2> 8.598 + <title>Choosing a revision control tool</title> 8.599 + 8.600 + <para id="x_bc">With the exception of CVS, all of the tools listed above 8.601 + have unique strengths that suit them to particular styles of 8.602 + work. There is no single revision control tool that is best 8.603 + in all situations.</para> 8.604 + 8.605 + <para id="x_bd">As an example, Subversion is a good choice for working 8.606 + with frequently edited binary files, due to its centralised 8.607 + nature and support for file locking.</para> 8.608 + 8.609 + <para id="x_be">I personally find Mercurial's properties of simplicity, 8.610 + performance, and good merge support to be a compelling 8.611 + combination that has served me well for several years.</para> 8.612 + 8.613 + 8.614 + </sect2> 8.615 + </sect1> 8.616 + <sect1> 8.617 + <title>Switching from another tool to Mercurial</title> 8.618 + 8.619 + <para id="x_bf">Mercurial is bundled with an extension named <literal 8.620 + role="hg-ext">convert</literal>, which can incrementally 8.621 + import revision history from several other revision control 8.622 + tools. By <quote>incremental</quote>, I mean that you can 8.623 + convert all of a project's history to date in one go, then rerun 8.624 + the conversion later to obtain new changes that happened after 8.625 + the initial conversion.</para> 8.626 + 8.627 + <para id="x_c0">The revision control tools supported by <literal 8.628 + role="hg-ext">convert</literal> are as follows:</para> 8.629 + <itemizedlist> 8.630 + <listitem><para id="x_c1">Subversion</para></listitem> 8.631 + <listitem><para id="x_c2">CVS</para></listitem> 8.632 + <listitem><para id="x_c3">Git</para></listitem> 8.633 + <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist> 8.634 + 8.635 + <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can 8.636 + export changes from Mercurial to Subversion. This makes it 8.637 + possible to try Subversion and Mercurial in parallel before 8.638 + committing to a switchover, without risking the loss of any 8.639 + work.</para> 8.640 + 8.641 + <para id="x_c6">The <command role="hg-ext-convert">convert</command> command 8.642 + is easy to use. Simply point it at the path or URL of the 8.643 + source repository, optionally give it the name of the 8.644 + destination repository, and it will start working. After the 8.645 + initial conversion, just run the same command again to import 8.646 + new changes.</para> 8.647 + </sect1> 8.648 + 8.649 + <sect1> 8.650 + <title>A short history of revision control</title> 8.651 + 8.652 + <para id="x_c7">The best known of the old-time revision control tools is 8.653 + SCCS (Source Code Control System), which Marc Rochkind wrote at 8.654 + Bell Labs, in the early 1970s. SCCS operated on individual 8.655 + files, and required every person working on a project to have 8.656 + access to a shared workspace on a single system. Only one 8.657 + person could modify a file at any time; arbitration for access 8.658 + to files was via locks. It was common for people to lock files, 8.659 + and later forget to unlock them, preventing anyone else from 8.660 + modifying those files without the help of an 8.661 + administrator.</para> 8.662 + 8.663 + <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the 8.664 + early 1980s; he called his program RCS (Revision Control System). 8.665 + Like SCCS, RCS required developers to work in a single shared 8.666 + workspace, and to lock files to prevent multiple people from 8.667 + modifying them simultaneously.</para> 8.668 + 8.669 + <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block 8.670 + for a set of shell scripts he initially called cmt, but then 8.671 + renamed to CVS (Concurrent Versions System). The big innovation 8.672 + of CVS was that it let developers work simultaneously and 8.673 + somewhat independently in their own personal workspaces. The 8.674 + personal workspaces prevented developers from stepping on each 8.675 + other's toes all the time, as was common with SCCS and RCS. Each 8.676 + developer had a copy of every project file, and could modify 8.677 + their copies independently. They had to merge their edits prior 8.678 + to committing changes to the central repository.</para> 8.679 + 8.680 + <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote 8.681 + them in C, releasing in 1989 the code that has since developed 8.682 + into the modern version of CVS. CVS subsequently acquired the 8.683 + ability to operate over a network connection, giving it a 8.684 + client/server architecture. CVS's architecture is centralised; 8.685 + only the server has a copy of the history of the project. Client 8.686 + workspaces just contain copies of recent versions of the 8.687 + project's files, and a little metadata to tell them where the 8.688 + server is. CVS has been enormously successful; it is probably 8.689 + the world's most widely used revision control system.</para> 8.690 + 8.691 + <para id="x_cb">In the early 1990s, Sun Microsystems developed an early 8.692 + distributed revision control system, called TeamWare. A 8.693 + TeamWare workspace contains a complete copy of the project's 8.694 + history. TeamWare has no notion of a central repository. (CVS 8.695 + relied upon RCS for its history storage; TeamWare used 8.696 + SCCS.)</para> 8.697 + 8.698 + <para id="x_cc">As the 1990s progressed, awareness grew of a number of 8.699 + problems with CVS. It records simultaneous changes to multiple 8.700 + files individually, instead of grouping them together as a 8.701 + single logically atomic operation. It does not manage its file 8.702 + hierarchy well; it is easy to make a mess of a repository by 8.703 + renaming files and directories. Worse, its source code is 8.704 + difficult to read and maintain, which made the <quote>pain 8.705 + level</quote> of fixing these architectural problems 8.706 + prohibitive.</para> 8.707 + 8.708 + <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had 8.709 + worked on CVS, started a project to replace it with a tool that 8.710 + would have a better architecture and cleaner code. The result, 8.711 + Subversion, does not stray from CVS's centralised client/server 8.712 + model, but it adds multi-file atomic commits, better namespace 8.713 + management, and a number of other features that make it a 8.714 + generally better tool than CVS. Since its initial release, it 8.715 + has rapidly grown in popularity.</para> 8.716 + 8.717 + <para id="x_ce">More or less simultaneously, Graydon Hoare began working on 8.718 + an ambitious distributed revision control system that he named 8.719 + Monotone. While Monotone addresses many of CVS's design flaws 8.720 + and has a peer-to-peer architecture, it goes beyond earlier (and 8.721 + subsequent) revision control tools in a number of innovative 8.722 + ways. It uses cryptographic hashes as identifiers, and has an 8.723 + integral notion of <quote>trust</quote> for code from different 8.724 + sources.</para> 8.725 + 8.726 + <para id="x_cf">Mercurial began life in 2005. While a few aspects of its 8.727 + design are influenced by Monotone, Mercurial focuses on ease of 8.728 + use, high performance, and scalability to very large 8.729 + projects.</para> 8.730 + </sect1> 8.731 +</chapter> 8.732 + 8.733 +<!-- 8.734 +local variables: 8.735 +sgml-parent-document: ("00book.xml" "book" "chapter") 8.736 +end: 8.737 +-->
9.1 --- a/en/ch01-tour-basic.xml Sat Apr 18 11:52:33 2009 +0800 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,930 +0,0 @@ 9.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 9.5 - 9.6 -<chapter id="chap:tour-basic"> 9.7 - <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?> 9.8 - <title>A tour of Mercurial: the basics</title> 9.9 - 9.10 - <sect1 id="sec:tour:install"> 9.11 - <title>Installing Mercurial on your system</title> 9.12 - 9.13 - <para id="x_1">Prebuilt binary packages of Mercurial are available for 9.14 - every popular operating system. These make it easy to start 9.15 - using Mercurial on your computer immediately.</para> 9.16 - 9.17 - <sect2> 9.18 - <title>Windows</title> 9.19 - 9.20 - <para id="x_c">The best version of Mercurial for Windows is 9.21 - TortoiseHg, which can be found at <ulink 9.22 - url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>. 9.23 - This package has no external dependencies; it <quote>just 9.24 - works</quote>. It provides both command line and graphical 9.25 - user interfaces.</para> 9.26 - 9.27 - </sect2> 9.28 - 9.29 - <sect2> 9.30 - <title>Mac OS X</title> 9.31 - 9.32 - <para id="x_a">Lee Cantey publishes an installer of Mercurial 9.33 - for Mac OS X at <ulink 9.34 - url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para> 9.35 - </sect2> 9.36 - 9.37 - <sect2> 9.38 - <title>Linux</title> 9.39 - 9.40 - <para id="x_2">Because each Linux distribution has its own packaging 9.41 - tools, policies, and rate of development, it's difficult to 9.42 - give a comprehensive set of instructions on how to install 9.43 - Mercurial binaries. The version of Mercurial that you will 9.44 - end up with can vary depending on how active the person is who 9.45 - maintains the package for your distribution.</para> 9.46 - 9.47 - <para id="x_3">To keep things simple, I will focus on installing 9.48 - Mercurial from the command line under the most popular Linux 9.49 - distributions. Most of these distributions provide graphical 9.50 - package managers that will let you install Mercurial with a 9.51 - single click; the package name to look for is 9.52 - <literal>mercurial</literal>.</para> 9.53 - 9.54 - <itemizedlist> 9.55 - <listitem><para id="x_4">Ubuntu and Debian:</para> 9.56 - <programlisting>apt-get install mercurial</programlisting></listitem> 9.57 - <listitem><para id="x_5">Fedora and OpenSUSE:</para> 9.58 - <programlisting>yum install mercurial</programlisting></listitem> 9.59 - <listitem><para id="x_6">Gentoo:</para> 9.60 - <programlisting>emerge mercurial</programlisting></listitem> 9.61 - </itemizedlist> 9.62 - 9.63 - </sect2> 9.64 - <sect2> 9.65 - <title>Solaris</title> 9.66 - 9.67 - <para id="x_9">SunFreeWare, at <ulink 9.68 - url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 9.69 - provides prebuilt packages of Mercurial.</para> 9.70 - 9.71 - </sect2> 9.72 - 9.73 - </sect1> 9.74 - 9.75 - <sect1> 9.76 - <title>Getting started</title> 9.77 - 9.78 - <para id="x_e">To begin, we'll use the <command role="hg-cmd">hg 9.79 - version</command> command to find out whether Mercurial is 9.80 - actually installed properly. The actual version information 9.81 - that it prints isn't so important; it's whether it prints 9.82 - anything at all that we care about.</para> 9.83 - 9.84 - &interaction.tour.version; 9.85 - 9.86 - <sect2> 9.87 - <title>Built-in help</title> 9.88 - 9.89 - <para id="x_f">Mercurial provides a built-in help system. This is 9.90 - invaluable for those times when you find yourself stuck 9.91 - trying to remember how to run a command. If you are 9.92 - completely stuck, simply run <command role="hg-cmd">hg 9.93 - help</command>; it will print a brief list of commands, 9.94 - along with a description of what each does. If you ask for 9.95 - help on a specific command (as below), it prints more 9.96 - detailed information.</para> 9.97 - 9.98 - &interaction.tour.help; 9.99 - 9.100 - <para id="x_10">For a more impressive level of detail (which you won't 9.101 - usually need) run <command role="hg-cmd">hg help <option 9.102 - role="hg-opt-global">-v</option></command>. The <option 9.103 - role="hg-opt-global">-v</option> option is short for 9.104 - <option role="hg-opt-global">--verbose</option>, and tells 9.105 - Mercurial to print more information than it usually 9.106 - would.</para> 9.107 - 9.108 - </sect2> 9.109 - </sect1> 9.110 - <sect1> 9.111 - <title>Working with a repository</title> 9.112 - 9.113 - <para id="x_11">In Mercurial, everything happens inside a 9.114 - <emphasis>repository</emphasis>. The repository for a project 9.115 - contains all of the files that <quote>belong to</quote> that 9.116 - project, along with a historical record of the project's 9.117 - files.</para> 9.118 - 9.119 - <para id="x_12">There's nothing particularly magical about a repository; it 9.120 - is simply a directory tree in your filesystem that Mercurial 9.121 - treats as special. You can rename or delete a repository any 9.122 - time you like, using either the command line or your file 9.123 - browser.</para> 9.124 - 9.125 - <sect2> 9.126 - <title>Making a local copy of a repository</title> 9.127 - 9.128 - <para id="x_13"><emphasis>Copying</emphasis> a repository is just a little 9.129 - bit special. While you could use a normal file copying 9.130 - command to make a copy of a repository, it's best to use a 9.131 - built-in command that Mercurial provides. This command is 9.132 - called <command role="hg-cmd">hg clone</command>, because it 9.133 - makes an identical copy of an existing repository.</para> 9.134 - 9.135 - &interaction.tour.clone; 9.136 - 9.137 - <para id="x_67c">One advantage of using <command role="hg-cmd">hg 9.138 - clone</command> is that, as we can see above, it lets us clone 9.139 - repositories over the network. Another is that it remembers 9.140 - where we cloned from, which we'll find useful soon when we 9.141 - want to fetch new changes from another repository.</para> 9.142 - 9.143 - <para id="x_14">If our clone succeeded, we should now have a local 9.144 - directory called <filename class="directory">hello</filename>. 9.145 - This directory will contain some files.</para> 9.146 - 9.147 - &interaction.tour.ls; 9.148 - 9.149 - <para id="x_15">These files have the same contents and history in our 9.150 - repository as they do in the repository we cloned.</para> 9.151 - 9.152 - <para id="x_16">Every Mercurial repository is complete, 9.153 - self-contained, and independent. It contains its own private 9.154 - copy of a project's files and history. As we just mentioned, 9.155 - a cloned repository remembers the location of the repository 9.156 - it was cloned from, but Mercurial will not communicate with 9.157 - that repository, or any other, unless you tell it to.</para> 9.158 - 9.159 - <para id="x_17">What this means for now is that we're free to experiment 9.160 - with our repository, safe in the knowledge that it's a private 9.161 - <quote>sandbox</quote> that won't affect anyone else.</para> 9.162 - 9.163 - </sect2> 9.164 - <sect2> 9.165 - <title>What's in a repository?</title> 9.166 - 9.167 - <para id="x_18">When we take a more detailed look inside a repository, we 9.168 - can see that it contains a directory named <filename 9.169 - class="directory">.hg</filename>. This is where Mercurial 9.170 - keeps all of its metadata for the repository.</para> 9.171 - 9.172 - &interaction.tour.ls-a; 9.173 - 9.174 - <para id="x_19">The contents of the <filename 9.175 - class="directory">.hg</filename> directory and its 9.176 - subdirectories are private to Mercurial. Every other file and 9.177 - directory in the repository is yours to do with as you 9.178 - please.</para> 9.179 - 9.180 - <para id="x_1a">To introduce a little terminology, the <filename 9.181 - class="directory">.hg</filename> directory is the 9.182 - <quote>real</quote> repository, and all of the files and 9.183 - directories that coexist with it are said to live in the 9.184 - <emphasis>working directory</emphasis>. An easy way to 9.185 - remember the distinction is that the 9.186 - <emphasis>repository</emphasis> contains the 9.187 - <emphasis>history</emphasis> of your project, while the 9.188 - <emphasis>working directory</emphasis> contains a 9.189 - <emphasis>snapshot</emphasis> of your project at a particular 9.190 - point in history.</para> 9.191 - 9.192 - </sect2> 9.193 - </sect1> 9.194 - <sect1> 9.195 - <title>A tour through history</title> 9.196 - 9.197 - <para id="x_1b">One of the first things we might want to do with a new, 9.198 - unfamiliar repository is understand its history. The <command 9.199 - role="hg-cmd">hg log</command> command gives us a view of 9.200 - the history of changes in the repository.</para> 9.201 - 9.202 - &interaction.tour.log; 9.203 - 9.204 - <para id="x_1c">By default, this command prints a brief paragraph of output 9.205 - for each change to the project that was recorded. In Mercurial 9.206 - terminology, we call each of these recorded events a 9.207 - <emphasis>changeset</emphasis>, because it can contain a record 9.208 - of changes to several files.</para> 9.209 - 9.210 - <para id="x_1d">The fields in a record of output from <command 9.211 - role="hg-cmd">hg log</command> are as follows.</para> 9.212 - 9.213 - <itemizedlist> 9.214 - <listitem><para id="x_1e"><literal>changeset</literal>: This 9.215 - field has the format of a number, followed by a colon, 9.216 - followed by a hexadecimal (or <emphasis>hex</emphasis>) 9.217 - string. These are <emphasis>identifiers</emphasis> for the 9.218 - changeset. The hex string is a unique identifier: the same 9.219 - hex string will always refer to the same changeset. The 9.220 - number is shorter and easier to type than the hex string, 9.221 - but it isn't unique: the same number in two different clones 9.222 - of a repository may identify different changesets. Why 9.223 - provide the number at all, then? For local 9.224 - convenience.</para> 9.225 - </listitem> 9.226 - <listitem><para id="x_1f"><literal>user</literal>: The identity of the 9.227 - person who created the changeset. This is a free-form 9.228 - field, but it most often contains a person's name and email 9.229 - address.</para></listitem> 9.230 - <listitem><para id="x_20"><literal>date</literal>: The date and time on 9.231 - which the changeset was created, and the timezone in which 9.232 - it was created. (The date and time are local to that 9.233 - timezone; they display what time and date it was for the 9.234 - person who created the changeset.)</para></listitem> 9.235 - <listitem><para id="x_21"><literal>summary</literal>: The first line of 9.236 - the text message that the creator of the changeset entered 9.237 - to describe the changeset.</para></listitem> 9.238 - <listitem> 9.239 - <para id="x_67d">Some changesets, such as the first in the list above, 9.240 - have a <literal>tag</literal> field. A tag is another way 9.241 - to identify a changeset, by giving it an easy-to-remember 9.242 - name. (The tag named <literal>tip</literal> is special: it 9.243 - always refers to the newest change in a repository.)</para> 9.244 - </listitem> 9.245 - </itemizedlist> 9.246 - 9.247 - <para id="x_22">The default output printed by <command 9.248 - role="hg-cmd">hg log</command> is purely a summary; it is 9.249 - missing a lot of detail.</para> 9.250 - 9.251 - <para id="x_23"><xref linkend="fig:tour-basic:history"/> provides 9.252 - a graphical representation of the history of the <filename 9.253 - class="directory">hello</filename> repository, to make it a 9.254 - little easier to see which direction history is 9.255 - <quote>flowing</quote> in. We'll be returning to this figure 9.256 - several times in this chapter and the chapter that 9.257 - follows.</para> 9.258 - 9.259 - <figure id="fig:tour-basic:history"> 9.260 - <title>Graphical history of the <filename 9.261 - class="directory">hello</filename> repository</title> 9.262 - <mediaobject> 9.263 - <imageobject><imagedata fileref="figs/tour-history.png"/></imageobject> 9.264 - <textobject><phrase>XXX add text</phrase></textobject> 9.265 - </mediaobject> 9.266 - </figure> 9.267 - 9.268 - <sect2> 9.269 - <title>Changesets, revisions, and talking to other 9.270 - people</title> 9.271 - 9.272 - <para id="x_25">As English is a notoriously sloppy language, and computer 9.273 - science has a hallowed history of terminological confusion 9.274 - (why use one term when four will do?), revision control has a 9.275 - variety of words and phrases that mean the same thing. If you 9.276 - are talking about Mercurial history with other people, you 9.277 - will find that the word <quote>changeset</quote> is often 9.278 - compressed to <quote>change</quote> or (when written) 9.279 - <quote>cset</quote>, and sometimes a changeset is referred to 9.280 - as a <quote>revision</quote> or a <quote>rev</quote>.</para> 9.281 - 9.282 - <para id="x_26">While it doesn't matter what <emphasis>word</emphasis> you 9.283 - use to refer to the concept of <quote>a changeset</quote>, the 9.284 - <emphasis>identifier</emphasis> that you use to refer to 9.285 - <quote>a <emphasis>specific</emphasis> changeset</quote> is of 9.286 - great importance. Recall that the <literal>changeset</literal> 9.287 - field in the output from <command role="hg-cmd">hg 9.288 - log</command> identifies a changeset using both a number and 9.289 - a hexadecimal string.</para> 9.290 - <itemizedlist> 9.291 - <listitem><para id="x_27">The revision number is a handy 9.292 - notation that is <emphasis>only valid in that 9.293 - repository</emphasis>.</para></listitem> 9.294 - <listitem><para id="x_28">The hexadecimal string is the 9.295 - <emphasis>permanent, unchanging identifier</emphasis> that 9.296 - will always identify that exact changeset in 9.297 - <emphasis>every</emphasis> copy of the 9.298 - repository.</para></listitem></itemizedlist> 9.299 - 9.300 - <para id="x_29">This distinction is important. If you send 9.301 - someone an email talking about <quote>revision 33</quote>, 9.302 - there's a high likelihood that their revision 33 will 9.303 - <emphasis>not be the same</emphasis> as yours. The reason for 9.304 - this is that a revision number depends on the order in which 9.305 - changes arrived in a repository, and there is no guarantee 9.306 - that the same changes will happen in the same order in 9.307 - different repositories. Three changes <literal>a,b,c</literal> 9.308 - can easily appear in one repository as 9.309 - <literal>0,1,2</literal>, while in another as 9.310 - <literal>0,2,1</literal>.</para> 9.311 - 9.312 - <para id="x_2a">Mercurial uses revision numbers purely as a convenient 9.313 - shorthand. If you need to discuss a changeset with someone, 9.314 - or make a record of a changeset for some other reason (for 9.315 - example, in a bug report), use the hexadecimal 9.316 - identifier.</para> 9.317 - 9.318 - </sect2> 9.319 - <sect2> 9.320 - <title>Viewing specific revisions</title> 9.321 - 9.322 - <para id="x_2b">To narrow the output of <command role="hg-cmd">hg 9.323 - log</command> down to a single revision, use the <option 9.324 - role="hg-opt-log">-r</option> (or <option 9.325 - role="hg-opt-log">--rev</option>) option. You can use 9.326 - either a revision number or a hexadecimal identifier, 9.327 - and you can provide as many revisions as you want.</para> 9.328 - 9.329 - &interaction.tour.log-r; 9.330 - 9.331 - <para id="x_2c">If you want to see the history of several revisions 9.332 - without having to list each one, you can use <emphasis>range 9.333 - notation</emphasis>; this lets you express the idea <quote>I 9.334 - want all revisions between <literal>abc</literal> and 9.335 - <literal>def</literal>, inclusive</quote>.</para> 9.336 - 9.337 - &interaction.tour.log.range; 9.338 - 9.339 - <para id="x_2d">Mercurial also honours the order in which you specify 9.340 - revisions, so <command role="hg-cmd">hg log -r 2:4</command> 9.341 - prints 2, 3, and 4. while <command role="hg-cmd">hg log -r 9.342 - 4:2</command> prints 4, 3, and 2.</para> 9.343 - 9.344 - </sect2> 9.345 - <sect2> 9.346 - <title>More detailed information</title> 9.347 - 9.348 - <para id="x_2e">While the summary information printed by <command 9.349 - role="hg-cmd">hg log</command> is useful if you already know 9.350 - what you're looking for, you may need to see a complete 9.351 - description of the change, or a list of the files changed, if 9.352 - you're trying to decide whether a changeset is the one you're 9.353 - looking for. The <command role="hg-cmd">hg log</command> 9.354 - command's <option role="hg-opt-global">-v</option> (or <option 9.355 - role="hg-opt-global">--verbose</option>) option gives you 9.356 - this extra detail.</para> 9.357 - 9.358 - &interaction.tour.log-v; 9.359 - 9.360 - <para id="x_2f">If you want to see both the description and 9.361 - content of a change, add the <option 9.362 - role="hg-opt-log">-p</option> (or <option 9.363 - role="hg-opt-log">--patch</option>) option. This displays 9.364 - the content of a change as a <emphasis>unified diff</emphasis> 9.365 - (if you've never seen a unified diff before, see <xref 9.366 - linkend="sec:mq:patch"/> for an overview).</para> 9.367 - 9.368 - &interaction.tour.log-vp; 9.369 - 9.370 - <para id="x_67e">The <option role="hg-opt-log">-p</option> option is 9.371 - tremendously useful, so it's well worth remembering.</para> 9.372 - 9.373 - </sect2> 9.374 - </sect1> 9.375 - 9.376 - <sect1> 9.377 - <title>All about command options</title> 9.378 - 9.379 - <para id="x_30">Let's take a brief break from exploring Mercurial commands 9.380 - to discuss a pattern in the way that they work; you may find 9.381 - this useful to keep in mind as we continue our tour.</para> 9.382 - 9.383 - <para id="x_31">Mercurial has a consistent and straightforward approach to 9.384 - dealing with the options that you can pass to commands. It 9.385 - follows the conventions for options that are common to modern 9.386 - Linux and Unix systems.</para> 9.387 - 9.388 - <itemizedlist> 9.389 - <listitem> 9.390 - <para id="x_32">Every option has a long name. For example, as 9.391 - we've already seen, the <command role="hg-cmd">hg 9.392 - log</command> command accepts a <option 9.393 - role="hg-opt-log">--rev</option> option.</para> 9.394 - </listitem> 9.395 - <listitem> 9.396 - <para id="x_33">Most options have short names, too. Instead 9.397 - of <option role="hg-opt-log">--rev</option>, we can use 9.398 - <option role="hg-opt-log">-r</option>. (The reason that 9.399 - some options don't have short names is that the options in 9.400 - question are rarely used.)</para> 9.401 - </listitem> 9.402 - <listitem> 9.403 - <para id="x_34">Long options start with two dashes (e.g. 9.404 - <option role="hg-opt-log">--rev</option>), while short 9.405 - options start with one (e.g. <option 9.406 - role="hg-opt-log">-r</option>).</para> 9.407 - </listitem> 9.408 - <listitem> 9.409 - <para id="x_35">Option naming and usage is consistent across 9.410 - commands. For example, every command that lets you specify 9.411 - a changeset ID or revision number accepts both <option 9.412 - role="hg-opt-log">-r</option> and <option 9.413 - role="hg-opt-log">--rev</option> arguments.</para> 9.414 - </listitem> 9.415 - <listitem> 9.416 - <para id="x_67f">If you are using short options, you can save typing by 9.417 - running them together. For example, the command <command 9.418 - role="hg-cmd">hg log -v -p -r 2</command> can be written 9.419 - as <command role="hg-cmd">hg log -vpr2</command>.</para> 9.420 - </listitem> 9.421 - </itemizedlist> 9.422 - 9.423 - <para id="x_36">In the examples throughout this book, I use short options 9.424 - instead of long. This just reflects my own preference, so don't 9.425 - read anything significant into it.</para> 9.426 - 9.427 - <para id="x_37">Most commands that print output of some kind will print more 9.428 - output when passed a <option role="hg-opt-global">-v</option> 9.429 - (or <option role="hg-opt-global">--verbose</option>) option, and 9.430 - less when passed <option role="hg-opt-global">-q</option> (or 9.431 - <option role="hg-opt-global">--quiet</option>).</para> 9.432 - 9.433 - <note> 9.434 - <title>Option naming consistency</title> 9.435 - 9.436 - <para id="x_680">Almost always, Mercurial commands use consistent option 9.437 - names to refer to the same concepts. For instance, if a 9.438 - command deals with changesets, you'll always identify them 9.439 - with <option role="hg-opt-log">--rev</option> or <option 9.440 - role="hg-opt-log">-r</option>. This consistent use of 9.441 - option names makes it easier to remember what options a 9.442 - particular command takes.</para> 9.443 - </note> 9.444 - 9.445 - </sect1> 9.446 - <sect1> 9.447 - <title>Making and reviewing changes</title> 9.448 - 9.449 - <para id="x_38">Now that we have a grasp of viewing history in Mercurial, 9.450 - let's take a look at making some changes and examining 9.451 - them.</para> 9.452 - 9.453 - <para id="x_39">The first thing we'll do is isolate our experiment in a 9.454 - repository of its own. We use the <command role="hg-cmd">hg 9.455 - clone</command> command, but we don't need to clone a copy of 9.456 - the remote repository. Since we already have a copy of it 9.457 - locally, we can just clone that instead. This is much faster 9.458 - than cloning over the network, and cloning a local repository 9.459 - uses less disk space in most cases, too<footnote> 9.460 - <para id="x_681">The saving of space arises when source and destination 9.461 - repositories are on the same filesystem, in which case 9.462 - Mercurial will use hardlinks to do copy-on-write sharing of 9.463 - its internal metadata. If that explanation meant nothing to 9.464 - you, don't worry: everything happens transparently and 9.465 - automatically, and you don't need to understand it.</para> 9.466 - </footnote>.</para> 9.467 - 9.468 - &interaction.tour.reclone; 9.469 - 9.470 - <para id="x_3a">As an aside, it's often good practice to keep a 9.471 - <quote>pristine</quote> copy of a remote repository around, 9.472 - which you can then make temporary clones of to create sandboxes 9.473 - for each task you want to work on. This lets you work on 9.474 - multiple tasks in parallel, each isolated from the others until 9.475 - it's complete and you're ready to integrate it back. Because 9.476 - local clones are so cheap, there's almost no overhead to cloning 9.477 - and destroying repositories whenever you want.</para> 9.478 - 9.479 - <para id="x_3b">In our <filename class="directory">my-hello</filename> 9.480 - repository, we have a file <filename>hello.c</filename> that 9.481 - contains the classic <quote>hello, world</quote> program.</para> 9.482 - 9.483 - &interaction.tour.cat1; 9.484 - 9.485 - <para id="x_682">Let's edit this file so that it prints a second line of 9.486 - output.</para> 9.487 - 9.488 - &interaction.tour.cat2; 9.489 - 9.490 - <para id="x_3c">Mercurial's <command role="hg-cmd">hg status</command> 9.491 - command will tell us what Mercurial knows about the files in the 9.492 - repository.</para> 9.493 - 9.494 - &interaction.tour.status; 9.495 - 9.496 - <para id="x_3d">The <command role="hg-cmd">hg status</command> command 9.497 - prints no output for some files, but a line starting with 9.498 - <quote><literal>M</literal></quote> for 9.499 - <filename>hello.c</filename>. Unless you tell it to, <command 9.500 - role="hg-cmd">hg status</command> will not print any output 9.501 - for files that have not been modified.</para> 9.502 - 9.503 - <para id="x_3e">The <quote><literal>M</literal></quote> indicates that 9.504 - Mercurial has noticed that we modified 9.505 - <filename>hello.c</filename>. We didn't need to 9.506 - <emphasis>inform</emphasis> Mercurial that we were going to 9.507 - modify the file before we started, or that we had modified the 9.508 - file after we were done; it was able to figure this out 9.509 - itself.</para> 9.510 - 9.511 - <para id="x_3f">It's somewhat helpful to know that we've modified 9.512 - <filename>hello.c</filename>, but we might prefer to know 9.513 - exactly <emphasis>what</emphasis> changes we've made to it. To 9.514 - do this, we use the <command role="hg-cmd">hg diff</command> 9.515 - command.</para> 9.516 - 9.517 - &interaction.tour.diff; 9.518 - 9.519 - <tip> 9.520 - <title>Understanding patches</title> 9.521 - 9.522 - <para id="x_683">Remember to take a look at <xref 9.523 - linkend="sec:mq:patch"/> if you don't know how to read 9.524 - output above.</para> 9.525 - </tip> 9.526 - </sect1> 9.527 - <sect1> 9.528 - <title>Recording changes in a new changeset</title> 9.529 - 9.530 - <para id="x_40">We can modify files, build and test our changes, and use 9.531 - <command role="hg-cmd">hg status</command> and <command 9.532 - role="hg-cmd">hg diff</command> to review our changes, until 9.533 - we're satisfied with what we've done and arrive at a natural 9.534 - stopping point where we want to record our work in a new 9.535 - changeset.</para> 9.536 - 9.537 - <para id="x_41">The <command role="hg-cmd">hg commit</command> command lets 9.538 - us create a new changeset; we'll usually refer to this as 9.539 - <quote>making a commit</quote> or 9.540 - <quote>committing</quote>.</para> 9.541 - 9.542 - <sect2> 9.543 - <title>Setting up a username</title> 9.544 - 9.545 - <para id="x_42">When you try to run <command role="hg-cmd">hg 9.546 - commit</command> for the first time, it is not guaranteed to 9.547 - succeed. Mercurial records your name and address with each 9.548 - change that you commit, so that you and others will later be 9.549 - able to tell who made each change. Mercurial tries to 9.550 - automatically figure out a sensible username to commit the 9.551 - change with. It will attempt each of the following methods, 9.552 - in order:</para> 9.553 - <orderedlist> 9.554 - <listitem><para id="x_43">If you specify a <option 9.555 - role="hg-opt-commit">-u</option> option to the <command 9.556 - role="hg-cmd">hg commit</command> command on the command 9.557 - line, followed by a username, this is always given the 9.558 - highest precedence.</para></listitem> 9.559 - <listitem><para id="x_44">If you have set the <envar>HGUSER</envar> 9.560 - environment variable, this is checked 9.561 - next.</para></listitem> 9.562 - <listitem><para id="x_45">If you create a file in your home 9.563 - directory called <filename 9.564 - role="special">.hgrc</filename>, with a <envar 9.565 - role="rc-item-ui">username</envar> entry, that will be 9.566 - used next. To see what the contents of this file should 9.567 - look like, refer to <xref 9.568 - linkend="sec:tour-basic:username"/> 9.569 - below.</para></listitem> 9.570 - <listitem><para id="x_46">If you have set the <envar>EMAIL</envar> 9.571 - environment variable, this will be used 9.572 - next.</para></listitem> 9.573 - <listitem><para id="x_47">Mercurial will query your system to find out 9.574 - your local user name and host name, and construct a 9.575 - username from these components. Since this often results 9.576 - in a username that is not very useful, it will print a 9.577 - warning if it has to do 9.578 - this.</para></listitem> 9.579 - </orderedlist> 9.580 - <para id="x_48">If all of these mechanisms fail, Mercurial will 9.581 - fail, printing an error message. In this case, it will not 9.582 - let you commit until you set up a 9.583 - username.</para> 9.584 - <para id="x_49">You should think of the <envar>HGUSER</envar> environment 9.585 - variable and the <option role="hg-opt-commit">-u</option> 9.586 - option to the <command role="hg-cmd">hg commit</command> 9.587 - command as ways to <emphasis>override</emphasis> Mercurial's 9.588 - default selection of username. For normal use, the simplest 9.589 - and most robust way to set a username for yourself is by 9.590 - creating a <filename role="special">.hgrc</filename> file; see 9.591 - below for details.</para> 9.592 - <sect3 id="sec:tour-basic:username"> 9.593 - <title>Creating a Mercurial configuration file</title> 9.594 - 9.595 - <para id="x_4a">To set a user name, use your favorite editor 9.596 - to create a file called <filename 9.597 - role="special">.hgrc</filename> in your home directory. 9.598 - Mercurial will use this file to look up your personalised 9.599 - configuration settings. The initial contents of your 9.600 - <filename role="special">.hgrc</filename> should look like 9.601 - this.</para> 9.602 - 9.603 - <remark>Figure out what the appropriate directory is on 9.604 - Windows.</remark> 9.605 - 9.606 - <programlisting># This is a Mercurial configuration file. 9.607 -[ui] 9.608 -username = Firstname Lastname <email.address@domain.net></programlisting> 9.609 - 9.610 - <para id="x_4b">The <quote><literal>[ui]</literal></quote> line begins a 9.611 - <emphasis>section</emphasis> of the config file, so you can 9.612 - read the <quote><literal>username = ...</literal></quote> 9.613 - line as meaning <quote>set the value of the 9.614 - <literal>username</literal> item in the 9.615 - <literal>ui</literal> section</quote>. A section continues 9.616 - until a new section begins, or the end of the file. 9.617 - Mercurial ignores empty lines and treats any text from 9.618 - <quote><literal>#</literal></quote> to the end of a line as 9.619 - a comment.</para> 9.620 - </sect3> 9.621 - 9.622 - <sect3> 9.623 - <title>Choosing a user name</title> 9.624 - 9.625 - <para id="x_4c">You can use any text you like as the value of 9.626 - the <literal>username</literal> config item, since this 9.627 - information is for reading by other people, but will not be 9.628 - interpreted by Mercurial. The convention that most 9.629 - people follow is to use their name and email address, as 9.630 - in the example above.</para> 9.631 - <note> 9.632 - <para id="x_4d">Mercurial's built-in web server obfuscates 9.633 - email addresses, to make it more difficult for the email 9.634 - harvesting tools that spammers use. This reduces the 9.635 - likelihood that you'll start receiving more junk email 9.636 - if you publish a Mercurial repository on the 9.637 - web.</para></note> 9.638 - 9.639 - </sect3> 9.640 - </sect2> 9.641 - <sect2> 9.642 - <title>Writing a commit message</title> 9.643 - 9.644 - <para id="x_4e">When we commit a change, Mercurial drops us into 9.645 - a text editor, to enter a message that will describe the 9.646 - modifications we've made in this changeset. This is called 9.647 - the <emphasis>commit message</emphasis>. It will be a 9.648 - record for readers of what we did and why, and it will be 9.649 - printed by <command role="hg-cmd">hg log</command> after 9.650 - we've finished committing.</para> 9.651 - 9.652 - &interaction.tour.commit; 9.653 - 9.654 - <para id="x_4f">The editor that the <command role="hg-cmd">hg 9.655 - commit</command> command drops us into will contain an 9.656 - empty line or two, followed by a number of lines starting with 9.657 - <quote><literal>HG:</literal></quote>.</para> 9.658 - 9.659 - <programlisting> 9.660 -This is where I type my commit comment. 9.661 - 9.662 -HG: Enter commit message. Lines beginning with 'HG:' are removed. 9.663 -HG: -- 9.664 -HG: user: Bryan O'Sullivan <bos@serpentine.com> 9.665 -HG: branch 'default' 9.666 -HG: changed hello.c</programlisting> 9.667 - 9.668 - <para id="x_50">Mercurial ignores the lines that start with 9.669 - <quote><literal>HG:</literal></quote>; it uses them only to 9.670 - tell us which files it's recording changes to. Modifying or 9.671 - deleting these lines has no effect.</para> 9.672 - </sect2> 9.673 - <sect2> 9.674 - <title>Writing a good commit message</title> 9.675 - 9.676 - <para id="x_51">Since <command role="hg-cmd">hg log</command> 9.677 - only prints the first line of a commit message by default, 9.678 - it's best to write a commit message whose first line stands 9.679 - alone. Here's a real example of a commit message that 9.680 - <emphasis>doesn't</emphasis> follow this guideline, and 9.681 - hence has a summary that is not 9.682 - readable.</para> 9.683 - 9.684 - <programlisting> 9.685 -changeset: 73:584af0e231be 9.686 -user: Censored Person <censored.person@example.org> 9.687 -date: Tue Sep 26 21:37:07 2006 -0700 9.688 -summary: include buildmeister/commondefs. Add exports.</programlisting> 9.689 - 9.690 - <para id="x_52">As far as the remainder of the contents of the 9.691 - commit message are concerned, there are no hard-and-fast 9.692 - rules. Mercurial itself doesn't interpret or care about the 9.693 - contents of the commit message, though your project may have 9.694 - policies that dictate a certain kind of 9.695 - formatting.</para> 9.696 - <para id="x_53">My personal preference is for short, but 9.697 - informative, commit messages that tell me something that I 9.698 - can't figure out with a quick glance at the output of 9.699 - <command role="hg-cmd">hg log 9.700 - --patch</command>.</para> 9.701 - </sect2> 9.702 - <sect2> 9.703 - <title>Aborting a commit</title> 9.704 - 9.705 - <para id="x_54">If you decide that you don't want to commit 9.706 - while in the middle of editing a commit message, simply exit 9.707 - from your editor without saving the file that it's editing. 9.708 - This will cause nothing to happen to either the repository 9.709 - or the working directory.</para> 9.710 - <para id="x_55">If we run the <command role="hg-cmd">hg 9.711 - commit</command> command without any arguments, it records 9.712 - all of the changes we've made, as reported by <command 9.713 - role="hg-cmd">hg status</command> and <command 9.714 - role="hg-cmd">hg diff</command>.</para> 9.715 - </sect2> 9.716 - <sect2> 9.717 - <title>Admiring our new handiwork</title> 9.718 - 9.719 - <para id="x_56">Once we've finished the commit, we can use the 9.720 - <command role="hg-cmd">hg tip</command> command to display 9.721 - the changeset we just created. This command produces output 9.722 - that is identical to <command role="hg-cmd">hg 9.723 - log</command>, but it only displays the newest revision in 9.724 - the repository.</para> 9.725 - 9.726 - &interaction.tour.tip; 9.727 - 9.728 - <para id="x_57">We refer to the newest revision in the 9.729 - repository as the <emphasis>tip revision</emphasis>, or simply 9.730 - the <emphasis>tip</emphasis>.</para> 9.731 - 9.732 - <para id="x_684">By the way, the <command role="hg-cmd">hg tip</command> 9.733 - command accepts many of the same options as <command 9.734 - role="hg-cmd">hg log</command>, so <option 9.735 - role="hg-opt-global">-v</option> above indicates <quote>be 9.736 - verbose</quote>, <option role="hg-opt-tip">-p</option> 9.737 - specifies <quote>print a patch</quote>. The use of <option 9.738 - role="hg-opt-tip">-p</option> to print patches is another 9.739 - example of the consistent naming we mentioned earlier.</para> 9.740 - </sect2> 9.741 - </sect1> 9.742 - 9.743 - <sect1> 9.744 - <title>Sharing changes</title> 9.745 - 9.746 - <para id="x_58">We mentioned earlier that repositories in 9.747 - Mercurial are self-contained. This means that the changeset 9.748 - we just created exists only in our <filename 9.749 - class="directory">my-hello</filename> repository. Let's 9.750 - look at a few ways that we can propagate this change into 9.751 - other repositories.</para> 9.752 - 9.753 - <sect2 id="sec:tour:pull"> 9.754 - <title>Pulling changes from another repository</title> 9.755 - <para id="x_59">To get started, let's clone our original 9.756 - <filename class="directory">hello</filename> repository, 9.757 - which does not contain the change we just committed. We'll 9.758 - call our temporary repository <filename 9.759 - class="directory">hello-pull</filename>.</para> 9.760 - 9.761 - &interaction.tour.clone-pull; 9.762 - 9.763 - <para id="x_5a">We'll use the <command role="hg-cmd">hg 9.764 - pull</command> command to bring changes from <filename 9.765 - class="directory">my-hello</filename> into <filename 9.766 - class="directory">hello-pull</filename>. However, blindly 9.767 - pulling unknown changes into a repository is a somewhat 9.768 - scary prospect. Mercurial provides the <command 9.769 - role="hg-cmd">hg incoming</command> command to tell us 9.770 - what changes the <command role="hg-cmd">hg pull</command> 9.771 - command <emphasis>would</emphasis> pull into the repository, 9.772 - without actually pulling the changes in.</para> 9.773 - 9.774 - &interaction.tour.incoming; 9.775 - 9.776 - <para id="x_5b">Suppose you're pulling changes from a repository 9.777 - on the network somewhere. While you are looking at the <command 9.778 - role="hg-cmd">hg incoming</command> output, and before you 9.779 - pull those changes, someone might have committed something in 9.780 - the remote repository. This means that it's possible to pull 9.781 - more changes than you saw when using <command 9.782 - role="hg-cmd">hg incoming</command>.</para> 9.783 - 9.784 - <para id="x_5c">Bringing changes into a repository is a simple 9.785 - matter of running the <command role="hg-cmd">hg 9.786 - pull</command> command, and telling it which repository to 9.787 - pull from.</para> 9.788 - 9.789 - &interaction.tour.pull; 9.790 - 9.791 - <para id="x_5d">As you can see 9.792 - from the before-and-after output of <command 9.793 - role="hg-cmd">hg tip</command>, we have successfully 9.794 - pulled changes into our repository. There remains one step 9.795 - before we can see these changes in the working 9.796 - directory.</para> 9.797 - </sect2> 9.798 - <sect2> 9.799 - <title>Updating the working directory</title> 9.800 - 9.801 - <para id="x_5e">We have so far glossed over the relationship 9.802 - between a repository and its working directory. The <command 9.803 - role="hg-cmd">hg pull</command> command that we ran in 9.804 - <xref linkend="sec:tour:pull"/> brought changes into the 9.805 - repository, but if we check, there's no sign of those changes 9.806 - in the working directory. This is because <command 9.807 - role="hg-cmd">hg pull</command> does not (by default) touch 9.808 - the working directory. Instead, we use the <command 9.809 - role="hg-cmd">hg update</command> command to do this.</para> 9.810 - 9.811 - &interaction.tour.update; 9.812 - 9.813 - <para id="x_5f">It might seem a bit strange that <command role="hg-cmd">hg 9.814 - pull</command> doesn't update the working directory 9.815 - automatically. There's actually a good reason for this: you 9.816 - can use <command role="hg-cmd">hg update</command> to update 9.817 - the working directory to the state it was in at <emphasis>any 9.818 - revision</emphasis> in the history of the repository. If 9.819 - you had the working directory updated to an old revision&emdash;to 9.820 - hunt down the origin of a bug, say&emdash;and ran a <command 9.821 - role="hg-cmd">hg pull</command> which automatically updated 9.822 - the working directory to a new revision, you might not be 9.823 - terribly happy.</para> 9.824 - <para id="x_60">However, since pull-then-update is such a common thing to 9.825 - do, Mercurial lets you combine the two by passing the <option 9.826 - role="hg-opt-pull">-u</option> option to <command 9.827 - role="hg-cmd">hg pull</command>.</para> 9.828 - 9.829 - <para id="x_61">If you look back at the output of <command 9.830 - role="hg-cmd">hg pull</command> in <xref 9.831 - linkend="sec:tour:pull"/> when we ran it without <option 9.832 - role="hg-opt-pull">-u</option>, you can see that it printed 9.833 - a helpful reminder that we'd have to take an explicit step to 9.834 - update the working directory:</para> 9.835 - 9.836 - <!-- &interaction.xxx.fixme; --> 9.837 - 9.838 - <para id="x_62">To find out what revision the working directory is at, use 9.839 - the <command role="hg-cmd">hg parents</command> 9.840 - command.</para> 9.841 - 9.842 - &interaction.tour.parents; 9.843 - 9.844 - <para id="x_63">If you look back at <xref 9.845 - linkend="fig:tour-basic:history"/>, 9.846 - you'll see arrows connecting each changeset. The node that 9.847 - the arrow leads <emphasis>from</emphasis> in each case is a 9.848 - parent, and the node that the arrow leads 9.849 - <emphasis>to</emphasis> is its child. The working directory 9.850 - has a parent in just the same way; this is the changeset that 9.851 - the working directory currently contains.</para> 9.852 - 9.853 - <para id="x_64">To update the working directory to a particular revision, 9.854 - 9.855 - give a revision number or changeset ID to the <command 9.856 - role="hg-cmd">hg update</command> command.</para> 9.857 - 9.858 - &interaction.tour.older; 9.859 - 9.860 - <para id="x_65">If you omit an explicit revision, <command 9.861 - role="hg-cmd">hg update</command> will update to the tip 9.862 - revision, as shown by the second call to <command 9.863 - role="hg-cmd">hg update</command> in the example 9.864 - above.</para> 9.865 - </sect2> 9.866 - 9.867 - <sect2> 9.868 - <title>Pushing changes to another repository</title> 9.869 - 9.870 - <para id="x_66">Mercurial lets us push changes to another 9.871 - repository, from the repository we're currently visiting. 9.872 - As with the example of <command role="hg-cmd">hg 9.873 - pull</command> above, we'll create a temporary repository 9.874 - to push our changes into.</para> 9.875 - 9.876 - &interaction.tour.clone-push; 9.877 - 9.878 - <para id="x_67">The <command role="hg-cmd">hg outgoing</command> command 9.879 - tells us what changes would be pushed into another 9.880 - repository.</para> 9.881 - 9.882 - &interaction.tour.outgoing; 9.883 - 9.884 - <para id="x_68">And the 9.885 - <command role="hg-cmd">hg push</command> command does the 9.886 - actual push.</para> 9.887 - 9.888 - &interaction.tour.push; 9.889 - 9.890 - <para id="x_69">As with <command role="hg-cmd">hg 9.891 - pull</command>, the <command role="hg-cmd">hg push</command> 9.892 - command does not update the working directory in the 9.893 - repository that it's pushing changes into. Unlike <command 9.894 - role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg 9.895 - push</command> does not provide a <literal>-u</literal> 9.896 - option that updates the other repository's working directory. 9.897 - This asymmetry is deliberate: the repository we're pushing to 9.898 - might be on a remote server and shared between several people. 9.899 - If we were to update its working directory while someone was 9.900 - working in it, their work would be disrupted.</para> 9.901 - 9.902 - <para id="x_6a">What happens if we try to pull or push changes 9.903 - and the receiving repository already has those changes? 9.904 - Nothing too exciting.</para> 9.905 - 9.906 - &interaction.tour.push.nothing; 9.907 - </sect2> 9.908 - <sect2> 9.909 - <title>Sharing changes over a network</title> 9.910 - 9.911 - <para id="x_6b">The commands we have covered in the previous few 9.912 - sections are not limited to working with local repositories. 9.913 - Each works in exactly the same fashion over a network 9.914 - connection; simply pass in a URL instead of a local 9.915 - path.</para> 9.916 - 9.917 - &interaction.tour.outgoing.net; 9.918 - 9.919 - <para id="x_6c">In this example, we 9.920 - can see what changes we could push to the remote repository, 9.921 - but the repository is understandably not set up to let 9.922 - anonymous users push to it.</para> 9.923 - 9.924 - &interaction.tour.push.net; 9.925 - </sect2> 9.926 - </sect1> 9.927 -</chapter> 9.928 - 9.929 -<!-- 9.930 -local variables: 9.931 -sgml-parent-document: ("00book.xml" "book" "chapter") 9.932 -end: 9.933 --->
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/en/ch02-tour-basic.xml Thu May 21 14:16:17 2009 +0800 10.3 @@ -0,0 +1,1035 @@ 10.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 10.5 + 10.6 +<chapter id="chap:tour-basic"> 10.7 + <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?> 10.8 + <title>A tour of Mercurial: the basics</title> 10.9 + 10.10 + <sect1 id="sec:tour:install"> 10.11 + <title>Installing Mercurial on your system</title> 10.12 + 10.13 + <para id="x_1">Prebuilt binary packages of Mercurial are available for 10.14 + every popular operating system. These make it easy to start 10.15 + using Mercurial on your computer immediately.</para> 10.16 + 10.17 + <sect2> 10.18 + <title>Windows</title> 10.19 + 10.20 + <para id="x_c">The best version of Mercurial for Windows is 10.21 + TortoiseHg, which can be found at <ulink 10.22 + url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>. 10.23 + This package has no external dependencies; it <quote>just 10.24 + works</quote>. It provides both command line and graphical 10.25 + user interfaces.</para> 10.26 + 10.27 + </sect2> 10.28 + 10.29 + <sect2> 10.30 + <title>Mac OS X</title> 10.31 + 10.32 + <para id="x_a">Lee Cantey publishes an installer of Mercurial 10.33 + for Mac OS X at <ulink 10.34 + url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para> 10.35 + </sect2> 10.36 + 10.37 + <sect2> 10.38 + <title>Linux</title> 10.39 + 10.40 + <para id="x_2">Because each Linux distribution has its own packaging 10.41 + tools, policies, and rate of development, it's difficult to 10.42 + give a comprehensive set of instructions on how to install 10.43 + Mercurial binaries. The version of Mercurial that you will 10.44 + end up with can vary depending on how active the person is who 10.45 + maintains the package for your distribution.</para> 10.46 + 10.47 + <para id="x_3">To keep things simple, I will focus on installing 10.48 + Mercurial from the command line under the most popular Linux 10.49 + distributions. Most of these distributions provide graphical 10.50 + package managers that will let you install Mercurial with a 10.51 + single click; the package name to look for is 10.52 + <literal>mercurial</literal>.</para> 10.53 + 10.54 + <itemizedlist> 10.55 + <listitem><para id="x_4">Ubuntu and Debian:</para> 10.56 + <programlisting>apt-get install mercurial</programlisting></listitem> 10.57 + <listitem><para id="x_5">Fedora:</para> 10.58 + <programlisting>yum install mercurial</programlisting></listitem> 10.59 + <listitem><para id="x_715">OpenSUSE:</para> 10.60 + <programlisting>zypper install mercurial</programlisting></listitem> 10.61 + <listitem><para id="x_6">Gentoo:</para> 10.62 + <programlisting>emerge mercurial</programlisting></listitem> 10.63 + </itemizedlist> 10.64 + 10.65 + </sect2> 10.66 + <sect2> 10.67 + <title>Solaris</title> 10.68 + 10.69 + <para id="x_9">SunFreeWare, at <ulink 10.70 + url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 10.71 + provides prebuilt packages of Mercurial.</para> 10.72 + 10.73 + </sect2> 10.74 + 10.75 + </sect1> 10.76 + 10.77 + <sect1> 10.78 + <title>Getting started</title> 10.79 + 10.80 + <para id="x_e">To begin, we'll use the <command role="hg-cmd">hg 10.81 + version</command> command to find out whether Mercurial is 10.82 + installed properly. The actual version information that it 10.83 + prints isn't so important; we simply care whether the command 10.84 + runs and prints anything at all.</para> 10.85 + 10.86 + &interaction.tour.version; 10.87 + 10.88 + <sect2> 10.89 + <title>Built-in help</title> 10.90 + 10.91 + <para id="x_f">Mercurial provides a built-in help system. This is 10.92 + invaluable for those times when you find yourself stuck 10.93 + trying to remember how to run a command. If you are 10.94 + completely stuck, simply run <command role="hg-cmd">hg 10.95 + help</command>; it will print a brief list of commands, 10.96 + along with a description of what each does. If you ask for 10.97 + help on a specific command (as below), it prints more 10.98 + detailed information.</para> 10.99 + 10.100 + &interaction.tour.help; 10.101 + 10.102 + <para id="x_10">For a more impressive level of detail (which you won't 10.103 + usually need) run <command role="hg-cmd">hg help <option 10.104 + role="hg-opt-global">-v</option></command>. The <option 10.105 + role="hg-opt-global">-v</option> option is short for 10.106 + <option role="hg-opt-global">--verbose</option>, and tells 10.107 + Mercurial to print more information than it usually 10.108 + would.</para> 10.109 + 10.110 + </sect2> 10.111 + </sect1> 10.112 + <sect1> 10.113 + <title>Working with a repository</title> 10.114 + 10.115 + <para id="x_11">In Mercurial, everything happens inside a 10.116 + <emphasis>repository</emphasis>. The repository for a project 10.117 + contains all of the files that <quote>belong to</quote> that 10.118 + project, along with a historical record of the project's 10.119 + files.</para> 10.120 + 10.121 + <para id="x_12">There's nothing particularly magical about a repository; it 10.122 + is simply a directory tree in your filesystem that Mercurial 10.123 + treats as special. You can rename or delete a repository any 10.124 + time you like, using either the command line or your file 10.125 + browser.</para> 10.126 + 10.127 + <sect2> 10.128 + <title>Making a local copy of a repository</title> 10.129 + 10.130 + <para id="x_13"><emphasis>Copying</emphasis> a repository is just a little 10.131 + bit special. While you could use a normal file copying 10.132 + command to make a copy of a repository, it's best to use a 10.133 + built-in command that Mercurial provides. This command is 10.134 + called <command role="hg-cmd">hg clone</command>, because it 10.135 + makes an identical copy of an existing repository.</para> 10.136 + 10.137 + &interaction.tour.clone; 10.138 + 10.139 + <para id="x_67c">One advantage of using <command role="hg-cmd">hg 10.140 + clone</command> is that, as we can see above, it lets us clone 10.141 + repositories over the network. Another is that it remembers 10.142 + where we cloned from, which we'll find useful soon when we 10.143 + want to fetch new changes from another repository.</para> 10.144 + 10.145 + <para id="x_14">If our clone succeeded, we should now have a local 10.146 + directory called <filename class="directory">hello</filename>. 10.147 + This directory will contain some files.</para> 10.148 + 10.149 + &interaction.tour.ls; 10.150 + 10.151 + <para id="x_15">These files have the same contents and history in our 10.152 + repository as they do in the repository we cloned.</para> 10.153 + 10.154 + <para id="x_16">Every Mercurial repository is complete, 10.155 + self-contained, and independent. It contains its own private 10.156 + copy of a project's files and history. As we just mentioned, 10.157 + a cloned repository remembers the location of the repository 10.158 + it was cloned from, but Mercurial will not communicate with 10.159 + that repository, or any other, unless you tell it to.</para> 10.160 + 10.161 + <para id="x_17">What this means for now is that we're free to experiment 10.162 + with our repository, safe in the knowledge that it's a private 10.163 + <quote>sandbox</quote> that won't affect anyone else.</para> 10.164 + 10.165 + </sect2> 10.166 + <sect2> 10.167 + <title>What's in a repository?</title> 10.168 + 10.169 + <para id="x_18">When we take a more detailed look inside a repository, we 10.170 + can see that it contains a directory named <filename 10.171 + class="directory">.hg</filename>. This is where Mercurial 10.172 + keeps all of its metadata for the repository.</para> 10.173 + 10.174 + &interaction.tour.ls-a; 10.175 + 10.176 + <para id="x_19">The contents of the <filename 10.177 + class="directory">.hg</filename> directory and its 10.178 + subdirectories are private to Mercurial. Every other file and 10.179 + directory in the repository is yours to do with as you 10.180 + please.</para> 10.181 + 10.182 + <para id="x_1a">To introduce a little terminology, the <filename 10.183 + class="directory">.hg</filename> directory is the 10.184 + <quote>real</quote> repository, and all of the files and 10.185 + directories that coexist with it are said to live in the 10.186 + <emphasis>working directory</emphasis>. An easy way to 10.187 + remember the distinction is that the 10.188 + <emphasis>repository</emphasis> contains the 10.189 + <emphasis>history</emphasis> of your project, while the 10.190 + <emphasis>working directory</emphasis> contains a 10.191 + <emphasis>snapshot</emphasis> of your project at a particular 10.192 + point in history.</para> 10.193 + 10.194 + </sect2> 10.195 + </sect1> 10.196 + <sect1> 10.197 + <title>A tour through history</title> 10.198 + 10.199 + <para id="x_1b">One of the first things we might want to do with a new, 10.200 + unfamiliar repository is understand its history. The <command 10.201 + role="hg-cmd">hg log</command> command gives us a view of 10.202 + the history of changes in the repository.</para> 10.203 + 10.204 + &interaction.tour.log; 10.205 + 10.206 + <para id="x_1c">By default, this command prints a brief paragraph of output 10.207 + for each change to the project that was recorded. In Mercurial 10.208 + terminology, we call each of these recorded events a 10.209 + <emphasis>changeset</emphasis>, because it can contain a record 10.210 + of changes to several files.</para> 10.211 + 10.212 + <para id="x_1d">The fields in a record of output from <command 10.213 + role="hg-cmd">hg log</command> are as follows.</para> 10.214 + 10.215 + <itemizedlist> 10.216 + <listitem><para id="x_1e"><literal>changeset</literal>: This 10.217 + field has the format of a number, followed by a colon, 10.218 + followed by a hexadecimal (or <emphasis>hex</emphasis>) 10.219 + string. These are <emphasis>identifiers</emphasis> for the 10.220 + changeset. The hex string is a unique identifier: the same 10.221 + hex string will always refer to the same changeset in every 10.222 + copy of this repository. The 10.223 + number is shorter and easier to type than the hex string, 10.224 + but it isn't unique: the same number in two different clones 10.225 + of a repository may identify different changesets.</para> 10.226 + </listitem> 10.227 + <listitem><para id="x_1f"><literal>user</literal>: The identity of the 10.228 + person who created the changeset. This is a free-form 10.229 + field, but it most often contains a person's name and email 10.230 + address.</para></listitem> 10.231 + <listitem><para id="x_20"><literal>date</literal>: The date and time on 10.232 + which the changeset was created, and the timezone in which 10.233 + it was created. (The date and time are local to that 10.234 + timezone; they display what time and date it was for the 10.235 + person who created the changeset.)</para></listitem> 10.236 + <listitem><para id="x_21"><literal>summary</literal>: The first line of 10.237 + the text message that the creator of the changeset entered 10.238 + to describe the changeset.</para></listitem> 10.239 + <listitem> 10.240 + <para id="x_67d">Some changesets, such as the first in the list above, 10.241 + have a <literal>tag</literal> field. A tag is another way 10.242 + to identify a changeset, by giving it an easy-to-remember 10.243 + name. (The tag named <literal>tip</literal> is special: it 10.244 + always refers to the newest change in a repository.)</para> 10.245 + </listitem> 10.246 + </itemizedlist> 10.247 + 10.248 + <para id="x_22">The default output printed by <command 10.249 + role="hg-cmd">hg log</command> is purely a summary; it is 10.250 + missing a lot of detail.</para> 10.251 + 10.252 + <para id="x_23"><xref linkend="fig:tour-basic:history"/> provides 10.253 + a graphical representation of the history of the <filename 10.254 + class="directory">hello</filename> repository, to make it a 10.255 + little easier to see which direction history is 10.256 + <quote>flowing</quote> in. We'll be returning to this figure 10.257 + several times in this chapter and the chapter that 10.258 + follows.</para> 10.259 + 10.260 + <figure id="fig:tour-basic:history"> 10.261 + <title>Graphical history of the <filename 10.262 + class="directory">hello</filename> repository</title> 10.263 + <mediaobject> 10.264 + <imageobject><imagedata fileref="figs/tour-history.png"/></imageobject> 10.265 + <textobject><phrase>XXX add text</phrase></textobject> 10.266 + </mediaobject> 10.267 + </figure> 10.268 + 10.269 + <sect2> 10.270 + <title>Changesets, revisions, and talking to other 10.271 + people</title> 10.272 + 10.273 + <para id="x_25">As English is a notoriously sloppy language, and computer 10.274 + science has a hallowed history of terminological confusion 10.275 + (why use one term when four will do?), revision control has a 10.276 + variety of words and phrases that mean the same thing. If you 10.277 + are talking about Mercurial history with other people, you 10.278 + will find that the word <quote>changeset</quote> is often 10.279 + compressed to <quote>change</quote> or (when written) 10.280 + <quote>cset</quote>, and sometimes a changeset is referred to 10.281 + as a <quote>revision</quote> or a <quote>rev</quote>.</para> 10.282 + 10.283 + <para id="x_26">While it doesn't matter what <emphasis>word</emphasis> you 10.284 + use to refer to the concept of <quote>a changeset</quote>, the 10.285 + <emphasis>identifier</emphasis> that you use to refer to 10.286 + <quote>a <emphasis>specific</emphasis> changeset</quote> is of 10.287 + great importance. Recall that the <literal>changeset</literal> 10.288 + field in the output from <command role="hg-cmd">hg 10.289 + log</command> identifies a changeset using both a number and 10.290 + a hexadecimal string.</para> 10.291 + <itemizedlist> 10.292 + <listitem><para id="x_27">The revision number is a handy 10.293 + notation that is <emphasis>only valid in that 10.294 + repository</emphasis>.</para></listitem> 10.295 + <listitem><para id="x_28">The hexadecimal string is the 10.296 + <emphasis>permanent, unchanging identifier</emphasis> that 10.297 + will always identify that exact changeset in 10.298 + <emphasis>every</emphasis> copy of the 10.299 + repository.</para></listitem></itemizedlist> 10.300 + 10.301 + <para id="x_29">This distinction is important. If you send 10.302 + someone an email talking about <quote>revision 33</quote>, 10.303 + there's a high likelihood that their revision 33 will 10.304 + <emphasis>not be the same</emphasis> as yours. The reason for 10.305 + this is that a revision number depends on the order in which 10.306 + changes arrived in a repository, and there is no guarantee 10.307 + that the same changes will happen in the same order in 10.308 + different repositories. Three changes <literal>a,b,c</literal> 10.309 + can easily appear in one repository as 10.310 + <literal>0,1,2</literal>, while in another as 10.311 + <literal>0,2,1</literal>.</para> 10.312 + 10.313 + <para id="x_2a">Mercurial uses revision numbers purely as a convenient 10.314 + shorthand. If you need to discuss a changeset with someone, 10.315 + or make a record of a changeset for some other reason (for 10.316 + example, in a bug report), use the hexadecimal 10.317 + identifier.</para> 10.318 + 10.319 + </sect2> 10.320 + <sect2> 10.321 + <title>Viewing specific revisions</title> 10.322 + 10.323 + <para id="x_2b">To narrow the output of <command role="hg-cmd">hg 10.324 + log</command> down to a single revision, use the <option 10.325 + role="hg-opt-log">-r</option> (or <option 10.326 + role="hg-opt-log">--rev</option>) option. You can use 10.327 + either a revision number or a hexadecimal identifier, 10.328 + and you can provide as many revisions as you want.</para> 10.329 + 10.330 + &interaction.tour.log-r; 10.331 + 10.332 + <para id="x_2c">If you want to see the history of several revisions 10.333 + without having to list each one, you can use <emphasis>range 10.334 + notation</emphasis>; this lets you express the idea <quote>I 10.335 + want all revisions between <literal>abc</literal> and 10.336 + <literal>def</literal>, inclusive</quote>.</para> 10.337 + 10.338 + &interaction.tour.log.range; 10.339 + 10.340 + <para id="x_2d">Mercurial also honours the order in which you specify 10.341 + revisions, so <command role="hg-cmd">hg log -r 2:4</command> 10.342 + prints 2, 3, and 4. while <command role="hg-cmd">hg log -r 10.343 + 4:2</command> prints 4, 3, and 2.</para> 10.344 + 10.345 + </sect2> 10.346 + <sect2> 10.347 + <title>More detailed information</title> 10.348 + 10.349 + <para id="x_2e">While the summary information printed by <command 10.350 + role="hg-cmd">hg log</command> is useful if you already know 10.351 + what you're looking for, you may need to see a complete 10.352 + description of the change, or a list of the files changed, if 10.353 + you're trying to decide whether a changeset is the one you're 10.354 + looking for. The <command role="hg-cmd">hg log</command> 10.355 + command's <option role="hg-opt-global">-v</option> (or <option 10.356 + role="hg-opt-global">--verbose</option>) option gives you 10.357 + this extra detail.</para> 10.358 + 10.359 + &interaction.tour.log-v; 10.360 + 10.361 + <para id="x_2f">If you want to see both the description and 10.362 + content of a change, add the <option 10.363 + role="hg-opt-log">-p</option> (or <option 10.364 + role="hg-opt-log">--patch</option>) option. This displays 10.365 + the content of a change as a <emphasis>unified diff</emphasis> 10.366 + (if you've never seen a unified diff before, see <xref 10.367 + linkend="sec:mq:patch"/> for an overview).</para> 10.368 + 10.369 + &interaction.tour.log-vp; 10.370 + 10.371 + <para id="x_67e">The <option role="hg-opt-log">-p</option> option is 10.372 + tremendously useful, so it's well worth remembering.</para> 10.373 + 10.374 + </sect2> 10.375 + </sect1> 10.376 + 10.377 + <sect1> 10.378 + <title>All about command options</title> 10.379 + 10.380 + <para id="x_30">Let's take a brief break from exploring Mercurial commands 10.381 + to discuss a pattern in the way that they work; you may find 10.382 + this useful to keep in mind as we continue our tour.</para> 10.383 + 10.384 + <para id="x_31">Mercurial has a consistent and straightforward approach to 10.385 + dealing with the options that you can pass to commands. It 10.386 + follows the conventions for options that are common to modern 10.387 + Linux and Unix systems.</para> 10.388 + 10.389 + <itemizedlist> 10.390 + <listitem> 10.391 + <para id="x_32">Every option has a long name. For example, as 10.392 + we've already seen, the <command role="hg-cmd">hg 10.393 + log</command> command accepts a <option 10.394 + role="hg-opt-log">--rev</option> option.</para> 10.395 + </listitem> 10.396 + <listitem> 10.397 + <para id="x_33">Most options have short names, too. Instead 10.398 + of <option role="hg-opt-log">--rev</option>, we can use 10.399 + <option role="hg-opt-log">-r</option>. (The reason that 10.400 + some options don't have short names is that the options in 10.401 + question are rarely used.)</para> 10.402 + </listitem> 10.403 + <listitem> 10.404 + <para id="x_34">Long options start with two dashes (e.g. 10.405 + <option role="hg-opt-log">--rev</option>), while short 10.406 + options start with one (e.g. <option 10.407 + role="hg-opt-log">-r</option>).</para> 10.408 + </listitem> 10.409 + <listitem> 10.410 + <para id="x_35">Option naming and usage is consistent across 10.411 + commands. For example, every command that lets you specify 10.412 + a changeset ID or revision number accepts both <option 10.413 + role="hg-opt-log">-r</option> and <option 10.414 + role="hg-opt-log">--rev</option> arguments.</para> 10.415 + </listitem> 10.416 + <listitem> 10.417 + <para id="x_67f">If you are using short options, you can save typing by 10.418 + running them together. For example, the command <command 10.419 + role="hg-cmd">hg log -v -p -r 2</command> can be written 10.420 + as <command role="hg-cmd">hg log -vpr2</command>.</para> 10.421 + </listitem> 10.422 + </itemizedlist> 10.423 + 10.424 + <para id="x_36">In the examples throughout this book, I usually 10.425 + use short options instead of long. This simply reflects my own 10.426 + preference, so don't read anything significant into it.</para> 10.427 + 10.428 + <para id="x_37">Most commands that print output of some kind will print more 10.429 + output when passed a <option role="hg-opt-global">-v</option> 10.430 + (or <option role="hg-opt-global">--verbose</option>) option, and 10.431 + less when passed <option role="hg-opt-global">-q</option> (or 10.432 + <option role="hg-opt-global">--quiet</option>).</para> 10.433 + 10.434 + <note> 10.435 + <title>Option naming consistency</title> 10.436 + 10.437 + <para id="x_680">Almost always, Mercurial commands use consistent option 10.438 + names to refer to the same concepts. For instance, if a 10.439 + command deals with changesets, you'll always identify them 10.440 + with <option role="hg-opt-log">--rev</option> or <option 10.441 + role="hg-opt-log">-r</option>. This consistent use of 10.442 + option names makes it easier to remember what options a 10.443 + particular command takes.</para> 10.444 + </note> 10.445 + 10.446 + </sect1> 10.447 + <sect1> 10.448 + <title>Making and reviewing changes</title> 10.449 + 10.450 + <para id="x_38">Now that we have a grasp of viewing history in Mercurial, 10.451 + let's take a look at making some changes and examining 10.452 + them.</para> 10.453 + 10.454 + <para id="x_39">The first thing we'll do is isolate our experiment in a 10.455 + repository of its own. We use the <command role="hg-cmd">hg 10.456 + clone</command> command, but we don't need to clone a copy of 10.457 + the remote repository. Since we already have a copy of it 10.458 + locally, we can just clone that instead. This is much faster 10.459 + than cloning over the network, and cloning a local repository 10.460 + uses less disk space in most cases, too<footnote> 10.461 + <para id="x_681">The saving of space arises when source and destination 10.462 + repositories are on the same filesystem, in which case 10.463 + Mercurial will use hardlinks to do copy-on-write sharing of 10.464 + its internal metadata. If that explanation meant nothing to 10.465 + you, don't worry: everything happens transparently and 10.466 + automatically, and you don't need to understand it.</para> 10.467 + </footnote>.</para> 10.468 + 10.469 + &interaction.tour.reclone; 10.470 + 10.471 + <para id="x_3a">As an aside, it's often good practice to keep a 10.472 + <quote>pristine</quote> copy of a remote repository around, 10.473 + which you can then make temporary clones of to create sandboxes 10.474 + for each task you want to work on. This lets you work on 10.475 + multiple tasks in parallel, each isolated from the others until 10.476 + it's complete and you're ready to integrate it back. Because 10.477 + local clones are so cheap, there's almost no overhead to cloning 10.478 + and destroying repositories whenever you want.</para> 10.479 + 10.480 + <para id="x_3b">In our <filename class="directory">my-hello</filename> 10.481 + repository, we have a file <filename>hello.c</filename> that 10.482 + contains the classic <quote>hello, world</quote> program.</para> 10.483 + 10.484 + &interaction.tour.cat1; 10.485 + 10.486 + <para id="x_682">Let's edit this file so that it prints a second line of 10.487 + output.</para> 10.488 + 10.489 + &interaction.tour.cat2; 10.490 + 10.491 + <para id="x_3c">Mercurial's <command role="hg-cmd">hg status</command> 10.492 + command will tell us what Mercurial knows about the files in the 10.493 + repository.</para> 10.494 + 10.495 + &interaction.tour.status; 10.496 + 10.497 + <para id="x_3d">The <command role="hg-cmd">hg status</command> command 10.498 + prints no output for some files, but a line starting with 10.499 + <quote><literal>M</literal></quote> for 10.500 + <filename>hello.c</filename>. Unless you tell it to, <command 10.501 + role="hg-cmd">hg status</command> will not print any output 10.502 + for files that have not been modified.</para> 10.503 + 10.504 + <para id="x_3e">The <quote><literal>M</literal></quote> indicates that 10.505 + Mercurial has noticed that we modified 10.506 + <filename>hello.c</filename>. We didn't need to 10.507 + <emphasis>inform</emphasis> Mercurial that we were going to 10.508 + modify the file before we started, or that we had modified the 10.509 + file after we were done; it was able to figure this out 10.510 + itself.</para> 10.511 + 10.512 + <para id="x_3f">It's somewhat helpful to know that we've modified 10.513 + <filename>hello.c</filename>, but we might prefer to know 10.514 + exactly <emphasis>what</emphasis> changes we've made to it. To 10.515 + do this, we use the <command role="hg-cmd">hg diff</command> 10.516 + command.</para> 10.517 + 10.518 + &interaction.tour.diff; 10.519 + 10.520 + <tip> 10.521 + <title>Understanding patches</title> 10.522 + 10.523 + <para id="x_683">Remember to take a look at <xref 10.524 + linkend="sec:mq:patch"/> if you don't know how to read 10.525 + output above.</para> 10.526 + </tip> 10.527 + </sect1> 10.528 + <sect1> 10.529 + <title>Recording changes in a new changeset</title> 10.530 + 10.531 + <para id="x_40">We can modify files, build and test our changes, and use 10.532 + <command role="hg-cmd">hg status</command> and <command 10.533 + role="hg-cmd">hg diff</command> to review our changes, until 10.534 + we're satisfied with what we've done and arrive at a natural 10.535 + stopping point where we want to record our work in a new 10.536 + changeset.</para> 10.537 + 10.538 + <para id="x_41">The <command role="hg-cmd">hg commit</command> command lets 10.539 + us create a new changeset; we'll usually refer to this as 10.540 + <quote>making a commit</quote> or 10.541 + <quote>committing</quote>.</para> 10.542 + 10.543 + <sect2> 10.544 + <title>Setting up a username</title> 10.545 + 10.546 + <para id="x_42">When you try to run <command role="hg-cmd">hg 10.547 + commit</command> for the first time, it is not guaranteed to 10.548 + succeed. Mercurial records your name and address with each 10.549 + change that you commit, so that you and others will later be 10.550 + able to tell who made each change. Mercurial tries to 10.551 + automatically figure out a sensible username to commit the 10.552 + change with. It will attempt each of the following methods, 10.553 + in order:</para> 10.554 + <orderedlist> 10.555 + <listitem><para id="x_43">If you specify a <option 10.556 + role="hg-opt-commit">-u</option> option to the <command 10.557 + role="hg-cmd">hg commit</command> command on the command 10.558 + line, followed by a username, this is always given the 10.559 + highest precedence.</para></listitem> 10.560 + <listitem><para id="x_44">If you have set the <envar>HGUSER</envar> 10.561 + environment variable, this is checked 10.562 + next.</para></listitem> 10.563 + <listitem><para id="x_45">If you create a file in your home 10.564 + directory called <filename 10.565 + role="special">.hgrc</filename>, with a <envar 10.566 + role="rc-item-ui">username</envar> entry, that will be 10.567 + used next. To see what the contents of this file should 10.568 + look like, refer to <xref 10.569 + linkend="sec:tour-basic:username"/> 10.570 + below.</para></listitem> 10.571 + <listitem><para id="x_46">If you have set the <envar>EMAIL</envar> 10.572 + environment variable, this will be used 10.573 + next.</para></listitem> 10.574 + <listitem><para id="x_47">Mercurial will query your system to find out 10.575 + your local user name and host name, and construct a 10.576 + username from these components. Since this often results 10.577 + in a username that is not very useful, it will print a 10.578 + warning if it has to do 10.579 + this.</para></listitem> 10.580 + </orderedlist> 10.581 + <para id="x_48">If all of these mechanisms fail, Mercurial will 10.582 + fail, printing an error message. In this case, it will not 10.583 + let you commit until you set up a 10.584 + username.</para> 10.585 + <para id="x_49">You should think of the <envar>HGUSER</envar> environment 10.586 + variable and the <option role="hg-opt-commit">-u</option> 10.587 + option to the <command role="hg-cmd">hg commit</command> 10.588 + command as ways to <emphasis>override</emphasis> Mercurial's 10.589 + default selection of username. For normal use, the simplest 10.590 + and most robust way to set a username for yourself is by 10.591 + creating a <filename role="special">.hgrc</filename> file; see 10.592 + below for details.</para> 10.593 + <sect3 id="sec:tour-basic:username"> 10.594 + <title>Creating a Mercurial configuration file</title> 10.595 + 10.596 + <para id="x_4a">To set a user name, use your favorite editor 10.597 + to create a file called <filename 10.598 + role="special">.hgrc</filename> in your home directory. 10.599 + Mercurial will use this file to look up your personalised 10.600 + configuration settings. The initial contents of your 10.601 + <filename role="special">.hgrc</filename> should look like 10.602 + this.</para> 10.603 + 10.604 + <tip> 10.605 + <title><quote>Home directory</quote> on Windows</title> 10.606 + 10.607 + <para id="x_716">When we refer to your home directory, on an English 10.608 + language installation of Windows this will usually be a 10.609 + folder named after your user name in 10.610 + <filename>C:\Documents and Settings</filename>. You can 10.611 + find out the exact name of your home directory by opening 10.612 + a command prompt window and running the following 10.613 + command.</para> 10.614 + 10.615 + <screen><prompt>C:\></prompt> <userinput>echo %UserProfile%</userinput></screen> 10.616 + </tip> 10.617 + 10.618 + <programlisting># This is a Mercurial configuration file. 10.619 +[ui] 10.620 +username = Firstname Lastname <email.address@example.net></programlisting> 10.621 + 10.622 + <para id="x_4b">The <quote><literal>[ui]</literal></quote> line begins a 10.623 + <emphasis>section</emphasis> of the config file, so you can 10.624 + read the <quote><literal>username = ...</literal></quote> 10.625 + line as meaning <quote>set the value of the 10.626 + <literal>username</literal> item in the 10.627 + <literal>ui</literal> section</quote>. A section continues 10.628 + until a new section begins, or the end of the file. 10.629 + Mercurial ignores empty lines and treats any text from 10.630 + <quote><literal>#</literal></quote> to the end of a line as 10.631 + a comment.</para> 10.632 + </sect3> 10.633 + 10.634 + <sect3> 10.635 + <title>Choosing a user name</title> 10.636 + 10.637 + <para id="x_4c">You can use any text you like as the value of 10.638 + the <literal>username</literal> config item, since this 10.639 + information is for reading by other people, but will not be 10.640 + interpreted by Mercurial. The convention that most people 10.641 + follow is to use their name and email address, as in the 10.642 + example above.</para> 10.643 + <note> 10.644 + <para id="x_4d">Mercurial's built-in web server obfuscates 10.645 + email addresses, to make it more difficult for the email 10.646 + harvesting tools that spammers use. This reduces the 10.647 + likelihood that you'll start receiving more junk email if 10.648 + you publish a Mercurial repository on the 10.649 + web.</para></note> 10.650 + </sect3> 10.651 + </sect2> 10.652 + <sect2> 10.653 + <title>Writing a commit message</title> 10.654 + 10.655 + <para id="x_4e">When we commit a change, Mercurial drops us into 10.656 + a text editor, to enter a message that will describe the 10.657 + modifications we've made in this changeset. This is called 10.658 + the <emphasis>commit message</emphasis>. It will be a record 10.659 + for readers of what we did and why, and it will be printed by 10.660 + <command role="hg-cmd">hg log</command> after we've finished 10.661 + committing.</para> 10.662 + 10.663 + &interaction.tour.commit; 10.664 + 10.665 + <para id="x_4f">The editor that the <command role="hg-cmd">hg 10.666 + commit</command> command drops us into will contain an empty 10.667 + line or two, followed by a number of lines starting with 10.668 + <quote><literal>HG:</literal></quote>.</para> 10.669 + 10.670 + <programlisting> 10.671 +This is where I type my commit comment. 10.672 + 10.673 +HG: Enter commit message. Lines beginning with 'HG:' are removed. 10.674 +HG: -- 10.675 +HG: user: Bryan O'Sullivan <bos@serpentine.com> 10.676 +HG: branch 'default' 10.677 +HG: changed hello.c</programlisting> 10.678 + 10.679 + <para id="x_50">Mercurial ignores the lines that start with 10.680 + <quote><literal>HG:</literal></quote>; it uses them only to 10.681 + tell us which files it's recording changes to. Modifying or 10.682 + deleting these lines has no effect.</para> 10.683 + </sect2> 10.684 + <sect2> 10.685 + <title>Writing a good commit message</title> 10.686 + 10.687 + <para id="x_51">Since <command role="hg-cmd">hg log</command> 10.688 + only prints the first line of a commit message by default, 10.689 + it's best to write a commit message whose first line stands 10.690 + alone. Here's a real example of a commit message that 10.691 + <emphasis>doesn't</emphasis> follow this guideline, and hence 10.692 + has a summary that is not readable.</para> 10.693 + 10.694 + <programlisting> 10.695 +changeset: 73:584af0e231be 10.696 +user: Censored Person <censored.person@example.org> 10.697 +date: Tue Sep 26 21:37:07 2006 -0700 10.698 +summary: include buildmeister/commondefs. Add exports.</programlisting> 10.699 + 10.700 + <para id="x_52">As far as the remainder of the contents of the 10.701 + commit message are concerned, there are no hard-and-fast 10.702 + rules. Mercurial itself doesn't interpret or care about the 10.703 + contents of the commit message, though your project may have 10.704 + policies that dictate a certain kind of formatting.</para> 10.705 + <para id="x_53">My personal preference is for short, but 10.706 + informative, commit messages that tell me something that I 10.707 + can't figure out with a quick glance at the output of <command 10.708 + role="hg-cmd">hg log --patch</command>.</para> 10.709 + <para id="x_55">If we run the <command role="hg-cmd">hg 10.710 + commit</command> command without any arguments, it records 10.711 + all of the changes we've made, as reported by <command 10.712 + role="hg-cmd">hg status</command> and <command 10.713 + role="hg-cmd">hg diff</command>.</para> 10.714 + 10.715 + <note> 10.716 + <title>A surprise for Subversion users</title> 10.717 + 10.718 + <para id="x_717">Like other Mercurial commands, if we don't supply 10.719 + explicit names to commit to the <command role="hg-cmd">hg 10.720 + commit</command>, it will operate across a repository's 10.721 + entire working directory. Be wary of this if you're coming 10.722 + from the Subversion or CVS world, since you might expect it 10.723 + to operate only on the current directory that you happen to 10.724 + be visiting and its subdirectories.</para> 10.725 + </note> 10.726 + </sect2> 10.727 + 10.728 + <sect2> 10.729 + <title>Aborting a commit</title> 10.730 + 10.731 + <para id="x_54">If you decide that you don't want to commit 10.732 + while in the middle of editing a commit message, simply exit 10.733 + from your editor without saving the file that it's editing. 10.734 + This will cause nothing to happen to either the repository or 10.735 + the working directory.</para> 10.736 + </sect2> 10.737 + 10.738 + <sect2> 10.739 + <title>Admiring our new handiwork</title> 10.740 + 10.741 + <para id="x_56">Once we've finished the commit, we can use the 10.742 + <command role="hg-cmd">hg tip</command> command to display the 10.743 + changeset we just created. This command produces output that 10.744 + is identical to <command role="hg-cmd">hg log</command>, but 10.745 + it only displays the newest revision in the repository.</para> 10.746 + 10.747 + &interaction.tour.tip; 10.748 + 10.749 + <para id="x_57">We refer to the newest revision in the 10.750 + repository as the <emphasis>tip revision</emphasis>, or simply 10.751 + the <emphasis>tip</emphasis>.</para> 10.752 + 10.753 + <para id="x_684">By the way, the <command role="hg-cmd">hg tip</command> 10.754 + command accepts many of the same options as <command 10.755 + role="hg-cmd">hg log</command>, so <option 10.756 + role="hg-opt-global">-v</option> above indicates <quote>be 10.757 + verbose</quote>, <option role="hg-opt-tip">-p</option> 10.758 + specifies <quote>print a patch</quote>. The use of <option 10.759 + role="hg-opt-tip">-p</option> to print patches is another 10.760 + example of the consistent naming we mentioned earlier.</para> 10.761 + </sect2> 10.762 + </sect1> 10.763 + 10.764 + <sect1> 10.765 + <title>Sharing changes</title> 10.766 + 10.767 + <para id="x_58">We mentioned earlier that repositories in 10.768 + Mercurial are self-contained. This means that the changeset we 10.769 + just created exists only in our <filename 10.770 + class="directory">my-hello</filename> repository. Let's look 10.771 + at a few ways that we can propagate this change into other 10.772 + repositories.</para> 10.773 + 10.774 + <sect2 id="sec:tour:pull"> 10.775 + <title>Pulling changes from another repository</title> 10.776 + 10.777 + <para id="x_59">To get started, let's clone our original 10.778 + <filename class="directory">hello</filename> repository, which 10.779 + does not contain the change we just committed. We'll call our 10.780 + temporary repository <filename 10.781 + class="directory">hello-pull</filename>.</para> 10.782 + 10.783 + &interaction.tour.clone-pull; 10.784 + 10.785 + <para id="x_5a">We'll use the <command role="hg-cmd">hg 10.786 + pull</command> command to bring changes from <filename 10.787 + class="directory">my-hello</filename> into <filename 10.788 + class="directory">hello-pull</filename>. However, blindly 10.789 + pulling unknown changes into a repository is a somewhat scary 10.790 + prospect. Mercurial provides the <command role="hg-cmd">hg 10.791 + incoming</command> command to tell us what changes the 10.792 + <command role="hg-cmd">hg pull</command> command 10.793 + <emphasis>would</emphasis> pull into the repository, without 10.794 + actually pulling the changes in.</para> 10.795 + 10.796 + &interaction.tour.incoming; 10.797 + 10.798 + <para id="x_5c">Bringing changes into a repository is a simple 10.799 + matter of running the <command role="hg-cmd">hg pull</command> 10.800 + command, and optionally telling it which repository to pull from.</para> 10.801 + 10.802 + &interaction.tour.pull; 10.803 + 10.804 + <para id="x_5d">As you can see from the before-and-after output 10.805 + of <command role="hg-cmd">hg tip</command>, we have 10.806 + successfully pulled changes into our repository. However, 10.807 + Mercurial separates pulling changes in from updating the 10.808 + working directory. There remains one step before we will see 10.809 + the changes that we just pulled appear in the working 10.810 + directory.</para> 10.811 + 10.812 + <tip> 10.813 + <title>Pulling specific changes</title> 10.814 + 10.815 + <para id="x_5b">It is possible that due to the delay between 10.816 + running <command role="hg-cmd">hg incoming</command> and 10.817 + <command role="hg-cmd">hg pull</command>, you may not see 10.818 + all changesets that will be brought from the other 10.819 + repository. Suppose you're pulling changes from a repository 10.820 + on the network somewhere. While you are looking at the 10.821 + <command role="hg-cmd">hg incoming</command> output, and 10.822 + before you pull those changes, someone might have committed 10.823 + something in the remote repository. This means that it's 10.824 + possible to pull more changes than you saw when using 10.825 + <command role="hg-cmd">hg incoming</command>.</para> 10.826 + 10.827 + <para id="x_718">If you only want to pull precisely the changes that were 10.828 + listed by <command role="hg-cmd">hg incoming</command>, or 10.829 + you have some other reason to pull a subset of changes, 10.830 + simply identify the change that you want to pull by its 10.831 + changeset ID, e.g. <command>hg pull 10.832 + -r7e95bb</command>.</para> 10.833 + </tip> 10.834 + </sect2> 10.835 + 10.836 + <sect2> 10.837 + <title>Updating the working directory</title> 10.838 + 10.839 + <para id="x_5e">We have so far glossed over the relationship 10.840 + between a repository and its working directory. The <command 10.841 + role="hg-cmd">hg pull</command> command that we ran in 10.842 + <xref linkend="sec:tour:pull"/> brought changes into the 10.843 + repository, but if we check, there's no sign of those changes 10.844 + in the working directory. This is because <command 10.845 + role="hg-cmd">hg pull</command> does not (by default) touch 10.846 + the working directory. Instead, we use the <command 10.847 + role="hg-cmd">hg update</command> command to do this.</para> 10.848 + 10.849 + &interaction.tour.update; 10.850 + 10.851 + <para id="x_5f">It might seem a bit strange that <command 10.852 + role="hg-cmd">hg pull</command> doesn't update the working 10.853 + directory automatically. There's actually a good reason for 10.854 + this: you can use <command role="hg-cmd">hg update</command> 10.855 + to update the working directory to the state it was in at 10.856 + <emphasis>any revision</emphasis> in the history of the 10.857 + repository. If you had the working directory updated to an 10.858 + old revision&emdash;to hunt down the origin of a bug, 10.859 + say&emdash;and ran a <command role="hg-cmd">hg pull</command> 10.860 + which automatically updated the working directory to a new 10.861 + revision, you might not be terribly happy.</para> 10.862 + 10.863 + <para id="x_60">Since pull-then-update is such a common sequence 10.864 + of operations, Mercurial lets you combine the two by passing 10.865 + the <option role="hg-opt-pull">-u</option> option to <command 10.866 + role="hg-cmd">hg pull</command>.</para> 10.867 + 10.868 + <para id="x_61">If you look back at the output of <command 10.869 + role="hg-cmd">hg pull</command> in <xref 10.870 + linkend="sec:tour:pull"/> when we ran it without <option 10.871 + role="hg-opt-pull">-u</option>, you can see that it printed 10.872 + a helpful reminder that we'd have to take an explicit step to 10.873 + update the working directory.</para> 10.874 + 10.875 + <para id="x_62">To find out what revision the working directory 10.876 + is at, use the <command role="hg-cmd">hg parents</command> 10.877 + command.</para> 10.878 + 10.879 + &interaction.tour.parents; 10.880 + 10.881 + <para id="x_63">If you look back at <xref 10.882 + linkend="fig:tour-basic:history"/>, you'll see arrows 10.883 + connecting each changeset. The node that the arrow leads 10.884 + <emphasis>from</emphasis> in each case is a parent, and the 10.885 + node that the arrow leads <emphasis>to</emphasis> is its 10.886 + child. The working directory has a parent in just the same 10.887 + way; this is the changeset that the working directory 10.888 + currently contains.</para> 10.889 + 10.890 + <para id="x_64">To update the working directory to a particular 10.891 + revision, give a revision number or changeset ID to the 10.892 + <command role="hg-cmd">hg update</command> command.</para> 10.893 + 10.894 + &interaction.tour.older; 10.895 + 10.896 + <para id="x_65">If you omit an explicit revision, <command 10.897 + role="hg-cmd">hg update</command> will update to the tip 10.898 + revision, as shown by the second call to <command 10.899 + role="hg-cmd">hg update</command> in the example 10.900 + above.</para> 10.901 + </sect2> 10.902 + 10.903 + <sect2> 10.904 + <title>Pushing changes to another repository</title> 10.905 + 10.906 + <para id="x_66">Mercurial lets us push changes to another 10.907 + repository, from the repository we're currently visiting. As 10.908 + with the example of <command role="hg-cmd">hg pull</command> 10.909 + above, we'll create a temporary repository to push our changes 10.910 + into.</para> 10.911 + 10.912 + &interaction.tour.clone-push; 10.913 + 10.914 + <para id="x_67">The <command role="hg-cmd">hg outgoing</command> 10.915 + command tells us what changes would be pushed into another 10.916 + repository.</para> 10.917 + 10.918 + &interaction.tour.outgoing; 10.919 + 10.920 + <para id="x_68">And the <command role="hg-cmd">hg push</command> 10.921 + command does the actual push.</para> 10.922 + 10.923 + &interaction.tour.push; 10.924 + 10.925 + <para id="x_69">As with <command role="hg-cmd">hg 10.926 + pull</command>, the <command role="hg-cmd">hg push</command> 10.927 + command does not update the working directory in the 10.928 + repository that it's pushing changes into. Unlike <command 10.929 + role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg 10.930 + push</command> does not provide a <literal>-u</literal> 10.931 + option that updates the other repository's working directory. 10.932 + This asymmetry is deliberate: the repository we're pushing to 10.933 + might be on a remote server and shared between several people. 10.934 + If we were to update its working directory while someone was 10.935 + working in it, their work would be disrupted.</para> 10.936 + 10.937 + <para id="x_6a">What happens if we try to pull or push changes 10.938 + and the receiving repository already has those changes? 10.939 + Nothing too exciting.</para> 10.940 + 10.941 + &interaction.tour.push.nothing; 10.942 + </sect2> 10.943 + 10.944 + <sect2> 10.945 + <title>Default locations</title> 10.946 + 10.947 + <para id="x_719">When we clone a repository, Mercurial records the location 10.948 + of the repository we cloned in the 10.949 + <filename>.hg/hgrc</filename> file of the new repository. If 10.950 + we don't supply a location to <command>hg pull</command> from 10.951 + or <command>hg push</command> to, those commands will use this 10.952 + location as a default. The <command>hg incoming</command> 10.953 + and <command>hg outgoing</command> commands do so too.</para> 10.954 + 10.955 + <para id="x_71a">If you open a repository's <filename>.hg/hgrc</filename> 10.956 + file in a text editor, you will see contents like the 10.957 + following.</para> 10.958 + 10.959 + <programlisting>[paths] 10.960 +default = http://www.selenic.com/repo/hg</programlisting> 10.961 + 10.962 + <para id="x_71b">It is possible&emdash;and often useful&emdash;to have the 10.963 + default location for <command>hg push</command> and 10.964 + <command>hg outgoing</command> be different from those for 10.965 + <command>hg pull</command> and <command>hg incoming</command>. 10.966 + We can do this by adding a <literal>default-push</literal> 10.967 + entry to the <literal>[paths]</literal> section of the 10.968 + <filename>.hg/hgrc</filename> file, as follows.</para> 10.969 + 10.970 + <programlisting>[paths] 10.971 +default = http://www.selenic.com/repo/hg 10.972 +default-push = http://hg.example.com/hg</programlisting> 10.973 + </sect2> 10.974 + 10.975 + <sect2> 10.976 + <title>Sharing changes over a network</title> 10.977 + 10.978 + <para id="x_6b">The commands we have covered in the previous few 10.979 + sections are not limited to working with local repositories. 10.980 + Each works in exactly the same fashion over a network 10.981 + connection; simply pass in a URL instead of a local 10.982 + path.</para> 10.983 + 10.984 + &interaction.tour.outgoing.net; 10.985 + 10.986 + <para id="x_6c">In this example, we can see what changes we 10.987 + could push to the remote repository, but the repository is 10.988 + understandably not set up to let anonymous users push to 10.989 + it.</para> 10.990 + 10.991 + &interaction.tour.push.net; 10.992 + </sect2> 10.993 + </sect1> 10.994 + 10.995 + <sect1> 10.996 + <title>Starting a new project</title> 10.997 + 10.998 + <para id="x_71c">It is just as easy to begin a new project as to work on one 10.999 + that already exists. The <command>hg init</command> command 10.1000 + creates a new, empty Mercurial repository.</para> 10.1001 + 10.1002 + &interaction.ch01-new.init; 10.1003 + 10.1004 + <para id="x_71d">This simply creates a repository named 10.1005 + <filename>myproject</filename> in the current directory.</para> 10.1006 + 10.1007 + &interaction.ch01-new.ls; 10.1008 + 10.1009 + <para id="x_71e">We can tell that <filename>myproject</filename> is a 10.1010 + Mercurial repository, because it contains a 10.1011 + <filename>.hg</filename> directory.</para> 10.1012 + 10.1013 + &interaction.ch01-new.ls2; 10.1014 + 10.1015 + <para id="x_71f">If we want to add some pre-existing files to the repository, 10.1016 + we copy them into place, and tell Mercurial to start tracking 10.1017 + them using the <command>hg add</command> command.</para> 10.1018 + 10.1019 + &interaction.ch01-new.add; 10.1020 + 10.1021 + <para id="x_720">Once we are satisfied that our project looks right, we 10.1022 + commit our changes.</para> 10.1023 + 10.1024 + &interaction.ch01-new.commit; 10.1025 + 10.1026 + <para id="x_721">It takes just a few moments to start using Mercurial on a 10.1027 + new project, which is part of its appeal. Revision control is 10.1028 + now so easy to work with, we can use it on the smallest of 10.1029 + projects that we might not have considered with a more 10.1030 + complicated tool.</para> 10.1031 + </sect1> 10.1032 +</chapter> 10.1033 + 10.1034 +<!-- 10.1035 +local variables: 10.1036 +sgml-parent-document: ("00book.xml" "book" "chapter") 10.1037 +end: 10.1038 +-->
11.1 --- a/en/ch02-tour-merge.xml Sat Apr 18 11:52:33 2009 +0800 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,401 +0,0 @@ 11.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 11.5 - 11.6 -<chapter id="chap:tour-merge"> 11.7 - <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?> 11.8 - <title>A tour of Mercurial: merging work</title> 11.9 - 11.10 - <para id="x_338">We've now covered cloning a repository, making changes in a 11.11 - repository, and pulling or pushing changes from one repository 11.12 - into another. Our next step is <emphasis>merging</emphasis> 11.13 - changes from separate repositories.</para> 11.14 - 11.15 - <sect1> 11.16 - <title>Merging streams of work</title> 11.17 - 11.18 - <para id="x_339">Merging is a fundamental part of working with a distributed 11.19 - revision control tool.</para> 11.20 - <itemizedlist> 11.21 - <listitem><para id="x_33a">Alice and Bob each have a personal copy of a 11.22 - repository for a project they're collaborating on. Alice 11.23 - fixes a bug in her repository; Bob adds a new feature in 11.24 - his. They want the shared repository to contain both the 11.25 - bug fix and the new feature.</para> 11.26 - </listitem> 11.27 - <listitem><para id="x_33b">I frequently work on several different tasks for 11.28 - a single project at once, each safely isolated in its own 11.29 - repository. Working this way means that I often need to 11.30 - merge one piece of my own work with another.</para> 11.31 - </listitem></itemizedlist> 11.32 - 11.33 - <para id="x_33c">Because merging is such a common thing to need to do, 11.34 - Mercurial makes it easy. Let's walk through the process. We'll 11.35 - begin by cloning yet another repository (see how often they 11.36 - spring up?) and making a change in it.</para> 11.37 - 11.38 - &interaction.tour.merge.clone; 11.39 - 11.40 - <para id="x_33d">We should now have two copies of 11.41 - <filename>hello.c</filename> with different contents. The 11.42 - histories of the two repositories have also diverged, as 11.43 - illustrated in <xref 11.44 - linkend="fig:tour-merge:sep-repos"/>.</para> 11.45 - 11.46 - &interaction.tour.merge.cat; 11.47 - 11.48 - <figure id="fig:tour-merge:sep-repos"> 11.49 - <title>Divergent recent histories of the <filename 11.50 - class="directory">my-hello</filename> and <filename 11.51 - class="directory">my-new-hello</filename> 11.52 - repositories</title> 11.53 - <mediaobject> 11.54 - <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject> 11.55 - <textobject><phrase>XXX add text</phrase></textobject> 11.56 - </mediaobject> 11.57 - </figure> 11.58 - 11.59 - <para id="x_33f">We already know that pulling changes from our <filename 11.60 - class="directory">my-hello</filename> repository will have no 11.61 - effect on the working directory.</para> 11.62 - 11.63 - &interaction.tour.merge.pull; 11.64 - 11.65 - <para id="x_340">However, the <command role="hg-cmd">hg pull</command> 11.66 - command says something about <quote>heads</quote>.</para> 11.67 - 11.68 - <sect2> 11.69 - <title>Head changesets</title> 11.70 - 11.71 - <para id="x_341">A head is a change that has no descendants, or children, 11.72 - as they're also known. The tip revision is thus a head, 11.73 - because the newest revision in a repository doesn't have any 11.74 - children, but a repository can contain more than one 11.75 - head.</para> 11.76 - 11.77 - <figure id="fig:tour-merge:pull"> 11.78 - <title>Repository contents after pulling from <filename 11.79 - class="directory">my-hello</filename> into <filename 11.80 - class="directory">my-new-hello</filename></title> 11.81 - <mediaobject> 11.82 - <imageobject> 11.83 - <imagedata fileref="figs/tour-merge-pull.png"/> 11.84 - </imageobject> 11.85 - <textobject><phrase>XXX add text</phrase></textobject> 11.86 - </mediaobject> 11.87 - </figure> 11.88 - 11.89 - <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can 11.90 - see the effect of the pull from <filename 11.91 - class="directory">my-hello</filename> into <filename 11.92 - class="directory">my-new-hello</filename>. The history that 11.93 - was already present in <filename 11.94 - class="directory">my-new-hello</filename> is untouched, but 11.95 - a new revision has been added. By referring to <xref 11.96 - linkend="fig:tour-merge:sep-repos"/>, we can see that the 11.97 - <emphasis>changeset ID</emphasis> remains the same in the new 11.98 - repository, but the <emphasis>revision number</emphasis> has 11.99 - changed. (This, incidentally, is a fine example of why it's 11.100 - not safe to use revision numbers when discussing changesets.) 11.101 - We can view the heads in a repository using the <command 11.102 - role="hg-cmd">hg heads</command> command.</para> 11.103 - 11.104 - &interaction.tour.merge.heads; 11.105 - 11.106 - </sect2> 11.107 - <sect2> 11.108 - <title>Performing the merge</title> 11.109 - 11.110 - <para id="x_344">What happens if we try to use the normal <command 11.111 - role="hg-cmd">hg update</command> command to update to the 11.112 - new tip?</para> 11.113 - 11.114 - &interaction.tour.merge.update; 11.115 - 11.116 - <para id="x_345">Mercurial is telling us that the <command role="hg-cmd">hg 11.117 - update</command> command won't do a merge; it won't update 11.118 - the working directory when it thinks we might want to do 11.119 - a merge, unless we force it to do so. Instead, we use the 11.120 - <command role="hg-cmd">hg merge</command> command to merge the 11.121 - two heads.</para> 11.122 - 11.123 - &interaction.tour.merge.merge; 11.124 - 11.125 - <para id="x_347">This updates the working directory so that it contains 11.126 - changes from <emphasis>both</emphasis> heads, which is 11.127 - reflected in both the output of <command role="hg-cmd">hg 11.128 - parents</command> and the contents of 11.129 - <filename>hello.c</filename>.</para> 11.130 - 11.131 - &interaction.tour.merge.parents; 11.132 - 11.133 - </sect2> 11.134 - <sect2> 11.135 - <title>Committing the results of the merge</title> 11.136 - 11.137 - <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg 11.138 - parents</command> will display two parents until we <command 11.139 - role="hg-cmd">hg commit</command> the results of the 11.140 - merge.</para> 11.141 - 11.142 - &interaction.tour.merge.commit; 11.143 - 11.144 - <para id="x_349">We now have a new tip revision; notice that it has 11.145 - <emphasis>both</emphasis> of our former heads as its parents. 11.146 - These are the same revisions that were previously displayed by 11.147 - <command role="hg-cmd">hg parents</command>.</para> 11.148 - 11.149 - &interaction.tour.merge.tip; 11.150 - 11.151 - <para id="x_34a">In <xref 11.152 - linkend="fig:tour-merge:merge"/>, you can see a 11.153 - representation of what happens to the working directory during 11.154 - the merge, and how this affects the repository when the commit 11.155 - happens. During the merge, the working directory has two 11.156 - parent changesets, and these become the parents of the new 11.157 - changeset.</para> 11.158 - 11.159 - <figure id="fig:tour-merge:merge"> 11.160 - <title>Working directory and repository during merge, and 11.161 - following commit</title> 11.162 - <mediaobject> 11.163 - <imageobject> 11.164 - <imagedata fileref="figs/tour-merge-merge.png"/> 11.165 - </imageobject> 11.166 - <textobject><phrase>XXX add text</phrase></textobject> 11.167 - </mediaobject> 11.168 - </figure> 11.169 - 11.170 - <para id="x_69c">We sometimes talk about a merge having 11.171 - <emphasis>sides</emphasis>: the left side is the first parent 11.172 - in the output of <command role="hg-cmd">hg parents</command>, 11.173 - and the right side is the second. If the working directory 11.174 - was at e.g. revision 5 before we began a merge, that revision 11.175 - will become the left side of the merge.</para> 11.176 - </sect2> 11.177 - </sect1> 11.178 - 11.179 - <sect1> 11.180 - <title>Merging conflicting changes</title> 11.181 - 11.182 - <para id="x_34b">Most merges are simple affairs, but sometimes you'll find 11.183 - yourself merging changes where each side modifies the same portions 11.184 - of the same files. Unless both modifications are identical, 11.185 - this results in a <emphasis>conflict</emphasis>, where you have 11.186 - to decide how to reconcile the different changes into something 11.187 - coherent.</para> 11.188 - 11.189 - <figure id="fig:tour-merge:conflict"> 11.190 - <title>Conflicting changes to a document</title> 11.191 - <mediaobject> 11.192 - <imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject> 11.193 - <textobject><phrase>XXX add text</phrase></textobject> 11.194 - </mediaobject> 11.195 - </figure> 11.196 - 11.197 - <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates 11.198 - an instance of two conflicting changes to a document. We 11.199 - started with a single version of the file; then we made some 11.200 - changes; while someone else made different changes to the same 11.201 - text. Our task in resolving the conflicting changes is to 11.202 - decide what the file should look like.</para> 11.203 - 11.204 - <para id="x_34e">Mercurial doesn't have a built-in facility for handling 11.205 - conflicts. Instead, it runs an external program, usually one 11.206 - that displays some kind of graphical conflict resolution 11.207 - interface. By default, Mercurial tries to find one of several 11.208 - different merging tools that are likely to be installed on your 11.209 - system. It first tries a few fully automatic merging tools; if 11.210 - these don't succeed (because the resolution process requires 11.211 - human guidance) or aren't present, it tries a few 11.212 - different graphical merging tools.</para> 11.213 - 11.214 - <para id="x_34f">It's also possible to get Mercurial to run another program 11.215 - or script instead of <command>hgmerge</command>, by setting the 11.216 - <envar>HGMERGE</envar> environment variable to the name of your 11.217 - preferred program.</para> 11.218 - 11.219 - <sect2> 11.220 - <title>Using a graphical merge tool</title> 11.221 - 11.222 - <para id="x_350">My preferred graphical merge tool is 11.223 - <command>kdiff3</command>, which I'll use to describe the 11.224 - features that are common to graphical file merging tools. You 11.225 - can see a screenshot of <command>kdiff3</command> in action in 11.226 - <xref linkend="fig:tour-merge:kdiff3"/>. The kind of 11.227 - merge it is performing is called a <emphasis>three-way 11.228 - merge</emphasis>, because there are three different versions 11.229 - of the file of interest to us. The tool thus splits the upper 11.230 - portion of the window into three panes:</para> 11.231 - <itemizedlist> 11.232 - <listitem><para id="x_351">At the left is the <emphasis>base</emphasis> 11.233 - version of the file, i.e. the most recent version from 11.234 - which the two versions we're trying to merge are 11.235 - descended.</para> 11.236 - </listitem> 11.237 - <listitem><para id="x_352">In the middle is <quote>our</quote> version of 11.238 - the file, with the contents that we modified.</para> 11.239 - </listitem> 11.240 - <listitem><para id="x_353">On the right is <quote>their</quote> version 11.241 - of the file, the one that from the changeset that we're 11.242 - trying to merge with.</para> 11.243 - </listitem></itemizedlist> 11.244 - <para id="x_354">In the pane below these is the current 11.245 - <emphasis>result</emphasis> of the merge. Our task is to 11.246 - replace all of the red text, which indicates unresolved 11.247 - conflicts, with some sensible merger of the 11.248 - <quote>ours</quote> and <quote>theirs</quote> versions of the 11.249 - file.</para> 11.250 - 11.251 - <para id="x_355">All four of these panes are <emphasis>locked 11.252 - together</emphasis>; if we scroll vertically or horizontally 11.253 - in any of them, the others are updated to display the 11.254 - corresponding sections of their respective files.</para> 11.255 - 11.256 - <figure id="fig:tour-merge:kdiff3"> 11.257 - <title>Using <command>kdiff3</command> to merge versions of a 11.258 - file</title> 11.259 - <mediaobject> 11.260 - <imageobject> 11.261 - <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject> 11.262 - <textobject> 11.263 - <phrase>XXX add text</phrase> 11.264 - </textobject> 11.265 - </mediaobject> 11.266 - </figure> 11.267 - 11.268 - <para id="x_357">For each conflicting portion of the file, we can choose to 11.269 - resolve the conflict using some combination of text from the 11.270 - base version, ours, or theirs. We can also manually edit the 11.271 - merged file at any time, in case we need to make further 11.272 - modifications.</para> 11.273 - 11.274 - <para id="x_358">There are <emphasis>many</emphasis> file merging tools 11.275 - available, too many to cover here. They vary in which 11.276 - platforms they are available for, and in their particular 11.277 - strengths and weaknesses. Most are tuned for merging files 11.278 - containing plain text, while a few are aimed at specialised 11.279 - file formats (generally XML).</para> 11.280 - 11.281 - </sect2> 11.282 - <sect2> 11.283 - <title>A worked example</title> 11.284 - 11.285 - <para id="x_359">In this example, we will reproduce the file modification 11.286 - history of <xref linkend="fig:tour-merge:conflict"/> 11.287 - above. Let's begin by creating a repository with a base 11.288 - version of our document.</para> 11.289 - 11.290 - &interaction.tour-merge-conflict.wife; 11.291 - 11.292 - <para id="x_35a">We'll clone the repository and make a change to the 11.293 - file.</para> 11.294 - 11.295 - &interaction.tour-merge-conflict.cousin; 11.296 - 11.297 - <para id="x_35b">And another clone, to simulate someone else making a 11.298 - change to the file. (This hints at the idea that it's not all 11.299 - that unusual to merge with yourself when you isolate tasks in 11.300 - separate repositories, and indeed to find and resolve 11.301 - conflicts while doing so.)</para> 11.302 - 11.303 - &interaction.tour-merge-conflict.son; 11.304 - 11.305 - <para id="x_35c">Having created two 11.306 - different versions of the file, we'll set up an environment 11.307 - suitable for running our merge.</para> 11.308 - 11.309 - &interaction.tour-merge-conflict.pull; 11.310 - 11.311 - <para id="x_35d">In this example, I'll set 11.312 - <envar>HGMERGE</envar> to tell Mercurial to use the 11.313 - non-interactive <command>merge</command> command. This is 11.314 - bundled with many Unix-like systems. (If you're following this 11.315 - example on your computer, don't bother setting 11.316 - <envar>HGMERGE</envar>.)</para> 11.317 - 11.318 - &interaction.tour-merge-conflict.merge; 11.319 - 11.320 - <para id="x_35f">Because <command>merge</command> can't resolve the 11.321 - conflicting changes, it leaves <emphasis>merge 11.322 - markers</emphasis> inside the file that has conflicts, 11.323 - indicating which lines have conflicts, and whether they came 11.324 - from our version of the file or theirs.</para> 11.325 - 11.326 - <para id="x_360">Mercurial can tell from the way <command>merge</command> 11.327 - exits that it wasn't able to merge successfully, so it tells 11.328 - us what commands we'll need to run if we want to redo the 11.329 - merging operation. This could be useful if, for example, we 11.330 - were running a graphical merge tool and quit because we were 11.331 - confused or realised we had made a mistake.</para> 11.332 - 11.333 - <para id="x_361">If automatic or manual merges fail, there's nothing to 11.334 - prevent us from <quote>fixing up</quote> the affected files 11.335 - ourselves, and committing the results of our merge:</para> 11.336 - 11.337 - &interaction.tour-merge-conflict.commit; 11.338 - 11.339 - </sect2> 11.340 - </sect1> 11.341 - <sect1 id="sec:tour-merge:fetch"> 11.342 - <title>Simplifying the pull-merge-commit sequence</title> 11.343 - 11.344 - <para id="x_362">The process of merging changes as outlined above is 11.345 - straightforward, but requires running three commands in 11.346 - sequence.</para> 11.347 - <programlisting>hg pull -u 11.348 -hg merge 11.349 -hg commit -m 'Merged remote changes'</programlisting> 11.350 - <para id="x_363">In the case of the final commit, you also need to enter a 11.351 - commit message, which is almost always going to be a piece of 11.352 - uninteresting <quote>boilerplate</quote> text.</para> 11.353 - 11.354 - <para id="x_364">It would be nice to reduce the number of steps needed, if 11.355 - this were possible. Indeed, Mercurial is distributed with an 11.356 - extension called <literal role="hg-ext">fetch</literal> that 11.357 - does just this.</para> 11.358 - 11.359 - <para id="x_365">Mercurial provides a flexible extension mechanism that lets 11.360 - people extend its functionality, while keeping the core of 11.361 - Mercurial small and easy to deal with. Some extensions add new 11.362 - commands that you can use from the command line, while others 11.363 - work <quote>behind the scenes,</quote> for example adding 11.364 - capabilities to the server.</para> 11.365 - 11.366 - <para id="x_366">The <literal role="hg-ext">fetch</literal> 11.367 - extension adds a new command called, not surprisingly, <command 11.368 - role="hg-cmd">hg fetch</command>. This extension acts as a 11.369 - combination of <command role="hg-cmd">hg pull -u</command>, 11.370 - <command role="hg-cmd">hg merge</command> and <command 11.371 - role="hg-cmd">hg commit</command>. It begins by pulling 11.372 - changes from another repository into the current repository. If 11.373 - it finds that the changes added a new head to the repository, it 11.374 - begins a merge, then (if the merge succeeded) commits the result 11.375 - of the merge with an automatically-generated commit message. If 11.376 - no new heads were added, it updates the working directory to the 11.377 - new tip changeset.</para> 11.378 - 11.379 - <para id="x_367">Enabling the <literal 11.380 - role="hg-ext">fetch</literal> extension is easy. Edit the 11.381 - <filename role="special">.hgrc</filename> file in your home 11.382 - directory, and either go to the <literal 11.383 - role="rc-extensions">extensions</literal> section or create an 11.384 - <literal role="rc-extensions">extensions</literal> section. Then 11.385 - add a line that simply reads 11.386 - <quote><literal>fetch=</literal></quote>.</para> 11.387 - 11.388 - <programlisting>[extensions] 11.389 -fetch =</programlisting> 11.390 - 11.391 - <para id="x_368">(Normally, the right-hand side of the 11.392 - <quote><literal>=</literal></quote> would indicate where to find 11.393 - the extension, but since the <literal 11.394 - role="hg-ext">fetch</literal> extension is in the standard 11.395 - distribution, Mercurial knows where to search for it.)</para> 11.396 - 11.397 - </sect1> 11.398 -</chapter> 11.399 - 11.400 -<!-- 11.401 -local variables: 11.402 -sgml-parent-document: ("00book.xml" "book" "chapter") 11.403 -end: 11.404 --->
12.1 --- a/en/ch03-concepts.xml Sat Apr 18 11:52:33 2009 +0800 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,754 +0,0 @@ 12.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 12.5 - 12.6 -<chapter id="chap:concepts"> 12.7 - <?dbhtml filename="behind-the-scenes.html"?> 12.8 - <title>Behind the scenes</title> 12.9 - 12.10 - <para id="x_2e8">Unlike many revision control systems, the concepts 12.11 - upon which Mercurial is built are simple enough that it's easy to 12.12 - understand how the software really works. Knowing these details 12.13 - certainly isn't necessary, so it is certainly safe to skip this 12.14 - chapter. However, I think you will get more out of the software 12.15 - with a <quote>mental model</quote> of what's going on.</para> 12.16 - 12.17 - <para id="x_2e9">Being able to understand what's going on behind the 12.18 - scenes gives me confidence that Mercurial has been carefully 12.19 - designed to be both <emphasis>safe</emphasis> and 12.20 - <emphasis>efficient</emphasis>. And just as importantly, if it's 12.21 - easy for me to retain a good idea of what the software is doing 12.22 - when I perform a revision control task, I'm less likely to be 12.23 - surprised by its behavior.</para> 12.24 - 12.25 - <para id="x_2ea">In this chapter, we'll initially cover the core concepts 12.26 - behind Mercurial's design, then continue to discuss some of the 12.27 - interesting details of its implementation.</para> 12.28 - 12.29 - <sect1> 12.30 - <title>Mercurial's historical record</title> 12.31 - 12.32 - <sect2> 12.33 - <title>Tracking the history of a single file</title> 12.34 - 12.35 - <para id="x_2eb">When Mercurial tracks modifications to a file, it stores 12.36 - the history of that file in a metadata object called a 12.37 - <emphasis>filelog</emphasis>. Each entry in the filelog 12.38 - contains enough information to reconstruct one revision of the 12.39 - file that is being tracked. Filelogs are stored as files in 12.40 - the <filename role="special" 12.41 - class="directory">.hg/store/data</filename> directory. A 12.42 - filelog contains two kinds of information: revision data, and 12.43 - an index to help Mercurial to find a revision 12.44 - efficiently.</para> 12.45 - 12.46 - <para id="x_2ec">A file that is large, or has a lot of history, has its 12.47 - filelog stored in separate data 12.48 - (<quote><literal>.d</literal></quote> suffix) and index 12.49 - (<quote><literal>.i</literal></quote> suffix) files. For 12.50 - small files without much history, the revision data and index 12.51 - are combined in a single <quote><literal>.i</literal></quote> 12.52 - file. The correspondence between a file in the working 12.53 - directory and the filelog that tracks its history in the 12.54 - repository is illustrated in <xref 12.55 - linkend="fig:concepts:filelog"/>.</para> 12.56 - 12.57 - <figure id="fig:concepts:filelog"> 12.58 - <title>Relationships between files in working directory and 12.59 - filelogs in repository</title> 12.60 - <mediaobject> 12.61 - <imageobject><imagedata fileref="figs/filelog.png"/></imageobject> 12.62 - <textobject><phrase>XXX add text</phrase></textobject> 12.63 - </mediaobject> 12.64 - </figure> 12.65 - 12.66 - </sect2> 12.67 - <sect2> 12.68 - <title>Managing tracked files</title> 12.69 - 12.70 - <para id="x_2ee">Mercurial uses a structure called a 12.71 - <emphasis>manifest</emphasis> to collect together information 12.72 - about the files that it tracks. Each entry in the manifest 12.73 - contains information about the files present in a single 12.74 - changeset. An entry records which files are present in the 12.75 - changeset, the revision of each file, and a few other pieces 12.76 - of file metadata.</para> 12.77 - 12.78 - </sect2> 12.79 - <sect2> 12.80 - <title>Recording changeset information</title> 12.81 - 12.82 - <para id="x_2ef">The <emphasis>changelog</emphasis> contains information 12.83 - about each changeset. Each revision records who committed a 12.84 - change, the changeset comment, other pieces of 12.85 - changeset-related information, and the revision of the 12.86 - manifest to use.</para> 12.87 - 12.88 - </sect2> 12.89 - <sect2> 12.90 - <title>Relationships between revisions</title> 12.91 - 12.92 - <para id="x_2f0">Within a changelog, a manifest, or a filelog, each 12.93 - revision stores a pointer to its immediate parent (or to its 12.94 - two parents, if it's a merge revision). As I mentioned above, 12.95 - there are also relationships between revisions 12.96 - <emphasis>across</emphasis> these structures, and they are 12.97 - hierarchical in nature.</para> 12.98 - 12.99 - <para id="x_2f1">For every changeset in a repository, there is exactly one 12.100 - revision stored in the changelog. Each revision of the 12.101 - changelog contains a pointer to a single revision of the 12.102 - manifest. A revision of the manifest stores a pointer to a 12.103 - single revision of each filelog tracked when that changeset 12.104 - was created. These relationships are illustrated in 12.105 - <xref linkend="fig:concepts:metadata"/>.</para> 12.106 - 12.107 - <figure id="fig:concepts:metadata"> 12.108 - <title>Metadata relationships</title> 12.109 - <mediaobject> 12.110 - <imageobject><imagedata fileref="figs/metadata.png"/></imageobject> 12.111 - <textobject><phrase>XXX add text</phrase></textobject> 12.112 - </mediaobject> 12.113 - </figure> 12.114 - 12.115 - <para id="x_2f3">As the illustration shows, there is 12.116 - <emphasis>not</emphasis> a <quote>one to one</quote> 12.117 - relationship between revisions in the changelog, manifest, or 12.118 - filelog. If the manifest hasn't changed between two 12.119 - changesets, the changelog entries for those changesets will 12.120 - point to the same revision of the manifest. If a file that 12.121 - Mercurial tracks hasn't changed between two changesets, the 12.122 - entry for that file in the two revisions of the manifest will 12.123 - point to the same revision of its filelog.</para> 12.124 - 12.125 - </sect2> 12.126 - </sect1> 12.127 - <sect1> 12.128 - <title>Safe, efficient storage</title> 12.129 - 12.130 - <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are 12.131 - provided by a single structure called the 12.132 - <emphasis>revlog</emphasis>.</para> 12.133 - 12.134 - <sect2> 12.135 - <title>Efficient storage</title> 12.136 - 12.137 - <para id="x_2f5">The revlog provides efficient storage of revisions using a 12.138 - <emphasis>delta</emphasis> mechanism. Instead of storing a 12.139 - complete copy of a file for each revision, it stores the 12.140 - changes needed to transform an older revision into the new 12.141 - revision. For many kinds of file data, these deltas are 12.142 - typically a fraction of a percent of the size of a full copy 12.143 - of a file.</para> 12.144 - 12.145 - <para id="x_2f6">Some obsolete revision control systems can only work with 12.146 - deltas of text files. They must either store binary files as 12.147 - complete snapshots or encoded into a text representation, both 12.148 - of which are wasteful approaches. Mercurial can efficiently 12.149 - handle deltas of files with arbitrary binary contents; it 12.150 - doesn't need to treat text as special.</para> 12.151 - 12.152 - </sect2> 12.153 - <sect2 id="sec:concepts:txn"> 12.154 - <title>Safe operation</title> 12.155 - 12.156 - <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to 12.157 - the end of a revlog file. It never modifies a section of a 12.158 - file after it has written it. This is both more robust and 12.159 - efficient than schemes that need to modify or rewrite 12.160 - data.</para> 12.161 - 12.162 - <para id="x_2f8">In addition, Mercurial treats every write as part of a 12.163 - <emphasis>transaction</emphasis> that can span a number of 12.164 - files. A transaction is <emphasis>atomic</emphasis>: either 12.165 - the entire transaction succeeds and its effects are all 12.166 - visible to readers in one go, or the whole thing is undone. 12.167 - This guarantee of atomicity means that if you're running two 12.168 - copies of Mercurial, where one is reading data and one is 12.169 - writing it, the reader will never see a partially written 12.170 - result that might confuse it.</para> 12.171 - 12.172 - <para id="x_2f9">The fact that Mercurial only appends to files makes it 12.173 - easier to provide this transactional guarantee. The easier it 12.174 - is to do stuff like this, the more confident you should be 12.175 - that it's done correctly.</para> 12.176 - 12.177 - </sect2> 12.178 - <sect2> 12.179 - <title>Fast retrieval</title> 12.180 - 12.181 - <para id="x_2fa">Mercurial cleverly avoids a pitfall common to all earlier 12.182 - revision control systems: the problem of <emphasis>inefficient 12.183 - retrieval</emphasis>. Most revision control systems store 12.184 - the contents of a revision as an incremental series of 12.185 - modifications against a <quote>snapshot</quote>. To 12.186 - reconstruct a specific revision, you must first read the 12.187 - snapshot, and then every one of the revisions between the 12.188 - snapshot and your target revision. The more history that a 12.189 - file accumulates, the more revisions you must read, hence the 12.190 - longer it takes to reconstruct a particular revision.</para> 12.191 - 12.192 - <figure id="fig:concepts:snapshot"> 12.193 - <title>Snapshot of a revlog, with incremental deltas</title> 12.194 - <mediaobject> 12.195 - <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject> 12.196 - <textobject><phrase>XXX add text</phrase></textobject> 12.197 - </mediaobject> 12.198 - </figure> 12.199 - 12.200 - <para id="x_2fc">The innovation that Mercurial applies to this problem is 12.201 - simple but effective. Once the cumulative amount of delta 12.202 - information stored since the last snapshot exceeds a fixed 12.203 - threshold, it stores a new snapshot (compressed, of course), 12.204 - instead of another delta. This makes it possible to 12.205 - reconstruct <emphasis>any</emphasis> revision of a file 12.206 - quickly. This approach works so well that it has since been 12.207 - copied by several other revision control systems.</para> 12.208 - 12.209 - <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates 12.210 - the idea. In an entry in a revlog's index file, Mercurial 12.211 - stores the range of entries from the data file that it must 12.212 - read to reconstruct a particular revision.</para> 12.213 - 12.214 - <sect3> 12.215 - <title>Aside: the influence of video compression</title> 12.216 - 12.217 - <para id="x_2fe">If you're familiar with video compression or have ever 12.218 - watched a TV feed through a digital cable or satellite 12.219 - service, you may know that most video compression schemes 12.220 - store each frame of video as a delta against its predecessor 12.221 - frame. In addition, these schemes use <quote>lossy</quote> 12.222 - compression techniques to increase the compression ratio, so 12.223 - visual errors accumulate over the course of a number of 12.224 - inter-frame deltas.</para> 12.225 - 12.226 - <para id="x_2ff">Because it's possible for a video stream to <quote>drop 12.227 - out</quote> occasionally due to signal glitches, and to 12.228 - limit the accumulation of artefacts introduced by the lossy 12.229 - compression process, video encoders periodically insert a 12.230 - complete frame (called a <quote>key frame</quote>) into the 12.231 - video stream; the next delta is generated against that 12.232 - frame. This means that if the video signal gets 12.233 - interrupted, it will resume once the next key frame is 12.234 - received. Also, the accumulation of encoding errors 12.235 - restarts anew with each key frame.</para> 12.236 - 12.237 - </sect3> 12.238 - </sect2> 12.239 - <sect2> 12.240 - <title>Identification and strong integrity</title> 12.241 - 12.242 - <para id="x_300">Along with delta or snapshot information, a revlog entry 12.243 - contains a cryptographic hash of the data that it represents. 12.244 - This makes it difficult to forge the contents of a revision, 12.245 - and easy to detect accidental corruption.</para> 12.246 - 12.247 - <para id="x_301">Hashes provide more than a mere check against corruption; 12.248 - they are used as the identifiers for revisions. The changeset 12.249 - identification hashes that you see as an end user are from 12.250 - revisions of the changelog. Although filelogs and the 12.251 - manifest also use hashes, Mercurial only uses these behind the 12.252 - scenes.</para> 12.253 - 12.254 - <para id="x_302">Mercurial verifies that hashes are correct when it 12.255 - retrieves file revisions and when it pulls changes from 12.256 - another repository. If it encounters an integrity problem, it 12.257 - will complain and stop whatever it's doing.</para> 12.258 - 12.259 - <para id="x_303">In addition to the effect it has on retrieval efficiency, 12.260 - Mercurial's use of periodic snapshots makes it more robust 12.261 - against partial data corruption. If a revlog becomes partly 12.262 - corrupted due to a hardware error or system bug, it's often 12.263 - possible to reconstruct some or most revisions from the 12.264 - uncorrupted sections of the revlog, both before and after the 12.265 - corrupted section. This would not be possible with a 12.266 - delta-only storage model.</para> 12.267 - 12.268 - </sect2> 12.269 - </sect1> 12.270 - <sect1> 12.271 - <title>Revision history, branching, and merging</title> 12.272 - 12.273 - <para id="x_304">Every entry in a Mercurial revlog knows the identity of its 12.274 - immediate ancestor revision, usually referred to as its 12.275 - <emphasis>parent</emphasis>. In fact, a revision contains room 12.276 - for not one parent, but two. Mercurial uses a special hash, 12.277 - called the <quote>null ID</quote>, to represent the idea 12.278 - <quote>there is no parent here</quote>. This hash is simply a 12.279 - string of zeroes.</para> 12.280 - 12.281 - <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see 12.282 - an example of the conceptual structure of a revlog. Filelogs, 12.283 - manifests, and changelogs all have this same structure; they 12.284 - differ only in the kind of data stored in each delta or 12.285 - snapshot.</para> 12.286 - 12.287 - <para id="x_306">The first revision in a revlog (at the bottom of the image) 12.288 - has the null ID in both of its parent slots. For a 12.289 - <quote>normal</quote> revision, its first parent slot contains 12.290 - the ID of its parent revision, and its second contains the null 12.291 - ID, indicating that the revision has only one real parent. Any 12.292 - two revisions that have the same parent ID are branches. A 12.293 - revision that represents a merge between branches has two normal 12.294 - revision IDs in its parent slots.</para> 12.295 - 12.296 - <figure id="fig:concepts:revlog"> 12.297 - <title>The conceptual structure of a revlog</title> 12.298 - <mediaobject> 12.299 - <imageobject><imagedata fileref="figs/revlog.png"/></imageobject> 12.300 - <textobject><phrase>XXX add text</phrase></textobject> 12.301 - </mediaobject> 12.302 - </figure> 12.303 - 12.304 - </sect1> 12.305 - <sect1> 12.306 - <title>The working directory</title> 12.307 - 12.308 - <para id="x_307">In the working directory, Mercurial stores a snapshot of the 12.309 - files from the repository as of a particular changeset.</para> 12.310 - 12.311 - <para id="x_308">The working directory <quote>knows</quote> which changeset 12.312 - it contains. When you update the working directory to contain a 12.313 - particular changeset, Mercurial looks up the appropriate 12.314 - revision of the manifest to find out which files it was tracking 12.315 - at the time that changeset was committed, and which revision of 12.316 - each file was then current. It then recreates a copy of each of 12.317 - those files, with the same contents it had when the changeset 12.318 - was committed.</para> 12.319 - 12.320 - <para id="x_309">The <emphasis>dirstate</emphasis> contains Mercurial's 12.321 - knowledge of the working directory. This details which 12.322 - changeset the working directory is updated to, and all of the 12.323 - files that Mercurial is tracking in the working 12.324 - directory.</para> 12.325 - 12.326 - <para id="x_30a">Just as a revision of a revlog has room for two parents, so 12.327 - that it can represent either a normal revision (with one parent) 12.328 - or a merge of two earlier revisions, the dirstate has slots for 12.329 - two parents. When you use the <command role="hg-cmd">hg 12.330 - update</command> command, the changeset that you update to is 12.331 - stored in the <quote>first parent</quote> slot, and the null ID 12.332 - in the second. When you <command role="hg-cmd">hg 12.333 - merge</command> with another changeset, the first parent 12.334 - remains unchanged, and the second parent is filled in with the 12.335 - changeset you're merging with. The <command role="hg-cmd">hg 12.336 - parents</command> command tells you what the parents of the 12.337 - dirstate are.</para> 12.338 - 12.339 - <sect2> 12.340 - <title>What happens when you commit</title> 12.341 - 12.342 - <para id="x_30b">The dirstate stores parent information for more than just 12.343 - book-keeping purposes. Mercurial uses the parents of the 12.344 - dirstate as <emphasis>the parents of a new 12.345 - changeset</emphasis> when you perform a commit.</para> 12.346 - 12.347 - <figure id="fig:concepts:wdir"> 12.348 - <title>The working directory can have two parents</title> 12.349 - <mediaobject> 12.350 - <imageobject><imagedata fileref="figs/wdir.png"/></imageobject> 12.351 - <textobject><phrase>XXX add text</phrase></textobject> 12.352 - </mediaobject> 12.353 - </figure> 12.354 - 12.355 - <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the 12.356 - normal state of the working directory, where it has a single 12.357 - changeset as parent. That changeset is the 12.358 - <emphasis>tip</emphasis>, the newest changeset in the 12.359 - repository that has no children.</para> 12.360 - 12.361 - <figure id="fig:concepts:wdir-after-commit"> 12.362 - <title>The working directory gains new parents after a 12.363 - commit</title> 12.364 - <mediaobject> 12.365 - <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject> 12.366 - <textobject><phrase>XXX add text</phrase></textobject> 12.367 - </mediaobject> 12.368 - </figure> 12.369 - 12.370 - <para id="x_30f">It's useful to think of the working directory as 12.371 - <quote>the changeset I'm about to commit</quote>. Any files 12.372 - that you tell Mercurial that you've added, removed, renamed, 12.373 - or copied will be reflected in that changeset, as will 12.374 - modifications to any files that Mercurial is already tracking; 12.375 - the new changeset will have the parents of the working 12.376 - directory as its parents.</para> 12.377 - 12.378 - <para id="x_310">After a commit, Mercurial will update the 12.379 - parents of the working directory, so that the first parent is 12.380 - the ID of the new changeset, and the second is the null ID. 12.381 - This is shown in <xref 12.382 - linkend="fig:concepts:wdir-after-commit"/>. Mercurial 12.383 - doesn't touch any of the files in the working directory when 12.384 - you commit; it just modifies the dirstate to note its new 12.385 - parents.</para> 12.386 - 12.387 - </sect2> 12.388 - <sect2> 12.389 - <title>Creating a new head</title> 12.390 - 12.391 - <para id="x_311">It's perfectly normal to update the working directory to a 12.392 - changeset other than the current tip. For example, you might 12.393 - want to know what your project looked like last Tuesday, or 12.394 - you could be looking through changesets to see which one 12.395 - introduced a bug. In cases like this, the natural thing to do 12.396 - is update the working directory to the changeset you're 12.397 - interested in, and then examine the files in the working 12.398 - directory directly to see their contents as they were when you 12.399 - committed that changeset. The effect of this is shown in 12.400 - <xref linkend="fig:concepts:wdir-pre-branch"/>.</para> 12.401 - 12.402 - <figure id="fig:concepts:wdir-pre-branch"> 12.403 - <title>The working directory, updated to an older 12.404 - changeset</title> 12.405 - <mediaobject> 12.406 - <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject> 12.407 - <textobject><phrase>XXX add text</phrase></textobject> 12.408 - </mediaobject> 12.409 - </figure> 12.410 - 12.411 - <para id="x_313">Having updated the working directory to an 12.412 - older changeset, what happens if you make some changes, and 12.413 - then commit? Mercurial behaves in the same way as I outlined 12.414 - above. The parents of the working directory become the 12.415 - parents of the new changeset. This new changeset has no 12.416 - children, so it becomes the new tip. And the repository now 12.417 - contains two changesets that have no children; we call these 12.418 - <emphasis>heads</emphasis>. You can see the structure that 12.419 - this creates in <xref 12.420 - linkend="fig:concepts:wdir-branch"/>.</para> 12.421 - 12.422 - <figure id="fig:concepts:wdir-branch"> 12.423 - <title>After a commit made while synced to an older 12.424 - changeset</title> 12.425 - <mediaobject> 12.426 - <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject> 12.427 - <textobject><phrase>XXX add text</phrase></textobject> 12.428 - </mediaobject> 12.429 - </figure> 12.430 - 12.431 - <note> 12.432 - <para id="x_315"> If you're new to Mercurial, you should keep in mind a 12.433 - common <quote>error</quote>, which is to use the <command 12.434 - role="hg-cmd">hg pull</command> command without any 12.435 - options. By default, the <command role="hg-cmd">hg 12.436 - pull</command> command <emphasis>does not</emphasis> 12.437 - update the working directory, so you'll bring new changesets 12.438 - into your repository, but the working directory will stay 12.439 - synced at the same changeset as before the pull. If you 12.440 - make some changes and commit afterwards, you'll thus create 12.441 - a new head, because your working directory isn't synced to 12.442 - whatever the current tip is.</para> 12.443 - 12.444 - <para id="x_316"> I put the word <quote>error</quote> in 12.445 - quotes because all that you need to do to rectify this 12.446 - situation is <command role="hg-cmd">hg merge</command>, then 12.447 - <command role="hg-cmd">hg commit</command>. In other words, 12.448 - this almost never has negative consequences; it's just 12.449 - something of a surprise for newcomers. I'll discuss other 12.450 - ways to avoid this behavior, and why Mercurial behaves in 12.451 - this initially surprising way, later on.</para> 12.452 - </note> 12.453 - 12.454 - </sect2> 12.455 - <sect2> 12.456 - <title>Merging changes</title> 12.457 - 12.458 - <para id="x_317">When you run the <command role="hg-cmd">hg 12.459 - merge</command> command, Mercurial leaves the first parent 12.460 - of the working directory unchanged, and sets the second parent 12.461 - to the changeset you're merging with, as shown in <xref 12.462 - linkend="fig:concepts:wdir-merge"/>.</para> 12.463 - 12.464 - <figure id="fig:concepts:wdir-merge"> 12.465 - <title>Merging two heads</title> 12.466 - <mediaobject> 12.467 - <imageobject> 12.468 - <imagedata fileref="figs/wdir-merge.png"/> 12.469 - </imageobject> 12.470 - <textobject><phrase>XXX add text</phrase></textobject> 12.471 - </mediaobject> 12.472 - </figure> 12.473 - 12.474 - <para id="x_319">Mercurial also has to modify the working directory, to 12.475 - merge the files managed in the two changesets. Simplified a 12.476 - little, the merging process goes like this, for every file in 12.477 - the manifests of both changesets.</para> 12.478 - <itemizedlist> 12.479 - <listitem><para id="x_31a">If neither changeset has modified a file, do 12.480 - nothing with that file.</para> 12.481 - </listitem> 12.482 - <listitem><para id="x_31b">If one changeset has modified a file, and the 12.483 - other hasn't, create the modified copy of the file in the 12.484 - working directory.</para> 12.485 - </listitem> 12.486 - <listitem><para id="x_31c">If one changeset has removed a file, and the 12.487 - other hasn't (or has also deleted it), delete the file 12.488 - from the working directory.</para> 12.489 - </listitem> 12.490 - <listitem><para id="x_31d">If one changeset has removed a file, but the 12.491 - other has modified the file, ask the user what to do: keep 12.492 - the modified file, or remove it?</para> 12.493 - </listitem> 12.494 - <listitem><para id="x_31e">If both changesets have modified a file, 12.495 - invoke an external merge program to choose the new 12.496 - contents for the merged file. This may require input from 12.497 - the user.</para> 12.498 - </listitem> 12.499 - <listitem><para id="x_31f">If one changeset has modified a file, and the 12.500 - other has renamed or copied the file, make sure that the 12.501 - changes follow the new name of the file.</para> 12.502 - </listitem></itemizedlist> 12.503 - <para id="x_320">There are more details&emdash;merging has plenty of corner 12.504 - cases&emdash;but these are the most common choices that are 12.505 - involved in a merge. As you can see, most cases are 12.506 - completely automatic, and indeed most merges finish 12.507 - automatically, without requiring your input to resolve any 12.508 - conflicts.</para> 12.509 - 12.510 - <para id="x_321">When you're thinking about what happens when you commit 12.511 - after a merge, once again the working directory is <quote>the 12.512 - changeset I'm about to commit</quote>. After the <command 12.513 - role="hg-cmd">hg merge</command> command completes, the 12.514 - working directory has two parents; these will become the 12.515 - parents of the new changeset.</para> 12.516 - 12.517 - <para id="x_322">Mercurial lets you perform multiple merges, but you must 12.518 - commit the results of each individual merge as you go. This 12.519 - is necessary because Mercurial only tracks two parents for 12.520 - both revisions and the working directory. While it would be 12.521 - technically possible to merge multiple changesets at once, the 12.522 - prospect of user confusion and making a terrible mess of a 12.523 - merge immediately becomes overwhelming.</para> 12.524 - 12.525 - </sect2> 12.526 - 12.527 - <sect2> 12.528 - <title>Merging and renames</title> 12.529 - 12.530 - <para id="x_69a">A surprising number of revision control systems pay little 12.531 - or no attention to a file's <emphasis>name</emphasis> over 12.532 - time. For instance, it used to be common that if a file got 12.533 - renamed on one side of a merge, the changes from the other 12.534 - side would be silently dropped.</para> 12.535 - 12.536 - <para id="x_69b">Mercurial records metadata when you tell it to perform a 12.537 - rename or copy. It uses this metadata during a merge to do the 12.538 - right thing in the case of a merge. For instance, if I rename 12.539 - a file, and you edit it without renaming it, when we merge our 12.540 - work the file will be renamed and have your edits 12.541 - applied.</para> 12.542 - </sect2> 12.543 - </sect1> 12.544 - 12.545 - <sect1> 12.546 - <title>Other interesting design features</title> 12.547 - 12.548 - <para id="x_323">In the sections above, I've tried to highlight some of the 12.549 - most important aspects of Mercurial's design, to illustrate that 12.550 - it pays careful attention to reliability and performance. 12.551 - However, the attention to detail doesn't stop there. There are 12.552 - a number of other aspects of Mercurial's construction that I 12.553 - personally find interesting. I'll detail a few of them here, 12.554 - separate from the <quote>big ticket</quote> items above, so that 12.555 - if you're interested, you can gain a better idea of the amount 12.556 - of thinking that goes into a well-designed system.</para> 12.557 - 12.558 - <sect2> 12.559 - <title>Clever compression</title> 12.560 - 12.561 - <para id="x_324">When appropriate, Mercurial will store both snapshots and 12.562 - deltas in compressed form. It does this by always 12.563 - <emphasis>trying to</emphasis> compress a snapshot or delta, 12.564 - but only storing the compressed version if it's smaller than 12.565 - the uncompressed version.</para> 12.566 - 12.567 - <para id="x_325">This means that Mercurial does <quote>the right 12.568 - thing</quote> when storing a file whose native form is 12.569 - compressed, such as a <literal>zip</literal> archive or a JPEG 12.570 - image. When these types of files are compressed a second 12.571 - time, the resulting file is usually bigger than the 12.572 - once-compressed form, and so Mercurial will store the plain 12.573 - <literal>zip</literal> or JPEG.</para> 12.574 - 12.575 - <para id="x_326">Deltas between revisions of a compressed file are usually 12.576 - larger than snapshots of the file, and Mercurial again does 12.577 - <quote>the right thing</quote> in these cases. It finds that 12.578 - such a delta exceeds the threshold at which it should store a 12.579 - complete snapshot of the file, so it stores the snapshot, 12.580 - again saving space compared to a naive delta-only 12.581 - approach.</para> 12.582 - 12.583 - <sect3> 12.584 - <title>Network recompression</title> 12.585 - 12.586 - <para id="x_327">When storing revisions on disk, Mercurial uses the 12.587 - <quote>deflate</quote> compression algorithm (the same one 12.588 - used by the popular <literal>zip</literal> archive format), 12.589 - which balances good speed with a respectable compression 12.590 - ratio. However, when transmitting revision data over a 12.591 - network connection, Mercurial uncompresses the compressed 12.592 - revision data.</para> 12.593 - 12.594 - <para id="x_328">If the connection is over HTTP, Mercurial recompresses 12.595 - the entire stream of data using a compression algorithm that 12.596 - gives a better compression ratio (the Burrows-Wheeler 12.597 - algorithm from the widely used <literal>bzip2</literal> 12.598 - compression package). This combination of algorithm and 12.599 - compression of the entire stream (instead of a revision at a 12.600 - time) substantially reduces the number of bytes to be 12.601 - transferred, yielding better network performance over most 12.602 - kinds of network.</para> 12.603 - 12.604 - <para id="x_329">(If the connection is over <command>ssh</command>, 12.605 - Mercurial <emphasis>doesn't</emphasis> recompress the 12.606 - stream, because <command>ssh</command> can already do this 12.607 - itself.)</para> 12.608 - 12.609 - </sect3> 12.610 - </sect2> 12.611 - <sect2> 12.612 - <title>Read/write ordering and atomicity</title> 12.613 - 12.614 - <para id="x_32a">Appending to files isn't the whole story when 12.615 - it comes to guaranteeing that a reader won't see a partial 12.616 - write. If you recall <xref linkend="fig:concepts:metadata"/>, 12.617 - revisions in 12.618 - the changelog point to revisions in the manifest, and 12.619 - revisions in the manifest point to revisions in filelogs. 12.620 - This hierarchy is deliberate.</para> 12.621 - 12.622 - <para id="x_32b">A writer starts a transaction by writing filelog and 12.623 - manifest data, and doesn't write any changelog data until 12.624 - those are finished. A reader starts by reading changelog 12.625 - data, then manifest data, followed by filelog data.</para> 12.626 - 12.627 - <para id="x_32c">Since the writer has always finished writing filelog and 12.628 - manifest data before it writes to the changelog, a reader will 12.629 - never read a pointer to a partially written manifest revision 12.630 - from the changelog, and it will never read a pointer to a 12.631 - partially written filelog revision from the manifest.</para> 12.632 - 12.633 - </sect2> 12.634 - <sect2> 12.635 - <title>Concurrent access</title> 12.636 - 12.637 - <para id="x_32d">The read/write ordering and atomicity guarantees mean that 12.638 - Mercurial never needs to <emphasis>lock</emphasis> a 12.639 - repository when it's reading data, even if the repository is 12.640 - being written to while the read is occurring. This has a big 12.641 - effect on scalability; you can have an arbitrary number of 12.642 - Mercurial processes safely reading data from a repository 12.643 - safely all at once, no matter whether it's being written to or 12.644 - not.</para> 12.645 - 12.646 - <para id="x_32e">The lockless nature of reading means that if you're 12.647 - sharing a repository on a multi-user system, you don't need to 12.648 - grant other local users permission to 12.649 - <emphasis>write</emphasis> to your repository in order for 12.650 - them to be able to clone it or pull changes from it; they only 12.651 - need <emphasis>read</emphasis> permission. (This is 12.652 - <emphasis>not</emphasis> a common feature among revision 12.653 - control systems, so don't take it for granted! Most require 12.654 - readers to be able to lock a repository to access it safely, 12.655 - and this requires write permission on at least one directory, 12.656 - which of course makes for all kinds of nasty and annoying 12.657 - security and administrative problems.)</para> 12.658 - 12.659 - <para id="x_32f">Mercurial uses locks to ensure that only one process can 12.660 - write to a repository at a time (the locking mechanism is safe 12.661 - even over filesystems that are notoriously hostile to locking, 12.662 - such as NFS). If a repository is locked, a writer will wait 12.663 - for a while to retry if the repository becomes unlocked, but 12.664 - if the repository remains locked for too long, the process 12.665 - attempting to write will time out after a while. This means 12.666 - that your daily automated scripts won't get stuck forever and 12.667 - pile up if a system crashes unnoticed, for example. (Yes, the 12.668 - timeout is configurable, from zero to infinity.)</para> 12.669 - 12.670 - <sect3> 12.671 - <title>Safe dirstate access</title> 12.672 - 12.673 - <para id="x_330">As with revision data, Mercurial doesn't take a lock to 12.674 - read the dirstate file; it does acquire a lock to write it. 12.675 - To avoid the possibility of reading a partially written copy 12.676 - of the dirstate file, Mercurial writes to a file with a 12.677 - unique name in the same directory as the dirstate file, then 12.678 - renames the temporary file atomically to 12.679 - <filename>dirstate</filename>. The file named 12.680 - <filename>dirstate</filename> is thus guaranteed to be 12.681 - complete, not partially written.</para> 12.682 - 12.683 - </sect3> 12.684 - </sect2> 12.685 - <sect2> 12.686 - <title>Avoiding seeks</title> 12.687 - 12.688 - <para id="x_331">Critical to Mercurial's performance is the avoidance of 12.689 - seeks of the disk head, since any seek is far more expensive 12.690 - than even a comparatively large read operation.</para> 12.691 - 12.692 - <para id="x_332">This is why, for example, the dirstate is stored in a 12.693 - single file. If there were a dirstate file per directory that 12.694 - Mercurial tracked, the disk would seek once per directory. 12.695 - Instead, Mercurial reads the entire single dirstate file in 12.696 - one step.</para> 12.697 - 12.698 - <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme 12.699 - when cloning a repository on local storage. Instead of 12.700 - copying every revlog file from the old repository into the new 12.701 - repository, it makes a <quote>hard link</quote>, which is a 12.702 - shorthand way to say <quote>these two names point to the same 12.703 - file</quote>. When Mercurial is about to write to one of a 12.704 - revlog's files, it checks to see if the number of names 12.705 - pointing at the file is greater than one. If it is, more than 12.706 - one repository is using the file, so Mercurial makes a new 12.707 - copy of the file that is private to this repository.</para> 12.708 - 12.709 - <para id="x_334">A few revision control developers have pointed out that 12.710 - this idea of making a complete private copy of a file is not 12.711 - very efficient in its use of storage. While this is true, 12.712 - storage is cheap, and this method gives the highest 12.713 - performance while deferring most book-keeping to the operating 12.714 - system. An alternative scheme would most likely reduce 12.715 - performance and increase the complexity of the software, each 12.716 - of which is much more important to the <quote>feel</quote> of 12.717 - day-to-day use.</para> 12.718 - 12.719 - </sect2> 12.720 - <sect2> 12.721 - <title>Other contents of the dirstate</title> 12.722 - 12.723 - <para id="x_335">Because Mercurial doesn't force you to tell it when you're 12.724 - modifying a file, it uses the dirstate to store some extra 12.725 - information so it can determine efficiently whether you have 12.726 - modified a file. For each file in the working directory, it 12.727 - stores the time that it last modified the file itself, and the 12.728 - size of the file at that time.</para> 12.729 - 12.730 - <para id="x_336">When you explicitly <command role="hg-cmd">hg 12.731 - add</command>, <command role="hg-cmd">hg remove</command>, 12.732 - <command role="hg-cmd">hg rename</command> or <command 12.733 - role="hg-cmd">hg copy</command> files, Mercurial updates the 12.734 - dirstate so that it knows what to do with those files when you 12.735 - commit.</para> 12.736 - 12.737 - <para id="x_337">When Mercurial is checking the states of files in the 12.738 - working directory, it first checks a file's modification time. 12.739 - If that has not changed, the file must not have been modified. 12.740 - If the file's size has changed, the file must have been 12.741 - modified. If the modification time has changed, but the size 12.742 - has not, only then does Mercurial need to read the actual 12.743 - contents of the file to see if they've changed. Storing these 12.744 - few extra pieces of information dramatically reduces the 12.745 - amount of data that Mercurial needs to read, which yields 12.746 - large performance improvements compared to other revision 12.747 - control systems.</para> 12.748 - 12.749 - </sect2> 12.750 - </sect1> 12.751 -</chapter> 12.752 - 12.753 -<!-- 12.754 -local variables: 12.755 -sgml-parent-document: ("00book.xml" "book" "chapter") 12.756 -end: 12.757 --->
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/en/ch03-tour-merge.xml Thu May 21 14:16:17 2009 +0800 13.3 @@ -0,0 +1,454 @@ 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 id="x_338">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 id="x_339">Merging is a fundamental part of working with a distributed 13.19 + revision control tool. Here are a few cases in which the need 13.20 + to merge work arises.</para> 13.21 + <itemizedlist> 13.22 + <listitem> 13.23 + <para id="x_33a">Alice and Bob each have a personal copy of a 13.24 + repository for a project they're collaborating on. Alice 13.25 + fixes a bug in her repository; Bob adds a new feature in 13.26 + his. They want the shared repository to contain both the 13.27 + bug fix and the new feature.</para> 13.28 + </listitem> 13.29 + <listitem> 13.30 + <para id="x_33b">Cynthia frequently works on several different 13.31 + tasks for a single project at once, each safely isolated in 13.32 + its own repository. Working this way means that she often 13.33 + needs to merge one piece of her own work with 13.34 + another.</para> 13.35 + </listitem> 13.36 + </itemizedlist> 13.37 + 13.38 + <para id="x_33c">Because we need to merge often, Mercurial makes 13.39 + the process easy. Let's walk through a merge. We'll begin by 13.40 + cloning yet another repository (see how often they spring up?) 13.41 + and making a change in it.</para> 13.42 + 13.43 + &interaction.tour.merge.clone; 13.44 + 13.45 + <para id="x_33d">We should now have two copies of 13.46 + <filename>hello.c</filename> with different contents. The 13.47 + histories of the two repositories have also diverged, as 13.48 + illustrated in <xref 13.49 + linkend="fig:tour-merge:sep-repos"/>. Here is a copy of our 13.50 + file from one repository.</para> 13.51 + 13.52 + &interaction.tour.merge.cat1; 13.53 + 13.54 + <para id="x_722">And here is our slightly different version from the other 13.55 + repository.</para> 13.56 + 13.57 + &interaction.tour.merge.cat2; 13.58 + 13.59 + <figure id="fig:tour-merge:sep-repos"> 13.60 + <title>Divergent recent histories of the <filename 13.61 + class="directory">my-hello</filename> and <filename 13.62 + class="directory">my-new-hello</filename> 13.63 + repositories</title> 13.64 + <mediaobject> 13.65 + <imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject> 13.66 + <textobject><phrase>XXX add text</phrase></textobject> 13.67 + </mediaobject> 13.68 + </figure> 13.69 + 13.70 + <para id="x_33f">We already know that pulling changes from our <filename 13.71 + class="directory">my-hello</filename> repository will have no 13.72 + effect on the working directory.</para> 13.73 + 13.74 + &interaction.tour.merge.pull; 13.75 + 13.76 + <para id="x_340">However, the <command role="hg-cmd">hg pull</command> 13.77 + command says something about <quote>heads</quote>.</para> 13.78 + 13.79 + <sect2> 13.80 + <title>Head changesets</title> 13.81 + 13.82 + <para id="x_341">Remember that Mercurial records what the parent 13.83 + of each change is. If a change has a parent, we call it a 13.84 + child or descendant of the parent. A head is a change that 13.85 + has no children. The tip revision is thus a head, because the 13.86 + newest revision in a repository doesn't have any children. 13.87 + There are times when a repository can contain more than one 13.88 + head.</para> 13.89 + 13.90 + <figure id="fig:tour-merge:pull"> 13.91 + <title>Repository contents after pulling from <filename 13.92 + class="directory">my-hello</filename> into <filename 13.93 + class="directory">my-new-hello</filename></title> 13.94 + <mediaobject> 13.95 + <imageobject> 13.96 + <imagedata fileref="figs/tour-merge-pull.png"/> 13.97 + </imageobject> 13.98 + <textobject><phrase>XXX add text</phrase></textobject> 13.99 + </mediaobject> 13.100 + </figure> 13.101 + 13.102 + <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can 13.103 + see the effect of the pull from <filename 13.104 + class="directory">my-hello</filename> into <filename 13.105 + class="directory">my-new-hello</filename>. The history that 13.106 + was already present in <filename 13.107 + class="directory">my-new-hello</filename> is untouched, but 13.108 + a new revision has been added. By referring to <xref 13.109 + linkend="fig:tour-merge:sep-repos"/>, we can see that the 13.110 + <emphasis>changeset ID</emphasis> remains the same in the new 13.111 + repository, but the <emphasis>revision number</emphasis> has 13.112 + changed. (This, incidentally, is a fine example of why it's 13.113 + not safe to use revision numbers when discussing changesets.) 13.114 + We can view the heads in a repository using the <command 13.115 + role="hg-cmd">hg heads</command> command.</para> 13.116 + 13.117 + &interaction.tour.merge.heads; 13.118 + </sect2> 13.119 + 13.120 + <sect2> 13.121 + <title>Performing the merge</title> 13.122 + 13.123 + <para id="x_344">What happens if we try to use the normal <command 13.124 + role="hg-cmd">hg update</command> command to update to the 13.125 + new tip?</para> 13.126 + 13.127 + &interaction.tour.merge.update; 13.128 + 13.129 + <para id="x_345">Mercurial is telling us that the <command 13.130 + role="hg-cmd">hg update</command> command won't do a merge; 13.131 + it won't update the working directory when it thinks we might 13.132 + want to do a merge, unless we force it to do so. 13.133 + (Incidentally, forcing the update with <command>hg update 13.134 + -C</command> would revert any uncommitted changes in the 13.135 + working directory.)</para> 13.136 + 13.137 + <para id="x_723">To start a merge between the two heads, we use the 13.138 + <command role="hg-cmd">hg merge</command> command.</para> 13.139 + 13.140 + &interaction.tour.merge.merge; 13.141 + 13.142 + <para id="x_347">We resolve the contents of <filename>hello.c</filename> 13.143 + 13.144 +This updates the working directory so that it 13.145 + contains changes from <emphasis>both</emphasis> heads, which 13.146 + is reflected in both the output of <command role="hg-cmd">hg 13.147 + parents</command> and the contents of 13.148 + <filename>hello.c</filename>.</para> 13.149 + 13.150 + &interaction.tour.merge.parents; 13.151 + </sect2> 13.152 + 13.153 + <sect2> 13.154 + <title>Committing the results of the merge</title> 13.155 + 13.156 + <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg 13.157 + parents</command> will display two parents until we <command 13.158 + role="hg-cmd">hg commit</command> the results of the 13.159 + merge.</para> 13.160 + 13.161 + &interaction.tour.merge.commit; 13.162 + 13.163 + <para id="x_349">We now have a new tip revision; notice that it has 13.164 + <emphasis>both</emphasis> of our former heads as its parents. 13.165 + These are the same revisions that were previously displayed by 13.166 + <command role="hg-cmd">hg parents</command>.</para> 13.167 + 13.168 + &interaction.tour.merge.tip; 13.169 + 13.170 + <para id="x_34a">In <xref 13.171 + linkend="fig:tour-merge:merge"/>, you can see a 13.172 + representation of what happens to the working directory during 13.173 + the merge, and how this affects the repository when the commit 13.174 + happens. During the merge, the working directory has two 13.175 + parent changesets, and these become the parents of the new 13.176 + changeset.</para> 13.177 + 13.178 + <figure id="fig:tour-merge:merge"> 13.179 + <title>Working directory and repository during merge, and 13.180 + following commit</title> 13.181 + <mediaobject> 13.182 + <imageobject> 13.183 + <imagedata fileref="figs/tour-merge-merge.png"/> 13.184 + </imageobject> 13.185 + <textobject><phrase>XXX add text</phrase></textobject> 13.186 + </mediaobject> 13.187 + </figure> 13.188 + 13.189 + <para id="x_69c">We sometimes talk about a merge having 13.190 + <emphasis>sides</emphasis>: the left side is the first parent 13.191 + in the output of <command role="hg-cmd">hg parents</command>, 13.192 + and the right side is the second. If the working directory 13.193 + was at e.g. revision 5 before we began a merge, that revision 13.194 + will become the left side of the merge.</para> 13.195 + </sect2> 13.196 + </sect1> 13.197 + 13.198 + <sect1> 13.199 + <title>Merging conflicting changes</title> 13.200 + 13.201 + <para id="x_34b">Most merges are simple affairs, but sometimes you'll find 13.202 + yourself merging changes where each side modifies the same portions 13.203 + of the same files. Unless both modifications are identical, 13.204 + this results in a <emphasis>conflict</emphasis>, where you have 13.205 + to decide how to reconcile the different changes into something 13.206 + coherent.</para> 13.207 + 13.208 + <figure id="fig:tour-merge:conflict"> 13.209 + <title>Conflicting changes to a document</title> 13.210 + <mediaobject> 13.211 + <imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject> 13.212 + <textobject><phrase>XXX add text</phrase></textobject> 13.213 + </mediaobject> 13.214 + </figure> 13.215 + 13.216 + <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates 13.217 + an instance of two conflicting changes to a document. We 13.218 + started with a single version of the file; then we made some 13.219 + changes; while someone else made different changes to the same 13.220 + text. Our task in resolving the conflicting changes is to 13.221 + decide what the file should look like.</para> 13.222 + 13.223 + <para id="x_34e">Mercurial doesn't have a built-in facility for handling 13.224 + conflicts. Instead, it runs an external program, usually one 13.225 + that displays some kind of graphical conflict resolution 13.226 + interface. By default, Mercurial tries to find one of several 13.227 + different merging tools that are likely to be installed on your 13.228 + system. It first tries a few fully automatic merging tools; if 13.229 + these don't succeed (because the resolution process requires 13.230 + human guidance) or aren't present, it tries a few 13.231 + different graphical merging tools.</para> 13.232 + 13.233 + <para id="x_34f">It's also possible to get Mercurial to run a 13.234 + specific program or script, by setting the 13.235 + <envar>HGMERGE</envar> environment variable to the name of your 13.236 + preferred program.</para> 13.237 + 13.238 + <sect2> 13.239 + <title>Using a graphical merge tool</title> 13.240 + 13.241 + <para id="x_350">My preferred graphical merge tool is 13.242 + <command>kdiff3</command>, which I'll use to describe the 13.243 + features that are common to graphical file merging tools. You 13.244 + can see a screenshot of <command>kdiff3</command> in action in 13.245 + <xref linkend="fig:tour-merge:kdiff3"/>. The kind of 13.246 + merge it is performing is called a <emphasis>three-way 13.247 + merge</emphasis>, because there are three different versions 13.248 + of the file of interest to us. The tool thus splits the upper 13.249 + portion of the window into three panes:</para> 13.250 + <itemizedlist> 13.251 + <listitem><para id="x_351">At the left is the <emphasis>base</emphasis> 13.252 + version of the file, i.e. the most recent version from 13.253 + which the two versions we're trying to merge are 13.254 + descended.</para> 13.255 + </listitem> 13.256 + <listitem><para id="x_352">In the middle is <quote>our</quote> version of 13.257 + the file, with the contents that we modified.</para> 13.258 + </listitem> 13.259 + <listitem><para id="x_353">On the right is <quote>their</quote> version 13.260 + of the file, the one that from the changeset that we're 13.261 + trying to merge with.</para> 13.262 + </listitem></itemizedlist> 13.263 + <para id="x_354">In the pane below these is the current 13.264 + <emphasis>result</emphasis> of the merge. Our task is to 13.265 + replace all of the red text, which indicates unresolved 13.266 + conflicts, with some sensible merger of the 13.267 + <quote>ours</quote> and <quote>theirs</quote> versions of the 13.268 + file.</para> 13.269 + 13.270 + <para id="x_355">All four of these panes are <emphasis>locked 13.271 + together</emphasis>; if we scroll vertically or horizontally 13.272 + in any of them, the others are updated to display the 13.273 + corresponding sections of their respective files.</para> 13.274 + 13.275 + <figure id="fig:tour-merge:kdiff3"> 13.276 + <title>Using <command>kdiff3</command> to merge versions of a 13.277 + file</title> 13.278 + <mediaobject> 13.279 + <imageobject> 13.280 + <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject> 13.281 + <textobject> 13.282 + <phrase>XXX add text</phrase> 13.283 + </textobject> 13.284 + </mediaobject> 13.285 + </figure> 13.286 + 13.287 + <para id="x_357">For each conflicting portion of the file, we can choose to 13.288 + resolve the conflict using some combination of text from the 13.289 + base version, ours, or theirs. We can also manually edit the 13.290 + merged file at any time, in case we need to make further 13.291 + modifications.</para> 13.292 + 13.293 + <para id="x_358">There are <emphasis>many</emphasis> file merging tools 13.294 + available, too many to cover here. They vary in which 13.295 + platforms they are available for, and in their particular 13.296 + strengths and weaknesses. Most are tuned for merging files 13.297 + containing plain text, while a few are aimed at specialised 13.298 + file formats (generally XML).</para> 13.299 + </sect2> 13.300 + 13.301 + <sect2> 13.302 + <title>A worked example</title> 13.303 + 13.304 + <para id="x_359">In this example, we will reproduce the file modification 13.305 + history of <xref linkend="fig:tour-merge:conflict"/> 13.306 + above. Let's begin by creating a repository with a base 13.307 + version of our document.</para> 13.308 + 13.309 + &interaction.tour-merge-conflict.wife; 13.310 + 13.311 + <para id="x_35a">We'll clone the repository and make a change to the 13.312 + file.</para> 13.313 + 13.314 + &interaction.tour-merge-conflict.cousin; 13.315 + 13.316 + <para id="x_35b">And another clone, to simulate someone else making a 13.317 + change to the file. (This hints at the idea that it's not all 13.318 + that unusual to merge with yourself when you isolate tasks in 13.319 + separate repositories, and indeed to find and resolve 13.320 + conflicts while doing so.)</para> 13.321 + 13.322 + &interaction.tour-merge-conflict.son; 13.323 + 13.324 + <para id="x_35c">Having created two 13.325 + different versions of the file, we'll set up an environment 13.326 + suitable for running our merge.</para> 13.327 + 13.328 + &interaction.tour-merge-conflict.pull; 13.329 + 13.330 + <para id="x_35d">In this example, I'll set 13.331 + <envar>HGMERGE</envar> to tell Mercurial to use the 13.332 + non-interactive <command>merge</command> command. This is 13.333 + bundled with many Unix-like systems. (If you're following this 13.334 + example on your computer, don't bother setting 13.335 + <envar>HGMERGE</envar>. You'll get dropped into a GUI file 13.336 + merge tool instead, which is much preferable.)</para> 13.337 + 13.338 + &interaction.tour-merge-conflict.merge; 13.339 + 13.340 + <para id="x_35f">Because <command>merge</command> can't resolve the 13.341 + conflicting changes, it leaves <emphasis>merge 13.342 + markers</emphasis> inside the file that has conflicts, 13.343 + indicating which lines have conflicts, and whether they came 13.344 + from our version of the file or theirs.</para> 13.345 + 13.346 + <para id="x_360">Mercurial can tell from the way <command>merge</command> 13.347 + exits that it wasn't able to merge successfully, so it tells 13.348 + us what commands we'll need to run if we want to redo the 13.349 + merging operation. This could be useful if, for example, we 13.350 + were running a graphical merge tool and quit because we were 13.351 + confused or realised we had made a mistake.</para> 13.352 + 13.353 + <para id="x_361">If automatic or manual merges fail, there's nothing to 13.354 + prevent us from <quote>fixing up</quote> the affected files 13.355 + ourselves, and committing the results of our merge:</para> 13.356 + 13.357 + &interaction.tour-merge-conflict.commit; 13.358 + 13.359 + <note> 13.360 + <title>Where is the <command>hg resolve</command> command?</title> 13.361 + 13.362 + <para id="x_724">The <command>hg resolve</command> command was introduced 13.363 + in Mercurial 1.1, which was released in December 2008. If 13.364 + you are using an older version of Mercurial (run <command>hg 13.365 + version</command> to see), this command will not be 13.366 + present. If your version of Mercurial is older than 1.1, 13.367 + you should strongly consider upgrading to a newer version 13.368 + before trying to tackle complicated merges.</para> 13.369 + </note> 13.370 + </sect2> 13.371 + </sect1> 13.372 + 13.373 + <sect1 id="sec:tour-merge:fetch"> 13.374 + <title>Simplifying the pull-merge-commit sequence</title> 13.375 + 13.376 + <para id="x_362">The process of merging changes as outlined above is 13.377 + straightforward, but requires running three commands in 13.378 + sequence.</para> 13.379 + <programlisting>hg pull -u 13.380 +hg merge 13.381 +hg commit -m 'Merged remote changes'</programlisting> 13.382 + <para id="x_363">In the case of the final commit, you also need to enter a 13.383 + commit message, which is almost always going to be a piece of 13.384 + uninteresting <quote>boilerplate</quote> text.</para> 13.385 + 13.386 + <para id="x_364">It would be nice to reduce the number of steps needed, if 13.387 + this were possible. Indeed, Mercurial is distributed with an 13.388 + extension called <literal role="hg-ext">fetch</literal> that 13.389 + does just this.</para> 13.390 + 13.391 + <para id="x_365">Mercurial provides a flexible extension mechanism that lets 13.392 + people extend its functionality, while keeping the core of 13.393 + Mercurial small and easy to deal with. Some extensions add new 13.394 + commands that you can use from the command line, while others 13.395 + work <quote>behind the scenes,</quote> for example adding 13.396 + capabilities to Mercurial's built-in server mode.</para> 13.397 + 13.398 + <para id="x_366">The <literal role="hg-ext">fetch</literal> 13.399 + extension adds a new command called, not surprisingly, <command 13.400 + role="hg-cmd">hg fetch</command>. This extension acts as a 13.401 + combination of <command role="hg-cmd">hg pull -u</command>, 13.402 + <command role="hg-cmd">hg merge</command> and <command 13.403 + role="hg-cmd">hg commit</command>. It begins by pulling 13.404 + changes from another repository into the current repository. If 13.405 + it finds that the changes added a new head to the repository, it 13.406 + updates to the new head, begins a merge, then (if the merge 13.407 + succeeded) commits the result of the merge with an 13.408 + automatically-generated commit message. If no new heads were 13.409 + added, it updates the working directory to the new tip 13.410 + changeset.</para> 13.411 + 13.412 + <para id="x_367">Enabling the <literal 13.413 + role="hg-ext">fetch</literal> extension is easy. Edit the 13.414 + <filename role="special">.hgrc</filename> file in your home 13.415 + directory, and either go to the <literal 13.416 + role="rc-extensions">extensions</literal> section or create an 13.417 + <literal role="rc-extensions">extensions</literal> section. Then 13.418 + add a line that simply reads 13.419 + <quote><literal>fetch=</literal></quote>.</para> 13.420 + 13.421 + <programlisting>[extensions] 13.422 +fetch =</programlisting> 13.423 + 13.424 + <para id="x_368">(Normally, the right-hand side of the 13.425 + <quote><literal>=</literal></quote> would indicate where to find 13.426 + the extension, but since the <literal 13.427 + role="hg-ext">fetch</literal> extension is in the standard 13.428 + distribution, Mercurial knows where to search for it.)</para> 13.429 + </sect1> 13.430 + 13.431 + <sect1> 13.432 + <title>Renaming, copying, and merging</title> 13.433 + 13.434 + <para id="x_729">During the life of a project, we will often want to change 13.435 + the layout of its files and directories. This can be as simple 13.436 + as renaming a single file, or as complex as restructuring the 13.437 + entire hierarchy of files within the project.</para> 13.438 + 13.439 + <para id="x_72a">Mercurial supports these kinds of complex changes fluently, 13.440 + provided we tell it what we're doing. If we want to rename a 13.441 + file, we should use the <command>hg rename</command><footnote> 13.442 + <para id="x_72b">If you're a Unix user, you'll be glad to know that the 13.443 + <command>hg rename</command> command can be abbreviated as 13.444 + <command>hg mv</command>.</para> 13.445 + </footnote> command to rename it, so that Mercurial can do the 13.446 + right thing later when we merge.</para> 13.447 + 13.448 + <para id="x_72c">We will cover the use of these commands in more detail in 13.449 + <xref linkend="chap:daily.copy"/>.</para> 13.450 + </sect1> 13.451 +</chapter> 13.452 + 13.453 +<!-- 13.454 +local variables: 13.455 +sgml-parent-document: ("00book.xml" "book" "chapter") 13.456 +end: 13.457 +-->
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/en/ch04-concepts.xml Thu May 21 14:16:17 2009 +0800 14.3 @@ -0,0 +1,778 @@ 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 id="x_2e8">Unlike many revision control systems, the concepts 14.11 + upon which Mercurial is built are simple enough that it's easy to 14.12 + understand how the software really works. Knowing these details 14.13 + certainly isn't necessary, so it is certainly safe to skip this 14.14 + chapter. However, I think you will get more out of the software 14.15 + with a <quote>mental model</quote> of what's going on.</para> 14.16 + 14.17 + <para id="x_2e9">Being able to understand what's going on behind the 14.18 + scenes gives me confidence that Mercurial has been carefully 14.19 + designed to be both <emphasis>safe</emphasis> and 14.20 + <emphasis>efficient</emphasis>. And just as importantly, if it's 14.21 + easy for me to retain a good idea of what the software is doing 14.22 + when I perform a revision control task, I'm less likely to be 14.23 + surprised by its behavior.</para> 14.24 + 14.25 + <para id="x_2ea">In this chapter, we'll initially cover the core concepts 14.26 + behind Mercurial's design, then continue to discuss some of the 14.27 + interesting details of its implementation.</para> 14.28 + 14.29 + <sect1> 14.30 + <title>Mercurial's historical record</title> 14.31 + 14.32 + <sect2> 14.33 + <title>Tracking the history of a single file</title> 14.34 + 14.35 + <para id="x_2eb">When Mercurial tracks modifications to a file, it stores 14.36 + the history of that file in a metadata object called a 14.37 + <emphasis>filelog</emphasis>. Each entry in the filelog 14.38 + contains enough information to reconstruct one revision of the 14.39 + file that is being tracked. Filelogs are stored as files in 14.40 + the <filename role="special" 14.41 + class="directory">.hg/store/data</filename> directory. A 14.42 + filelog contains two kinds of information: revision data, and 14.43 + an index to help Mercurial to find a revision 14.44 + efficiently.</para> 14.45 + 14.46 + <para id="x_2ec">A file that is large, or has a lot of history, has its 14.47 + filelog stored in separate data 14.48 + (<quote><literal>.d</literal></quote> suffix) and index 14.49 + (<quote><literal>.i</literal></quote> suffix) files. For 14.50 + small files without much history, the revision data and index 14.51 + are combined in a single <quote><literal>.i</literal></quote> 14.52 + file. The correspondence between a file in the working 14.53 + directory and the filelog that tracks its history in the 14.54 + repository is illustrated in <xref 14.55 + linkend="fig:concepts:filelog"/>.</para> 14.56 + 14.57 + <figure id="fig:concepts:filelog"> 14.58 + <title>Relationships between files in working directory and 14.59 + filelogs in repository</title> 14.60 + <mediaobject> 14.61 + <imageobject><imagedata fileref="figs/filelog.png"/></imageobject> 14.62 + <textobject><phrase>XXX add text</phrase></textobject> 14.63 + </mediaobject> 14.64 + </figure> 14.65 + 14.66 + </sect2> 14.67 + <sect2> 14.68 + <title>Managing tracked files</title> 14.69 + 14.70 + <para id="x_2ee">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 id="x_2ef">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 id="x_2f0">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 id="x_2f1">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 14.105 + <xref linkend="fig:concepts:metadata"/>.</para> 14.106 + 14.107 + <figure id="fig:concepts:metadata"> 14.108 + <title>Metadata relationships</title> 14.109 + <mediaobject> 14.110 + <imageobject><imagedata fileref="figs/metadata.png"/></imageobject> 14.111 + <textobject><phrase>XXX add text</phrase></textobject> 14.112 + </mediaobject> 14.113 + </figure> 14.114 + 14.115 + <para id="x_2f3">As the illustration shows, there is 14.116 + <emphasis>not</emphasis> a <quote>one to one</quote> 14.117 + relationship between revisions in the changelog, manifest, or 14.118 + filelog. If a file that 14.119 + Mercurial tracks hasn't changed between two changesets, the 14.120 + entry for that file in the two revisions of the manifest will 14.121 + point to the same revision of its filelog<footnote> 14.122 + <para id="x_725">It is possible (though unusual) for the manifest to 14.123 + remain the same between two changesets, in which case the 14.124 + changelog entries for those changesets will point to the 14.125 + same revision of the manifest.</para> 14.126 + </footnote>.</para> 14.127 + 14.128 + </sect2> 14.129 + </sect1> 14.130 + <sect1> 14.131 + <title>Safe, efficient storage</title> 14.132 + 14.133 + <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are 14.134 + provided by a single structure called the 14.135 + <emphasis>revlog</emphasis>.</para> 14.136 + 14.137 + <sect2> 14.138 + <title>Efficient storage</title> 14.139 + 14.140 + <para id="x_2f5">The revlog provides efficient storage of revisions using a 14.141 + <emphasis>delta</emphasis> mechanism. Instead of storing a 14.142 + complete copy of a file for each revision, it stores the 14.143 + changes needed to transform an older revision into the new 14.144 + revision. For many kinds of file data, these deltas are 14.145 + typically a fraction of a percent of the size of a full copy 14.146 + of a file.</para> 14.147 + 14.148 + <para id="x_2f6">Some obsolete revision control systems can only work with 14.149 + deltas of text files. They must either store binary files as 14.150 + complete snapshots or encoded into a text representation, both 14.151 + of which are wasteful approaches. Mercurial can efficiently 14.152 + handle deltas of files with arbitrary binary contents; it 14.153 + doesn't need to treat text as special.</para> 14.154 + 14.155 + </sect2> 14.156 + <sect2 id="sec:concepts:txn"> 14.157 + <title>Safe operation</title> 14.158 + 14.159 + <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to 14.160 + the end of a revlog file. It never modifies a section of a 14.161 + file after it has written it. This is both more robust and 14.162 + efficient than schemes that need to modify or rewrite 14.163 + data.</para> 14.164 + 14.165 + <para id="x_2f8">In addition, Mercurial treats every write as part of a 14.166 + <emphasis>transaction</emphasis> that can span a number of 14.167 + files. A transaction is <emphasis>atomic</emphasis>: either 14.168 + the entire transaction succeeds and its effects are all 14.169 + visible to readers in one go, or the whole thing is undone. 14.170 + This guarantee of atomicity means that if you're running two 14.171 + copies of Mercurial, where one is reading data and one is 14.172 + writing it, the reader will never see a partially written 14.173 + result that might confuse it.</para> 14.174 + 14.175 + <para id="x_2f9">The fact that Mercurial only appends to files makes it 14.176 + easier to provide this transactional guarantee. The easier it 14.177 + is to do stuff like this, the more confident you should be 14.178 + that it's done correctly.</para> 14.179 + 14.180 + </sect2> 14.181 + <sect2> 14.182 + <title>Fast retrieval</title> 14.183 + 14.184 + <para id="x_2fa">Mercurial cleverly avoids a pitfall common to 14.185 + all earlier revision control systems: the problem of 14.186 + <emphasis>inefficient retrieval</emphasis>. Most revision 14.187 + control systems store the contents of a revision as an 14.188 + incremental series of modifications against a 14.189 + <quote>snapshot</quote>. (Some base the snapshot on the 14.190 + oldest revision, others on the newest.) To reconstruct a 14.191 + specific revision, you must first read the snapshot, and then 14.192 + every one of the revisions between the snapshot and your 14.193 + target revision. The more history that a file accumulates, 14.194 + the more revisions you must read, hence the longer it takes to 14.195 + reconstruct a particular revision.</para> 14.196 + 14.197 + <figure id="fig:concepts:snapshot"> 14.198 + <title>Snapshot of a revlog, with incremental deltas</title> 14.199 + <mediaobject> 14.200 + <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject> 14.201 + <textobject><phrase>XXX add text</phrase></textobject> 14.202 + </mediaobject> 14.203 + </figure> 14.204 + 14.205 + <para id="x_2fc">The innovation that Mercurial applies to this problem is 14.206 + simple but effective. Once the cumulative amount of delta 14.207 + information stored since the last snapshot exceeds a fixed 14.208 + threshold, it stores a new snapshot (compressed, of course), 14.209 + instead of another delta. This makes it possible to 14.210 + reconstruct <emphasis>any</emphasis> revision of a file 14.211 + quickly. This approach works so well that it has since been 14.212 + copied by several other revision control systems.</para> 14.213 + 14.214 + <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates 14.215 + the idea. In an entry in a revlog's index file, Mercurial 14.216 + stores the range of entries from the data file that it must 14.217 + read to reconstruct a particular revision.</para> 14.218 + 14.219 + <sect3> 14.220 + <title>Aside: the influence of video compression</title> 14.221 + 14.222 + <para id="x_2fe">If you're familiar with video compression or 14.223 + have ever watched a TV feed through a digital cable or 14.224 + satellite service, you may know that most video compression 14.225 + schemes store each frame of video as a delta against its 14.226 + predecessor frame.</para> 14.227 + 14.228 + <para id="x_2ff">Mercurial borrows this idea to make it 14.229 + possible to reconstruct a revision from a snapshot and a 14.230 + small number of deltas.</para> 14.231 + 14.232 + </sect3> 14.233 + </sect2> 14.234 + <sect2> 14.235 + <title>Identification and strong integrity</title> 14.236 + 14.237 + <para id="x_300">Along with delta or snapshot information, a revlog entry 14.238 + contains a cryptographic hash of the data that it represents. 14.239 + This makes it difficult to forge the contents of a revision, 14.240 + and easy to detect accidental corruption.</para> 14.241 + 14.242 + <para id="x_301">Hashes provide more than a mere check against corruption; 14.243 + they are used as the identifiers for revisions. The changeset 14.244 + identification hashes that you see as an end user are from 14.245 + revisions of the changelog. Although filelogs and the 14.246 + manifest also use hashes, Mercurial only uses these behind the 14.247 + scenes.</para> 14.248 + 14.249 + <para id="x_302">Mercurial verifies that hashes are correct when it 14.250 + retrieves file revisions and when it pulls changes from 14.251 + another repository. If it encounters an integrity problem, it 14.252 + will complain and stop whatever it's doing.</para> 14.253 + 14.254 + <para id="x_303">In addition to the effect it has on retrieval efficiency, 14.255 + Mercurial's use of periodic snapshots makes it more robust 14.256 + against partial data corruption. If a revlog becomes partly 14.257 + corrupted due to a hardware error or system bug, it's often 14.258 + possible to reconstruct some or most revisions from the 14.259 + uncorrupted sections of the revlog, both before and after the 14.260 + corrupted section. This would not be possible with a 14.261 + delta-only storage model.</para> 14.262 + </sect2> 14.263 + </sect1> 14.264 + 14.265 + <sect1> 14.266 + <title>Revision history, branching, and merging</title> 14.267 + 14.268 + <para id="x_304">Every entry in a Mercurial revlog knows the identity of its 14.269 + immediate ancestor revision, usually referred to as its 14.270 + <emphasis>parent</emphasis>. In fact, a revision contains room 14.271 + for not one parent, but two. Mercurial uses a special hash, 14.272 + called the <quote>null ID</quote>, to represent the idea 14.273 + <quote>there is no parent here</quote>. This hash is simply a 14.274 + string of zeroes.</para> 14.275 + 14.276 + <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see 14.277 + an example of the conceptual structure of a revlog. Filelogs, 14.278 + manifests, and changelogs all have this same structure; they 14.279 + differ only in the kind of data stored in each delta or 14.280 + snapshot.</para> 14.281 + 14.282 + <para id="x_306">The first revision in a revlog (at the bottom of the image) 14.283 + has the null ID in both of its parent slots. For a 14.284 + <quote>normal</quote> revision, its first parent slot contains 14.285 + the ID of its parent revision, and its second contains the null 14.286 + ID, indicating that the revision has only one real parent. Any 14.287 + two revisions that have the same parent ID are branches. A 14.288 + revision that represents a merge between branches has two normal 14.289 + revision IDs in its parent slots.</para> 14.290 + 14.291 + <figure id="fig:concepts:revlog"> 14.292 + <title>The conceptual structure of a revlog</title> 14.293 + <mediaobject> 14.294 + <imageobject><imagedata fileref="figs/revlog.png"/></imageobject> 14.295 + <textobject><phrase>XXX add text</phrase></textobject> 14.296 + </mediaobject> 14.297 + </figure> 14.298 + 14.299 + </sect1> 14.300 + <sect1> 14.301 + <title>The working directory</title> 14.302 + 14.303 + <para id="x_307">In the working directory, Mercurial stores a snapshot of the 14.304 + files from the repository as of a particular changeset.</para> 14.305 + 14.306 + <para id="x_308">The working directory <quote>knows</quote> which changeset 14.307 + it contains. When you update the working directory to contain a 14.308 + particular changeset, Mercurial looks up the appropriate 14.309 + revision of the manifest to find out which files it was tracking 14.310 + at the time that changeset was committed, and which revision of 14.311 + each file was then current. It then recreates a copy of each of 14.312 + those files, with the same contents it had when the changeset 14.313 + was committed.</para> 14.314 + 14.315 + <para id="x_309">The <emphasis>dirstate</emphasis> is a special 14.316 + structure that contains Mercurial's knowledge of the working 14.317 + directory. It is maintained as a file named 14.318 + <filename>.hg/dirstate</filename> inside a repository. The 14.319 + dirstate details which changeset the working directory is 14.320 + updated to, and all of the files that Mercurial is tracking in 14.321 + the working directory. It also lets Mercurial quickly notice 14.322 + changed files, by recording their checkout times and 14.323 + sizes.</para> 14.324 + 14.325 + <para id="x_30a">Just as a revision of a revlog has room for two parents, so 14.326 + that it can represent either a normal revision (with one parent) 14.327 + or a merge of two earlier revisions, the dirstate has slots for 14.328 + two parents. When you use the <command role="hg-cmd">hg 14.329 + update</command> command, the changeset that you update to is 14.330 + stored in the <quote>first parent</quote> slot, and the null ID 14.331 + in the second. When you <command role="hg-cmd">hg 14.332 + merge</command> with another changeset, the first parent 14.333 + remains unchanged, and the second parent is filled in with the 14.334 + changeset you're merging with. The <command role="hg-cmd">hg 14.335 + parents</command> command tells you what the parents of the 14.336 + dirstate are.</para> 14.337 + 14.338 + <sect2> 14.339 + <title>What happens when you commit</title> 14.340 + 14.341 + <para id="x_30b">The dirstate stores parent information for more than just 14.342 + book-keeping purposes. Mercurial uses the parents of the 14.343 + dirstate as <emphasis>the parents of a new 14.344 + changeset</emphasis> when you perform a commit.</para> 14.345 + 14.346 + <figure id="fig:concepts:wdir"> 14.347 + <title>The working directory can have two parents</title> 14.348 + <mediaobject> 14.349 + <imageobject><imagedata fileref="figs/wdir.png"/></imageobject> 14.350 + <textobject><phrase>XXX add text</phrase></textobject> 14.351 + </mediaobject> 14.352 + </figure> 14.353 + 14.354 + <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the 14.355 + normal state of the working directory, where it has a single 14.356 + changeset as parent. That changeset is the 14.357 + <emphasis>tip</emphasis>, the newest changeset in the 14.358 + repository that has no children.</para> 14.359 + 14.360 + <figure id="fig:concepts:wdir-after-commit"> 14.361 + <title>The working directory gains new parents after a 14.362 + commit</title> 14.363 + <mediaobject> 14.364 + <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject> 14.365 + <textobject><phrase>XXX add text</phrase></textobject> 14.366 + </mediaobject> 14.367 + </figure> 14.368 + 14.369 + <para id="x_30f">It's useful to think of the working directory as 14.370 + <quote>the changeset I'm about to commit</quote>. Any files 14.371 + that you tell Mercurial that you've added, removed, renamed, 14.372 + or copied will be reflected in that changeset, as will 14.373 + modifications to any files that Mercurial is already tracking; 14.374 + the new changeset will have the parents of the working 14.375 + directory as its parents.</para> 14.376 + 14.377 + <para id="x_310">After a commit, Mercurial will update the 14.378 + parents of the working directory, so that the first parent is 14.379 + the ID of the new changeset, and the second is the null ID. 14.380 + This is shown in <xref 14.381 + linkend="fig:concepts:wdir-after-commit"/>. Mercurial 14.382 + doesn't touch any of the files in the working directory when 14.383 + you commit; it just modifies the dirstate to note its new 14.384 + parents.</para> 14.385 + 14.386 + </sect2> 14.387 + <sect2> 14.388 + <title>Creating a new head</title> 14.389 + 14.390 + <para id="x_311">It's perfectly normal to update the working directory to a 14.391 + changeset other than the current tip. For example, you might 14.392 + want to know what your project looked like last Tuesday, or 14.393 + you could be looking through changesets to see which one 14.394 + introduced a bug. In cases like this, the natural thing to do 14.395 + is update the working directory to the changeset you're 14.396 + interested in, and then examine the files in the working 14.397 + directory directly to see their contents as they were when you 14.398 + committed that changeset. The effect of this is shown in 14.399 + <xref linkend="fig:concepts:wdir-pre-branch"/>.</para> 14.400 + 14.401 + <figure id="fig:concepts:wdir-pre-branch"> 14.402 + <title>The working directory, updated to an older 14.403 + changeset</title> 14.404 + <mediaobject> 14.405 + <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject> 14.406 + <textobject><phrase>XXX add text</phrase></textobject> 14.407 + </mediaobject> 14.408 + </figure> 14.409 + 14.410 + <para id="x_313">Having updated the working directory to an 14.411 + older changeset, what happens if you make some changes, and 14.412 + then commit? Mercurial behaves in the same way as I outlined 14.413 + above. The parents of the working directory become the 14.414 + parents of the new changeset. This new changeset has no 14.415 + children, so it becomes the new tip. And the repository now 14.416 + contains two changesets that have no children; we call these 14.417 + <emphasis>heads</emphasis>. You can see the structure that 14.418 + this creates in <xref 14.419 + linkend="fig:concepts:wdir-branch"/>.</para> 14.420 + 14.421 + <figure id="fig:concepts:wdir-branch"> 14.422 + <title>After a commit made while synced to an older 14.423 + changeset</title> 14.424 + <mediaobject> 14.425 + <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject> 14.426 + <textobject><phrase>XXX add text</phrase></textobject> 14.427 + </mediaobject> 14.428 + </figure> 14.429 + 14.430 + <note> 14.431 + <para id="x_315">If you're new to Mercurial, you should keep 14.432 + in mind a common <quote>error</quote>, which is to use the 14.433 + <command role="hg-cmd">hg pull</command> command without any 14.434 + options. By default, the <command role="hg-cmd">hg 14.435 + pull</command> command <emphasis>does not</emphasis> 14.436 + update the working directory, so you'll bring new changesets 14.437 + into your repository, but the working directory will stay 14.438 + synced at the same changeset as before the pull. If you 14.439 + make some changes and commit afterwards, you'll thus create 14.440 + a new head, because your working directory isn't synced to 14.441 + whatever the current tip is. To combine the operation of a 14.442 + pull, followed by an update, run <command>hg pull 14.443 + -u</command>.</para> 14.444 + 14.445 + <para id="x_316">I put the word <quote>error</quote> in quotes 14.446 + because all that you need to do to rectify the situation 14.447 + where you created a new head by accident is 14.448 + <command role="hg-cmd">hg merge</command>, then <command 14.449 + role="hg-cmd">hg commit</command>. In other words, this 14.450 + almost never has negative consequences; it's just something 14.451 + of a surprise for newcomers. I'll discuss other ways to 14.452 + avoid this behavior, and why Mercurial behaves in this 14.453 + initially surprising way, later on.</para> 14.454 + </note> 14.455 + 14.456 + </sect2> 14.457 + <sect2> 14.458 + <title>Merging changes</title> 14.459 + 14.460 + <para id="x_317">When you run the <command role="hg-cmd">hg 14.461 + merge</command> command, Mercurial leaves the first parent 14.462 + of the working directory unchanged, and sets the second parent 14.463 + to the changeset you're merging with, as shown in <xref 14.464 + linkend="fig:concepts:wdir-merge"/>.</para> 14.465 + 14.466 + <figure id="fig:concepts:wdir-merge"> 14.467 + <title>Merging two heads</title> 14.468 + <mediaobject> 14.469 + <imageobject> 14.470 + <imagedata fileref="figs/wdir-merge.png"/> 14.471 + </imageobject> 14.472 + <textobject><phrase>XXX add text</phrase></textobject> 14.473 + </mediaobject> 14.474 + </figure> 14.475 + 14.476 + <para id="x_319">Mercurial also has to modify the working directory, to 14.477 + merge the files managed in the two changesets. Simplified a 14.478 + little, the merging process goes like this, for every file in 14.479 + the manifests of both changesets.</para> 14.480 + <itemizedlist> 14.481 + <listitem><para id="x_31a">If neither changeset has modified a file, do 14.482 + nothing with that file.</para> 14.483 + </listitem> 14.484 + <listitem><para id="x_31b">If one changeset has modified a file, and the 14.485 + other hasn't, create the modified copy of the file in the 14.486 + working directory.</para> 14.487 + </listitem> 14.488 + <listitem><para id="x_31c">If one changeset has removed a file, and the 14.489 + other hasn't (or has also deleted it), delete the file 14.490 + from the working directory.</para> 14.491 + </listitem> 14.492 + <listitem><para id="x_31d">If one changeset has removed a file, but the 14.493 + other has modified the file, ask the user what to do: keep 14.494 + the modified file, or remove it?</para> 14.495 + </listitem> 14.496 + <listitem><para id="x_31e">If both changesets have modified a file, 14.497 + invoke an external merge program to choose the new 14.498 + contents for the merged file. This may require input from 14.499 + the user.</para> 14.500 + </listitem> 14.501 + <listitem><para id="x_31f">If one changeset has modified a file, and the 14.502 + other has renamed or copied the file, make sure that the 14.503 + changes follow the new name of the file.</para> 14.504 + </listitem></itemizedlist> 14.505 + <para id="x_320">There are more details&emdash;merging has plenty of corner 14.506 + cases&emdash;but these are the most common choices that are 14.507 + involved in a merge. As you can see, most cases are 14.508 + completely automatic, and indeed most merges finish 14.509 + automatically, without requiring your input to resolve any 14.510 + conflicts.</para> 14.511 + 14.512 + <para id="x_321">When you're thinking about what happens when you commit 14.513 + after a merge, once again the working directory is <quote>the 14.514 + changeset I'm about to commit</quote>. After the <command 14.515 + role="hg-cmd">hg merge</command> command completes, the 14.516 + working directory has two parents; these will become the 14.517 + parents of the new changeset.</para> 14.518 + 14.519 + <para id="x_322">Mercurial lets you perform multiple merges, but 14.520 + you must commit the results of each individual merge as you 14.521 + go. This is necessary because Mercurial only tracks two 14.522 + parents for both revisions and the working directory. While 14.523 + it would be technically feasible to merge multiple changesets 14.524 + at once, Mercurial avoids this for simplicity. With multi-way 14.525 + merges, the risks of user confusion, nasty conflict 14.526 + resolution, and making a terrible mess of a merge would grow 14.527 + intolerable.</para> 14.528 + 14.529 + </sect2> 14.530 + 14.531 + <sect2> 14.532 + <title>Merging and renames</title> 14.533 + 14.534 + <para id="x_69a">A surprising number of revision control systems pay little 14.535 + or no attention to a file's <emphasis>name</emphasis> over 14.536 + time. For instance, it used to be common that if a file got 14.537 + renamed on one side of a merge, the changes from the other 14.538 + side would be silently dropped.</para> 14.539 + 14.540 + <para id="x_69b">Mercurial records metadata when you tell it to perform a 14.541 + rename or copy. It uses this metadata during a merge to do the 14.542 + right thing in the case of a merge. For instance, if I rename 14.543 + a file, and you edit it without renaming it, when we merge our 14.544 + work the file will be renamed and have your edits 14.545 + applied.</para> 14.546 + </sect2> 14.547 + </sect1> 14.548 + 14.549 + <sect1> 14.550 + <title>Other interesting design features</title> 14.551 + 14.552 + <para id="x_323">In the sections above, I've tried to highlight some of the 14.553 + most important aspects of Mercurial's design, to illustrate that 14.554 + it pays careful attention to reliability and performance. 14.555 + However, the attention to detail doesn't stop there. There are 14.556 + a number of other aspects of Mercurial's construction that I 14.557 + personally find interesting. I'll detail a few of them here, 14.558 + separate from the <quote>big ticket</quote> items above, so that 14.559 + if you're interested, you can gain a better idea of the amount 14.560 + of thinking that goes into a well-designed system.</para> 14.561 + 14.562 + <sect2> 14.563 + <title>Clever compression</title> 14.564 + 14.565 + <para id="x_324">When appropriate, Mercurial will store both snapshots and 14.566 + deltas in compressed form. It does this by always 14.567 + <emphasis>trying to</emphasis> compress a snapshot or delta, 14.568 + but only storing the compressed version if it's smaller than 14.569 + the uncompressed version.</para> 14.570 + 14.571 + <para id="x_325">This means that Mercurial does <quote>the right 14.572 + thing</quote> when storing a file whose native form is 14.573 + compressed, such as a <literal>zip</literal> archive or a JPEG 14.574 + image. When these types of files are compressed a second 14.575 + time, the resulting file is usually bigger than the 14.576 + once-compressed form, and so Mercurial will store the plain 14.577 + <literal>zip</literal> or JPEG.</para> 14.578 + 14.579 + <para id="x_326">Deltas between revisions of a compressed file are usually 14.580 + larger than snapshots of the file, and Mercurial again does 14.581 + <quote>the right thing</quote> in these cases. It finds that 14.582 + such a delta exceeds the threshold at which it should store a 14.583 + complete snapshot of the file, so it stores the snapshot, 14.584 + again saving space compared to a naive delta-only 14.585 + approach.</para> 14.586 + 14.587 + <sect3> 14.588 + <title>Network recompression</title> 14.589 + 14.590 + <para id="x_327">When storing revisions on disk, Mercurial uses the 14.591 + <quote>deflate</quote> compression algorithm (the same one 14.592 + used by the popular <literal>zip</literal> archive format), 14.593 + which balances good speed with a respectable compression 14.594 + ratio. However, when transmitting revision data over a 14.595 + network connection, Mercurial uncompresses the compressed 14.596 + revision data.</para> 14.597 + 14.598 + <para id="x_328">If the connection is over HTTP, Mercurial recompresses 14.599 + the entire stream of data using a compression algorithm that 14.600 + gives a better compression ratio (the Burrows-Wheeler 14.601 + algorithm from the widely used <literal>bzip2</literal> 14.602 + compression package). This combination of algorithm and 14.603 + compression of the entire stream (instead of a revision at a 14.604 + time) substantially reduces the number of bytes to be 14.605 + transferred, yielding better network performance over most 14.606 + kinds of network.</para> 14.607 + 14.608 + <para id="x_329">If the connection is over 14.609 + <command>ssh</command>, Mercurial 14.610 + <emphasis>doesn't</emphasis> recompress the stream, because 14.611 + <command>ssh</command> can already do this itself. You can 14.612 + tell Mercurial to always use <command>ssh</command>'s 14.613 + compression feature by editing the 14.614 + <filename>.hgrc</filename> file in your home directory as 14.615 + follows.</para> 14.616 + 14.617 + <programlisting>[ui] 14.618 +ssh = ssh -C</programlisting> 14.619 + 14.620 + </sect3> 14.621 + </sect2> 14.622 + <sect2> 14.623 + <title>Read/write ordering and atomicity</title> 14.624 + 14.625 + <para id="x_32a">Appending to files isn't the whole story when 14.626 + it comes to guaranteeing that a reader won't see a partial 14.627 + write. If you recall <xref linkend="fig:concepts:metadata"/>, 14.628 + revisions in the changelog point to revisions in the manifest, 14.629 + and revisions in the manifest point to revisions in filelogs. 14.630 + This hierarchy is deliberate.</para> 14.631 + 14.632 + <para id="x_32b">A writer starts a transaction by writing filelog and 14.633 + manifest data, and doesn't write any changelog data until 14.634 + those are finished. A reader starts by reading changelog 14.635 + data, then manifest data, followed by filelog data.</para> 14.636 + 14.637 + <para id="x_32c">Since the writer has always finished writing filelog and 14.638 + manifest data before it writes to the changelog, a reader will 14.639 + never read a pointer to a partially written manifest revision 14.640 + from the changelog, and it will never read a pointer to a 14.641 + partially written filelog revision from the manifest.</para> 14.642 + 14.643 + </sect2> 14.644 + <sect2> 14.645 + <title>Concurrent access</title> 14.646 + 14.647 + <para id="x_32d">The read/write ordering and atomicity guarantees mean that 14.648 + Mercurial never needs to <emphasis>lock</emphasis> a 14.649 + repository when it's reading data, even if the repository is 14.650 + being written to while the read is occurring. This has a big 14.651 + effect on scalability; you can have an arbitrary number of 14.652 + Mercurial processes safely reading data from a repository 14.653 + all at once, no matter whether it's being written to or 14.654 + not.</para> 14.655 + 14.656 + <para id="x_32e">The lockless nature of reading means that if you're 14.657 + sharing a repository on a multi-user system, you don't need to 14.658 + grant other local users permission to 14.659 + <emphasis>write</emphasis> to your repository in order for 14.660 + them to be able to clone it or pull changes from it; they only 14.661 + need <emphasis>read</emphasis> permission. (This is 14.662 + <emphasis>not</emphasis> a common feature among revision 14.663 + control systems, so don't take it for granted! Most require 14.664 + readers to be able to lock a repository to access it safely, 14.665 + and this requires write permission on at least one directory, 14.666 + which of course makes for all kinds of nasty and annoying 14.667 + security and administrative problems.)</para> 14.668 + 14.669 + <para id="x_32f">Mercurial uses locks to ensure that only one process can 14.670 + write to a repository at a time (the locking mechanism is safe 14.671 + even over filesystems that are notoriously hostile to locking, 14.672 + such as NFS). If a repository is locked, a writer will wait 14.673 + for a while to retry if the repository becomes unlocked, but 14.674 + if the repository remains locked for too long, the process 14.675 + attempting to write will time out after a while. This means 14.676 + that your daily automated scripts won't get stuck forever and 14.677 + pile up if a system crashes unnoticed, for example. (Yes, the 14.678 + timeout is configurable, from zero to infinity.)</para> 14.679 + 14.680 + <sect3> 14.681 + <title>Safe dirstate access</title> 14.682 + 14.683 + <para id="x_330">As with revision data, Mercurial doesn't take a lock to 14.684 + read the dirstate file; it does acquire a lock to write it. 14.685 + To avoid the possibility of reading a partially written copy 14.686 + of the dirstate file, Mercurial writes to a file with a 14.687 + unique name in the same directory as the dirstate file, then 14.688 + renames the temporary file atomically to 14.689 + <filename>dirstate</filename>. The file named 14.690 + <filename>dirstate</filename> is thus guaranteed to be 14.691 + complete, not partially written.</para> 14.692 + 14.693 + </sect3> 14.694 + </sect2> 14.695 + <sect2> 14.696 + <title>Avoiding seeks</title> 14.697 + 14.698 + <para id="x_331">Critical to Mercurial's performance is the avoidance of 14.699 + seeks of the disk head, since any seek is far more expensive 14.700 + than even a comparatively large read operation.</para> 14.701 + 14.702 + <para id="x_332">This is why, for example, the dirstate is stored in a 14.703 + single file. If there were a dirstate file per directory that 14.704 + Mercurial tracked, the disk would seek once per directory. 14.705 + Instead, Mercurial reads the entire single dirstate file in 14.706 + one step.</para> 14.707 + 14.708 + <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme 14.709 + when cloning a repository on local storage. Instead of 14.710 + copying every revlog file from the old repository into the new 14.711 + repository, it makes a <quote>hard link</quote>, which is a 14.712 + shorthand way to say <quote>these two names point to the same 14.713 + file</quote>. When Mercurial is about to write to one of a 14.714 + revlog's files, it checks to see if the number of names 14.715 + pointing at the file is greater than one. If it is, more than 14.716 + one repository is using the file, so Mercurial makes a new 14.717 + copy of the file that is private to this repository.</para> 14.718 + 14.719 + <para id="x_334">A few revision control developers have pointed out that 14.720 + this idea of making a complete private copy of a file is not 14.721 + very efficient in its use of storage. While this is true, 14.722 + storage is cheap, and this method gives the highest 14.723 + performance while deferring most book-keeping to the operating 14.724 + system. An alternative scheme would most likely reduce 14.725 + performance and increase the complexity of the software, but 14.726 + speed and simplicity are key to the <quote>feel</quote> of 14.727 + day-to-day use.</para> 14.728 + 14.729 + </sect2> 14.730 + <sect2> 14.731 + <title>Other contents of the dirstate</title> 14.732 + 14.733 + <para id="x_335">Because Mercurial doesn't force you to tell it when you're 14.734 + modifying a file, it uses the dirstate to store some extra 14.735 + information so it can determine efficiently whether you have 14.736 + modified a file. For each file in the working directory, it 14.737 + stores the time that it last modified the file itself, and the 14.738 + size of the file at that time.</para> 14.739 + 14.740 + <para id="x_336">When you explicitly <command role="hg-cmd">hg 14.741 + add</command>, <command role="hg-cmd">hg remove</command>, 14.742 + <command role="hg-cmd">hg rename</command> or <command 14.743 + role="hg-cmd">hg copy</command> files, Mercurial updates the 14.744 + dirstate so that it knows what to do with those files when you 14.745 + commit.</para> 14.746 + 14.747 + <para id="x_337">The dirstate helps Mercurial to efficiently 14.748 + check the status of files in a repository.</para> 14.749 + 14.750 + <itemizedlist> 14.751 + <listitem> 14.752 + <para id="x_726">When Mercurial checks the state of a file in the 14.753 + working directory, it first checks a file's modification 14.754 + time against the time in the dirstate that records when 14.755 + Mercurial last wrote the file. If the last modified time 14.756 + is the same as the time when Mercurial wrote the file, the 14.757 + file must not have been modified, so Mercurial does not 14.758 + need to check any further.</para> 14.759 + </listitem> 14.760 + <listitem> 14.761 + <para id="x_727">If the file's size has changed, the file must have 14.762 + been modified. If the modification time has changed, but 14.763 + the size has not, only then does Mercurial need to 14.764 + actually read the contents of the file to see if it has 14.765 + changed.</para> 14.766 + </listitem> 14.767 + </itemizedlist> 14.768 + 14.769 + <para id="x_728">Storing the modification time and size dramatically 14.770 + reduces the number of read operations that Mercurial needs to 14.771 + perform when we run commands like <command>hg status</command>. 14.772 + This results in large performance improvements.</para> 14.773 + </sect2> 14.774 + </sect1> 14.775 +</chapter> 14.776 + 14.777 +<!-- 14.778 +local variables: 14.779 +sgml-parent-document: ("00book.xml" "book" "chapter") 14.780 +end: 14.781 +-->
15.1 --- a/en/ch04-daily.xml Sat Apr 18 11:52:33 2009 +0800 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,682 +0,0 @@ 15.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 15.5 - 15.6 -<chapter id="chap:daily"> 15.7 - <?dbhtml filename="mercurial-in-daily-use.html"?> 15.8 - <title>Mercurial in daily use</title> 15.9 - 15.10 - <sect1> 15.11 - <title>Telling Mercurial which files to track</title> 15.12 - 15.13 - <para id="x_1a3">Mercurial does not work with files in your repository unless 15.14 - you tell it to manage them. The <command role="hg-cmd">hg 15.15 - status</command> command will tell you which files Mercurial 15.16 - doesn't know about; it uses a 15.17 - <quote><literal>?</literal></quote> to display such 15.18 - files.</para> 15.19 - 15.20 - <para id="x_1a4">To tell Mercurial to track a file, use the <command 15.21 - role="hg-cmd">hg add</command> command. Once you have added a 15.22 - file, the entry in the output of <command role="hg-cmd">hg 15.23 - status</command> for that file changes from 15.24 - <quote><literal>?</literal></quote> to 15.25 - <quote><literal>A</literal></quote>.</para> 15.26 - 15.27 - &interaction.daily.files.add; 15.28 - 15.29 - <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>, 15.30 - the files that you added before the commit will no longer be 15.31 - listed in the output of <command role="hg-cmd">hg 15.32 - status</command>. The reason for this is that by default, <command 15.33 - role="hg-cmd">hg status</command> only tells you about 15.34 - <quote>interesting</quote> files&emdash;those that you have (for 15.35 - example) modified, removed, or renamed. If you have a repository 15.36 - that contains thousands of files, you will rarely want to know 15.37 - about files that Mercurial is tracking, but that have not 15.38 - changed. (You can still get this information; we'll return to 15.39 - this later.)</para> 15.40 - 15.41 - <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it 15.42 - immediately. Instead, it will take a snapshot of the file's 15.43 - state the next time you perform a commit. It will then continue 15.44 - to track the changes you make to the file every time you commit, 15.45 - until you remove the file.</para> 15.46 - 15.47 - <sect2> 15.48 - <title>Explicit versus implicit file naming</title> 15.49 - 15.50 - <para id="x_1a7">A useful behavior that Mercurial has is that if you pass 15.51 - the name of a directory to a command, every Mercurial command 15.52 - will treat this as <quote>I want to operate on every file in 15.53 - this directory and its subdirectories</quote>.</para> 15.54 - 15.55 - &interaction.daily.files.add-dir; 15.56 - 15.57 - <para id="x_1a8">Notice in this example that Mercurial printed 15.58 - the names of the files it added, whereas it didn't do so when 15.59 - we added the file named <filename>myfile.txt</filename> in the 15.60 - earlier example.</para> 15.61 - 15.62 - <para id="x_1a9">What's going on is that in the former case, we explicitly 15.63 - named the file to add on the command line. The assumption 15.64 - that Mercurial makes in such cases is that we know what we 15.65 - are doing, and it doesn't print any output.</para> 15.66 - 15.67 - <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of 15.68 - files by giving the name of a directory, Mercurial takes the 15.69 - extra step of printing the name of each file that it does 15.70 - something with. This makes it more clear what is happening, 15.71 - and reduces the likelihood of a silent and nasty surprise. 15.72 - This behavior is common to most Mercurial commands.</para> 15.73 - </sect2> 15.74 - 15.75 - <sect2> 15.76 - <title>Mercurial tracks files, not directories</title> 15.77 - 15.78 - <para id="x_1ab">Mercurial does not track directory information. Instead, 15.79 - it tracks the path to a file. Before creating a file, it 15.80 - first creates any missing directory components of the path. 15.81 - After it deletes a file, it then deletes any empty directories 15.82 - that were in the deleted file's path. This sounds like a 15.83 - trivial distinction, but it has one minor practical 15.84 - consequence: it is not possible to represent a completely 15.85 - empty directory in Mercurial.</para> 15.86 - 15.87 - <para id="x_1ac">Empty directories are rarely useful, and there are 15.88 - unintrusive workarounds that you can use to achieve an 15.89 - appropriate effect. The developers of Mercurial thus felt 15.90 - that the complexity that would be required to manage empty 15.91 - directories was not worth the limited benefit this feature 15.92 - would bring.</para> 15.93 - 15.94 - <para id="x_1ad">If you need an empty directory in your repository, there 15.95 - are a few ways to achieve this. One is to create a directory, 15.96 - then <command role="hg-cmd">hg add</command> a 15.97 - <quote>hidden</quote> file to that directory. On Unix-like 15.98 - systems, any file name that begins with a period 15.99 - (<quote><literal>.</literal></quote>) is treated as hidden by 15.100 - most commands and GUI tools. This approach is illustrated 15.101 - below.</para> 15.102 - 15.103 -&interaction.daily.files.hidden; 15.104 - 15.105 - <para id="x_1ae">Another way to tackle a need for an empty directory is to 15.106 - simply create one in your automated build scripts before they 15.107 - will need it.</para> 15.108 - </sect2> 15.109 - </sect1> 15.110 - 15.111 - <sect1> 15.112 - <title>How to stop tracking a file</title> 15.113 - 15.114 - <para id="x_1af">Once you decide that a file no longer belongs in your 15.115 - repository, use the <command role="hg-cmd">hg remove</command> 15.116 - command. This deletes the file, and tells Mercurial to stop 15.117 - tracking it. A removed file is represented in the output of 15.118 - <command role="hg-cmd">hg status</command> with a 15.119 - <quote><literal>R</literal></quote>.</para> 15.120 - 15.121 - &interaction.daily.files.remove; 15.122 - 15.123 - <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file, 15.124 - Mercurial will no longer track changes to that file, even if you 15.125 - recreate a file with the same name in your working directory. 15.126 - If you do recreate a file with the same name and want Mercurial 15.127 - to track the new file, simply <command role="hg-cmd">hg 15.128 - add</command> it. Mercurial will know that the newly added 15.129 - file is not related to the old file of the same name.</para> 15.130 - 15.131 - <sect2> 15.132 - <title>Removing a file does not affect its history</title> 15.133 - 15.134 - <para id="x_1b1">It is important to understand that removing a file has 15.135 - only two effects.</para> 15.136 - <itemizedlist> 15.137 - <listitem><para id="x_1b2">It removes the current version of the file 15.138 - from the working directory.</para> 15.139 - </listitem> 15.140 - <listitem><para id="x_1b3">It stops Mercurial from tracking changes to 15.141 - the file, from the time of the next commit.</para> 15.142 - </listitem></itemizedlist> 15.143 - <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way 15.144 - alter the <emphasis>history</emphasis> of the file.</para> 15.145 - 15.146 - <para id="x_1b5">If you update the working directory to a 15.147 - changeset that was committed when it was still tracking a file 15.148 - that you later removed, the file will reappear in the working 15.149 - directory, with the contents it had when you committed that 15.150 - changeset. If you then update the working directory to a 15.151 - later changeset, in which the file had been removed, Mercurial 15.152 - will once again remove the file from the working 15.153 - directory.</para> 15.154 - </sect2> 15.155 - 15.156 - <sect2> 15.157 - <title>Missing files</title> 15.158 - 15.159 - <para id="x_1b6">Mercurial considers a file that you have deleted, but not 15.160 - used <command role="hg-cmd">hg remove</command> to delete, to 15.161 - be <emphasis>missing</emphasis>. A missing file is 15.162 - represented with <quote><literal>!</literal></quote> in the 15.163 - output of <command role="hg-cmd">hg status</command>. 15.164 - Mercurial commands will not generally do anything with missing 15.165 - files.</para> 15.166 - 15.167 - &interaction.daily.files.missing; 15.168 - 15.169 - <para id="x_1b7">If your repository contains a file that <command 15.170 - role="hg-cmd">hg status</command> reports as missing, and 15.171 - you want the file to stay gone, you can run <command 15.172 - role="hg-cmd">hg remove <option 15.173 - role="hg-opt-remove">--after</option></command> at any 15.174 - time later on, to tell Mercurial that you really did mean to 15.175 - remove the file.</para> 15.176 - 15.177 - &interaction.daily.files.remove-after; 15.178 - 15.179 - <para id="x_1b8">On the other hand, if you deleted the missing file by 15.180 - accident, give <command role="hg-cmd">hg revert</command> the 15.181 - name of the file to recover. It will reappear, in unmodified 15.182 - form.</para> 15.183 - 15.184 - &interaction.daily.files.recover-missing; 15.185 - </sect2> 15.186 - 15.187 - <sect2> 15.188 - <title>Aside: why tell Mercurial explicitly to remove a 15.189 - file?</title> 15.190 - 15.191 - <para id="x_1b9">You might wonder why Mercurial requires you to explicitly 15.192 - tell it that you are deleting a file. Early during the 15.193 - development of Mercurial, it let you delete a file however you 15.194 - pleased; Mercurial would notice the absence of the file 15.195 - automatically when you next ran a <command role="hg-cmd">hg 15.196 - commit</command>, and stop tracking the file. In practice, 15.197 - this made it too easy to accidentally remove a file without 15.198 - noticing.</para> 15.199 - </sect2> 15.200 - 15.201 - <sect2> 15.202 - <title>Useful shorthand&emdash;adding and removing files in one 15.203 - step</title> 15.204 - 15.205 - <para id="x_1ba">Mercurial offers a combination command, <command 15.206 - role="hg-cmd">hg addremove</command>, that adds untracked 15.207 - files and marks missing files as removed.</para> 15.208 - 15.209 - &interaction.daily.files.addremove; 15.210 - 15.211 - <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command 15.212 - also provides a <option role="hg-opt-commit">-A</option> 15.213 - option that performs this same add-and-remove, immediately 15.214 - followed by a commit.</para> 15.215 - 15.216 - &interaction.daily.files.commit-addremove; 15.217 - </sect2> 15.218 - </sect1> 15.219 - 15.220 - <sect1> 15.221 - <title>Copying files</title> 15.222 - 15.223 - <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg 15.224 - copy</command> command that lets you make a new copy of a 15.225 - file. When you copy a file using this command, Mercurial makes 15.226 - a record of the fact that the new file is a copy of the original 15.227 - file. It treats these copied files specially when you merge 15.228 - your work with someone else's.</para> 15.229 - 15.230 - <sect2> 15.231 - <title>The results of copying during a merge</title> 15.232 - 15.233 - <para id="x_1bd">What happens during a merge is that changes 15.234 - <quote>follow</quote> a copy. To best illustrate what this 15.235 - means, let's create an example. We'll start with the usual 15.236 - tiny repository that contains a single file.</para> 15.237 - 15.238 - &interaction.daily.copy.init; 15.239 - 15.240 - <para id="x_1be">We need to do some work in 15.241 - parallel, so that we'll have something to merge. So let's 15.242 - clone our repository.</para> 15.243 - 15.244 - &interaction.daily.copy.clone; 15.245 - 15.246 - <para id="x_1bf">Back in our initial repository, let's use the <command 15.247 - role="hg-cmd">hg copy</command> command to make a copy of 15.248 - the first file we created.</para> 15.249 - 15.250 - &interaction.daily.copy.copy; 15.251 - 15.252 - <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg 15.253 - status</command> command afterwards, the copied file looks 15.254 - just like a normal added file.</para> 15.255 - 15.256 - &interaction.daily.copy.status; 15.257 - 15.258 - <para id="x_1c1">But if we pass the <option 15.259 - role="hg-opt-status">-C</option> option to <command 15.260 - role="hg-cmd">hg status</command>, it prints another line of 15.261 - output: this is the file that our newly-added file was copied 15.262 - <emphasis>from</emphasis>.</para> 15.263 - 15.264 - &interaction.daily.copy.status-copy; 15.265 - 15.266 - <para id="x_1c2">Now, back in the repository we cloned, let's make a change 15.267 - in parallel. We'll add a line of content to the original file 15.268 - that we created.</para> 15.269 - 15.270 - &interaction.daily.copy.other; 15.271 - 15.272 - <para id="x_1c3">Now we have a modified <filename>file</filename> in this 15.273 - repository. When we pull the changes from the first 15.274 - repository, and merge the two heads, Mercurial will propagate 15.275 - the changes that we made locally to <filename>file</filename> 15.276 - into its copy, <filename>new-file</filename>.</para> 15.277 - 15.278 - &interaction.daily.copy.merge; 15.279 - </sect2> 15.280 - 15.281 - <sect2 id="sec:daily:why-copy"> 15.282 - <title>Why should changes follow copies?</title> 15.283 - 15.284 - <para id="x_1c4">This behavior&emdash;of changes to a file 15.285 - propagating out to copies of the file&emdash;might seem 15.286 - esoteric, but in most cases it's highly desirable.</para> 15.287 - 15.288 - <para id="x_1c5">First of all, remember that this propagation 15.289 - <emphasis>only</emphasis> happens when you merge. So if you 15.290 - <command role="hg-cmd">hg copy</command> a file, and 15.291 - subsequently modify the original file during the normal course 15.292 - of your work, nothing will happen.</para> 15.293 - 15.294 - <para id="x_1c6">The second thing to know is that modifications will only 15.295 - propagate across a copy as long as the changeset that you're 15.296 - merging changes from <emphasis>hasn't yet seen</emphasis> 15.297 - the copy.</para> 15.298 - 15.299 - <para id="x_1c7">The reason that Mercurial does this is as follows. Let's 15.300 - say I make an important bug fix in a source file, and commit 15.301 - my changes. Meanwhile, you've decided to <command 15.302 - role="hg-cmd">hg copy</command> the file in your repository, 15.303 - without knowing about the bug or having seen the fix, and you 15.304 - have started hacking on your copy of the file.</para> 15.305 - 15.306 - <para id="x_1c8">If you pulled and merged my changes, and Mercurial 15.307 - <emphasis>didn't</emphasis> propagate changes across copies, 15.308 - your new source file would now contain the bug, and unless you 15.309 - knew to propagate the bug fix by hand, the bug would 15.310 - <emphasis>remain</emphasis> in your copy of the file.</para> 15.311 - 15.312 - <para id="x_1c9">By automatically propagating the change that fixed the bug 15.313 - from the original file to the copy, Mercurial prevents this 15.314 - class of problem. To my knowledge, Mercurial is the 15.315 - <emphasis>only</emphasis> revision control system that 15.316 - propagates changes across copies like this.</para> 15.317 - 15.318 - <para id="x_1ca">Once your change history has a record that the copy and 15.319 - subsequent merge occurred, there's usually no further need to 15.320 - propagate changes from the original file to the copied file, 15.321 - and that's why Mercurial only propagates changes across copies 15.322 - at the first merge, and not afterwards.</para> 15.323 - </sect2> 15.324 - 15.325 - <sect2> 15.326 - <title>How to make changes <emphasis>not</emphasis> follow a 15.327 - copy</title> 15.328 - 15.329 - <para id="x_1cb">If, for some reason, you decide that this business of 15.330 - automatically propagating changes across copies is not for 15.331 - you, simply use your system's normal file copy command (on 15.332 - Unix-like systems, that's <command>cp</command>) to make a 15.333 - copy of a file, then <command role="hg-cmd">hg add</command> 15.334 - the new copy by hand. Before you do so, though, please do 15.335 - reread <xref linkend="sec:daily:why-copy"/>, and make 15.336 - an informed 15.337 - decision that this behavior is not appropriate to your 15.338 - specific case.</para> 15.339 - 15.340 - </sect2> 15.341 - <sect2> 15.342 - <title>Behavior of the <command role="hg-cmd">hg copy</command> 15.343 - command</title> 15.344 - 15.345 - <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command> 15.346 - command, Mercurial makes a copy of each source file as it 15.347 - currently stands in the working directory. This means that if 15.348 - you make some modifications to a file, then <command 15.349 - role="hg-cmd">hg copy</command> it without first having 15.350 - committed those changes, the new copy will also contain the 15.351 - modifications you have made up until that point. (I find this 15.352 - behavior a little counterintuitive, which is why I mention it 15.353 - here.)</para> 15.354 - 15.355 - <para id="x_1cd">The <command role="hg-cmd">hg copy</command> 15.356 - command acts similarly to the Unix <command>cp</command> 15.357 - command (you can use the <command role="hg-cmd">hg 15.358 - cp</command> alias if you prefer). We must supply two or 15.359 - more arguments, of which the last is treated as the 15.360 - <emphasis>destination</emphasis>, and all others are 15.361 - <emphasis>sources</emphasis>.</para> 15.362 - 15.363 - <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a 15.364 - single file as the source, and the destination does not exist, 15.365 - it creates a new file with that name.</para> 15.366 - 15.367 - &interaction.daily.copy.simple; 15.368 - 15.369 - <para id="x_1ce">If the destination is a directory, Mercurial copies its 15.370 - sources into that directory.</para> 15.371 - 15.372 - &interaction.daily.copy.dir-dest; 15.373 - 15.374 - <para id="x_1cf">Copying a directory is 15.375 - recursive, and preserves the directory structure of the 15.376 - source.</para> 15.377 - 15.378 - &interaction.daily.copy.dir-src; 15.379 - 15.380 - <para id="x_1d0">If the source and destination are both directories, the 15.381 - source tree is recreated in the destination directory.</para> 15.382 - 15.383 - &interaction.daily.copy.dir-src-dest; 15.384 - 15.385 - <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command> 15.386 - command, if you copy a file manually and then want Mercurial 15.387 - to know that you've copied the file, simply use the <option 15.388 - role="hg-opt-copy">--after</option> option to <command 15.389 - role="hg-cmd">hg copy</command>.</para> 15.390 - 15.391 - &interaction.daily.copy.after; 15.392 - </sect2> 15.393 - </sect1> 15.394 - 15.395 - <sect1> 15.396 - <title>Renaming files</title> 15.397 - 15.398 - <para id="x_1d2">It's rather more common to need to rename a file than to 15.399 - make a copy of it. The reason I discussed the <command 15.400 - role="hg-cmd">hg copy</command> command before talking about 15.401 - renaming files is that Mercurial treats a rename in essentially 15.402 - the same way as a copy. Therefore, knowing what Mercurial does 15.403 - when you copy a file tells you what to expect when you rename a 15.404 - file.</para> 15.405 - 15.406 - <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command> 15.407 - command, Mercurial makes a copy of each source file, then 15.408 - deletes it and marks the file as removed.</para> 15.409 - 15.410 - &interaction.daily.rename.rename; 15.411 - 15.412 - <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows 15.413 - the newly copied file as added, and the copied-from file as 15.414 - removed.</para> 15.415 - 15.416 - &interaction.daily.rename.status; 15.417 - 15.418 - <para id="x_1d5">As with the results of a <command role="hg-cmd">hg 15.419 - copy</command>, we must use the <option 15.420 - role="hg-opt-status">-C</option> option to <command 15.421 - role="hg-cmd">hg status</command> to see that the added file 15.422 - is really being tracked by Mercurial as a copy of the original, 15.423 - now removed, file.</para> 15.424 - 15.425 - &interaction.daily.rename.status-copy; 15.426 - 15.427 - <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and 15.428 - <command role="hg-cmd">hg copy</command>, you can tell Mercurial 15.429 - about a rename after the fact using the <option 15.430 - role="hg-opt-rename">--after</option> option. In most other 15.431 - respects, the behavior of the <command role="hg-cmd">hg 15.432 - rename</command> command, and the options it accepts, are 15.433 - similar to the <command role="hg-cmd">hg copy</command> 15.434 - command.</para> 15.435 - 15.436 - <para id="x_686">If you're familiar with the Unix command line, you'll be 15.437 - glad to know that <command role="hg-cmd">hg rename</command> 15.438 - command can be invoked as <command role="hg-cmd">hg 15.439 - mv</command>.</para> 15.440 - 15.441 - <sect2> 15.442 - <title>Renaming files and merging changes</title> 15.443 - 15.444 - <para id="x_1d7">Since Mercurial's rename is implemented as 15.445 - copy-and-remove, the same propagation of changes happens when 15.446 - you merge after a rename as after a copy.</para> 15.447 - 15.448 - <para id="x_1d8">If I modify a file, and you rename it to a new name, and 15.449 - then we merge our respective changes, my modifications to the 15.450 - file under its original name will be propagated into the file 15.451 - under its new name. (This is something you might expect to 15.452 - <quote>simply work,</quote> but not all revision control 15.453 - systems actually do this.)</para> 15.454 - 15.455 - <para id="x_1d9">Whereas having changes follow a copy is a feature where 15.456 - you can perhaps nod and say <quote>yes, that might be 15.457 - useful,</quote> it should be clear that having them follow a 15.458 - rename is definitely important. Without this facility, it 15.459 - would simply be too easy for changes to become orphaned when 15.460 - files are renamed.</para> 15.461 - </sect2> 15.462 - 15.463 - <sect2> 15.464 - <title>Divergent renames and merging</title> 15.465 - 15.466 - <para id="x_1da">The case of diverging names occurs when two developers 15.467 - start with a file&emdash;let's call it 15.468 - <filename>foo</filename>&emdash;in their respective 15.469 - repositories.</para> 15.470 - 15.471 - &interaction.rename.divergent.clone; 15.472 - 15.473 - <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para> 15.474 - 15.475 - &interaction.rename.divergent.rename.anne; 15.476 - 15.477 - <para id="x_1dc">Meanwhile, Bob renames it to 15.478 - <filename>quux</filename>. (Remember that <command 15.479 - role="hg-cmd">hg mv</command> is an alias for <command 15.480 - role="hg-cmd">hg rename</command>.)</para> 15.481 - 15.482 - &interaction.rename.divergent.rename.bob; 15.483 - 15.484 - <para id="x_1dd">I like to think of this as a conflict because each 15.485 - developer has expressed different intentions about what the 15.486 - file ought to be named.</para> 15.487 - 15.488 - <para id="x_1de">What do you think should happen when they merge their 15.489 - work? Mercurial's actual behavior is that it always preserves 15.490 - <emphasis>both</emphasis> names when it merges changesets that 15.491 - contain divergent renames.</para> 15.492 - 15.493 - &interaction.rename.divergent.merge; 15.494 - 15.495 - <para id="x_1df">Notice that while Mercurial warns about the divergent 15.496 - renames, it leaves it up to you to do something about the 15.497 - divergence after the merge.</para> 15.498 - </sect2> 15.499 - 15.500 - <sect2> 15.501 - <title>Convergent renames and merging</title> 15.502 - 15.503 - <para id="x_1e0">Another kind of rename conflict occurs when two people 15.504 - choose to rename different <emphasis>source</emphasis> files 15.505 - to the same <emphasis>destination</emphasis>. In this case, 15.506 - Mercurial runs its normal merge machinery, and lets you guide 15.507 - it to a suitable resolution.</para> 15.508 - </sect2> 15.509 - 15.510 - <sect2> 15.511 - <title>Other name-related corner cases</title> 15.512 - 15.513 - <para id="x_1e1">Mercurial has a longstanding bug in which it fails to 15.514 - handle a merge where one side has a file with a given name, 15.515 - while another has a directory with the same name. This is 15.516 - documented as <ulink role="hg-bug" 15.517 - url="http://www.selenic.com/mercurial/bts/issue29">issue 15.518 - 29</ulink>.</para> 15.519 - 15.520 - &interaction.issue29.go; 15.521 - 15.522 - </sect2> 15.523 - </sect1> 15.524 - 15.525 - <sect1> 15.526 - <title>Recovering from mistakes</title> 15.527 - 15.528 - <para id="x_1e2">Mercurial has some useful commands that will help you to 15.529 - recover from some common mistakes.</para> 15.530 - 15.531 - <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets 15.532 - you undo changes that you have made to your working directory. 15.533 - For example, if you <command role="hg-cmd">hg add</command> a 15.534 - file by accident, just run <command role="hg-cmd">hg 15.535 - revert</command> with the name of the file you added, and 15.536 - while the file won't be touched in any way, it won't be tracked 15.537 - for adding by Mercurial any longer, either. You can also use 15.538 - <command role="hg-cmd">hg revert</command> to get rid of 15.539 - erroneous changes to a file.</para> 15.540 - 15.541 - <para id="x_1e4">It's good to remember that the <command role="hg-cmd">hg 15.542 - revert</command> command is useful for changes that you have 15.543 - not yet committed. Once you've committed a change, if you 15.544 - decide it was a mistake, you can still do something about it, 15.545 - though your options may be more limited.</para> 15.546 - 15.547 - <para id="x_1e5">For more information about the <command 15.548 - role="hg-cmd">hg revert</command> command, and details about 15.549 - how to deal with changes you have already committed, see <xref 15.550 - linkend="chap:undo"/>.</para> 15.551 - </sect1> 15.552 - 15.553 - <sect1> 15.554 - <title>Dealing with tricky merges</title> 15.555 - 15.556 - <para id="x_687">In a complicated or large project, it's not unusual for a 15.557 - merge of two changesets to result in some headaches. Suppose 15.558 - there's a big source file that's been extensively edited by each 15.559 - side of a merge: this is almost inevitably going to result in 15.560 - conflicts, some of which can take a few tries to sort 15.561 - out.</para> 15.562 - 15.563 - <para id="x_688">Let's develop a simple case of this and see how to deal with 15.564 - it. We'll start off with a repository containing one file, and 15.565 - clone it twice.</para> 15.566 - 15.567 - &interaction.ch04-resolve.init; 15.568 - 15.569 - <para id="x_689">In one clone, we'll modify the file in one way.</para> 15.570 - 15.571 - &interaction.ch04-resolve.left; 15.572 - 15.573 - <para id="x_68a">In another, we'll modify the file differently.</para> 15.574 - 15.575 - &interaction.ch04-resolve.right; 15.576 - 15.577 - <para id="x_68b">Next, we'll pull each set of changes into our original 15.578 - repo.</para> 15.579 - 15.580 - &interaction.ch04-resolve.pull; 15.581 - 15.582 - <para id="x_68c">We expect our repository to now contain two heads.</para> 15.583 - 15.584 - &interaction.ch04-resolve.heads; 15.585 - 15.586 - <para id="x_68d">Normally, if we run <command role="hg-cmd">hg 15.587 - merge</command> at this point, it will drop us into a GUI that 15.588 - will let us manually resolve the conflicting edits to 15.589 - <filename>myfile.txt</filename>. However, to simplify things 15.590 - for presentation here, we'd like the merge to fail immediately 15.591 - instead. Here's one way we can do so.</para> 15.592 - 15.593 - &interaction.ch04-resolve.export; 15.594 - 15.595 - <para id="x_68e">We've told Mercurial's merge machinery to run the command 15.596 - <command>false</command> (which, as we desire, fails 15.597 - immediately) if it detects a merge that it can't sort out 15.598 - automatically.</para> 15.599 - 15.600 - <para id="x_68f">If we now fire up <command role="hg-cmd">hg 15.601 - merge</command>, it should grind to a halt and report a 15.602 - failure.</para> 15.603 - 15.604 - &interaction.ch04-resolve.merge; 15.605 - 15.606 - <para id="x_690">Even if we don't notice that the merge failed, Mercurial 15.607 - will prevent us from accidentally committing the result of a 15.608 - failed merge.</para> 15.609 - 15.610 - &interaction.ch04-resolve.cifail; 15.611 - 15.612 - <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in 15.613 - this case, it suggests that we use the unfamiliar <command 15.614 - role="hg-cmd">hg resolve</command> command. As usual, 15.615 - <command role="hg-cmd">hg help resolve</command> will print a 15.616 - helpful synopsis.</para> 15.617 - 15.618 - <sect2> 15.619 - <title>File resolution states</title> 15.620 - 15.621 - <para id="x_692">When a merge occurs, most files will usually remain 15.622 - unmodified. For each file where Mercurial has to do 15.623 - something, it tracks the state of the file.</para> 15.624 - 15.625 - <itemizedlist> 15.626 - <listitem> 15.627 - <para id="x_693">A <emphasis>resolved</emphasis> file has been 15.628 - successfully merged, either automatically by Mercurial or 15.629 - manually with human intervention.</para> 15.630 - </listitem> 15.631 - <listitem> 15.632 - <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged 15.633 - successfully, and needs more attention.</para> 15.634 - </listitem> 15.635 - </itemizedlist> 15.636 - 15.637 - <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the 15.638 - unresolved state after a merge, it considers the merge to have 15.639 - failed. Fortunately, we do not need to restart the entire 15.640 - merge from scratch.</para> 15.641 - 15.642 - <para id="x_696">The <option role="hg-opt-resolve">--list</option> or 15.643 - <option role="hg-opt-resolve">-l</option> option to <command 15.644 - role="hg-cmd">hg resolve</command> prints out the state of 15.645 - each merged file.</para> 15.646 - 15.647 - &interaction.ch04-resolve.list; 15.648 - 15.649 - <para id="x_697">In the output from <command role="hg-cmd">hg 15.650 - resolve</command>, a resolved file is marked with 15.651 - <literal>R</literal>, while an unresolved file is marked with 15.652 - <literal>U</literal>. If any files are listed with 15.653 - <literal>U</literal>, we know that an attempt to commit the 15.654 - results of the merge will fail.</para> 15.655 - </sect2> 15.656 - 15.657 - <sect2> 15.658 - <title>Resolving a file merge</title> 15.659 - 15.660 - <para id="x_698">We have several options to move a file from the unresolved 15.661 - into the resolved state. By far the most common is to rerun 15.662 - <command role="hg-cmd">hg resolve</command>. If we pass the 15.663 - names of individual files or directories, it will retry the 15.664 - merges of any unresolved files present in those locations. We 15.665 - can also pass the <option role="hg-opt-resolve">--all</option> 15.666 - or <option role="hg-opt-resolve">-a</option> option, which 15.667 - will retry the merges of <emphasis>all</emphasis> unresolved 15.668 - files.</para> 15.669 - 15.670 - <para id="x_699">Mercurial also lets us modify the resolution state of a 15.671 - file directly. We can manually mark a file as resolved using 15.672 - the <option role="hg-opt-resolve">--mark</option> option, or 15.673 - as unresolved using the <option 15.674 - role="hg-opt-resolve">--unmark</option> option. This allows 15.675 - us to clean up a particularly messy merge by hand, and to keep 15.676 - track of our progress with each file as we go.</para> 15.677 - </sect2> 15.678 - </sect1> 15.679 -</chapter> 15.680 - 15.681 -<!-- 15.682 -local variables: 15.683 -sgml-parent-document: ("00book.xml" "book" "chapter") 15.684 -end: 15.685 --->
16.1 --- a/en/ch05-collab.xml Sat Apr 18 11:52:33 2009 +0800 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,1575 +0,0 @@ 16.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 16.5 - 16.6 -<chapter id="cha:collab"> 16.7 - <?dbhtml filename="collaborating-with-other-people.html"?> 16.8 - <title>Collaborating with other people</title> 16.9 - 16.10 - <para id="x_44a">As a completely decentralised tool, Mercurial doesn't impose 16.11 - any policy on how people ought to work with each other. However, 16.12 - if you're new to distributed revision control, it helps to have 16.13 - some tools and examples in mind when you're thinking about 16.14 - possible workflow models.</para> 16.15 - 16.16 - <sect1> 16.17 - <title>Mercurial's web interface</title> 16.18 - 16.19 - <para id="x_44b">Mercurial has a powerful web interface that provides several 16.20 - useful capabilities.</para> 16.21 - 16.22 - <para id="x_44c">For interactive use, the web interface lets you browse a 16.23 - single repository or a collection of repositories. You can view 16.24 - the history of a repository, examine each change (comments and 16.25 - diffs), and view the contents of each directory and file. You 16.26 - can even get a view of history that gives a graphical view of 16.27 - the relationships between individual changes and merges.</para> 16.28 - 16.29 - <para id="x_44d">Also for human consumption, the web interface provides 16.30 - Atom and RSS feeds of the changes in a repository. This lets you 16.31 - <quote>subscribe</quote> to a repository using your favorite 16.32 - feed reader, and be automatically notified of activity in that 16.33 - repository as soon as it happens. I find this capability much 16.34 - more convenient than the model of subscribing to a mailing list 16.35 - to which notifications are sent, as it requires no additional 16.36 - configuration on the part of whoever is serving the 16.37 - repository.</para> 16.38 - 16.39 - <para id="x_44e">The web interface also lets remote users clone a repository, 16.40 - pull changes from it, and (when the server is configured to 16.41 - permit it) push changes back to it. Mercurial's HTTP tunneling 16.42 - protocol aggressively compresses data, so that it works 16.43 - efficiently even over low-bandwidth network connections.</para> 16.44 - 16.45 - <para id="x_44f">The easiest way to get started with the web interface is to 16.46 - use your web browser to visit an existing repository, such as 16.47 - the master Mercurial repository at <ulink 16.48 - url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para> 16.49 - 16.50 - <para id="x_450">If you're interested in providing a web interface 16.51 - to your own repositories, there are several good ways to do 16.52 - this.</para> 16.53 - 16.54 - <para id="x_69d">The easiest and fastest way to get started in an informal 16.55 - environment is to use the <command role="hg-cmd">hg 16.56 - serve</command> command, which is best suited to short-term 16.57 - <quote>lightweight</quote> serving. See <xref 16.58 - linkend="sec:collab:serve"/> below for details of how to use 16.59 - this command.</para> 16.60 - 16.61 - <para id="x_69e">For longer-lived repositories that you'd like to have 16.62 - permanently available, there are several public hosting services 16.63 - available.</para> 16.64 - 16.65 - <itemizedlist> 16.66 - <listitem> 16.67 - <para id="x_69f">Bitbucket, at <ulink 16.68 - url="http://bitbucket.org/">http://bitbucket.org/</ulink>, 16.69 - provides free hosting for open source projects, and paid 16.70 - hosting for commercial projects.</para> 16.71 - </listitem> 16.72 - </itemizedlist> 16.73 - 16.74 - <para id="x_6a0">If you would prefer to host your own repositories, Mercurial 16.75 - has built-in support for several popular hosting technologies, 16.76 - most notably CGI (Common Gateway Interface), and WSGI (Web 16.77 - Services Gateway Interface). See <xref 16.78 - linkend="sec:collab:cgi"/> for details of CGI and WSGI 16.79 - configuration.</para> 16.80 - </sect1> 16.81 - 16.82 - <sect1> 16.83 - <title>Collaboration models</title> 16.84 - 16.85 - <para id="x_451">With a suitably flexible tool, making decisions about 16.86 - workflow is much more of a social engineering challenge than a 16.87 - technical one. Mercurial imposes few limitations on how you can 16.88 - structure the flow of work in a project, so it's up to you and 16.89 - your group to set up and live with a model that matches your own 16.90 - particular needs.</para> 16.91 - 16.92 - <sect2> 16.93 - <title>Factors to keep in mind</title> 16.94 - 16.95 - <para id="x_452">The most important aspect of any model that you must keep 16.96 - in mind is how well it matches the needs and capabilities of 16.97 - the people who will be using it. This might seem 16.98 - self-evident; even so, you still can't afford to forget it for 16.99 - a moment.</para> 16.100 - 16.101 - <para id="x_453">I once put together a workflow model that seemed to make 16.102 - perfect sense to me, but that caused a considerable amount of 16.103 - consternation and strife within my development team. In spite 16.104 - of my attempts to explain why we needed a complex set of 16.105 - branches, and how changes ought to flow between them, a few 16.106 - team members revolted. Even though they were smart people, 16.107 - they didn't want to pay attention to the constraints we were 16.108 - operating under, or face the consequences of those constraints 16.109 - in the details of the model that I was advocating.</para> 16.110 - 16.111 - <para id="x_454">Don't sweep foreseeable social or technical problems under 16.112 - the rug. Whatever scheme you put into effect, you should plan 16.113 - for mistakes and problem scenarios. Consider adding automated 16.114 - machinery to prevent, or quickly recover from, trouble that 16.115 - you can anticipate. As an example, if you intend to have a 16.116 - branch with not-for-release changes in it, you'd do well to 16.117 - think early about the possibility that someone might 16.118 - accidentally merge those changes into a release branch. You 16.119 - could avoid this particular problem by writing a hook that 16.120 - prevents changes from being merged from an inappropriate 16.121 - branch.</para> 16.122 - </sect2> 16.123 - 16.124 - <sect2> 16.125 - <title>Informal anarchy</title> 16.126 - 16.127 - <para id="x_455">I wouldn't suggest an <quote>anything goes</quote> 16.128 - approach as something sustainable, but it's a model that's 16.129 - easy to grasp, and it works perfectly well in a few unusual 16.130 - situations.</para> 16.131 - 16.132 - <para id="x_456">As one example, many projects have a loose-knit group of 16.133 - collaborators who rarely physically meet each other. Some 16.134 - groups like to overcome the isolation of working at a distance 16.135 - by organizing occasional <quote>sprints</quote>. In a sprint, 16.136 - a number of people get together in a single location (a 16.137 - company's conference room, a hotel meeting room, that kind of 16.138 - place) and spend several days more or less locked in there, 16.139 - hacking intensely on a handful of projects.</para> 16.140 - 16.141 - <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the 16.142 - <command role="hg-cmd">hg serve</command> command, since 16.143 - <command role="hg-cmd">hg serve</command> does not require any 16.144 - fancy server infrastructure. You can get started with 16.145 - <command role="hg-cmd">hg serve</command> in moments, by 16.146 - reading <xref linkend="sec:collab:serve"/> below. Then simply 16.147 - tell the person next to you that you're running a server, send 16.148 - the URL to them in an instant message, and you immediately 16.149 - have a quick-turnaround way to work together. They can type 16.150 - your URL into their web browser and quickly review your 16.151 - changes; or they can pull a bugfix from you and verify it; or 16.152 - they can clone a branch containing a new feature and try it 16.153 - out.</para> 16.154 - 16.155 - <para id="x_458">The charm, and the problem, with doing things 16.156 - in an ad hoc fashion like this is that only people who know 16.157 - about your changes, and where they are, can see them. Such an 16.158 - informal approach simply doesn't scale beyond a handful 16.159 - people, because each individual needs to know about 16.160 - <emphasis>n</emphasis> different repositories to pull 16.161 - from.</para> 16.162 - </sect2> 16.163 - 16.164 - <sect2> 16.165 - <title>A single central repository</title> 16.166 - 16.167 - <para id="x_459">For smaller projects migrating from a centralised revision 16.168 - control tool, perhaps the easiest way to get started is to 16.169 - have changes flow through a single shared central repository. 16.170 - This is also the most common <quote>building block</quote> for 16.171 - more ambitious workflow schemes.</para> 16.172 - 16.173 - <para id="x_45a">Contributors start by cloning a copy of this repository. 16.174 - They can pull changes from it whenever they need to, and some 16.175 - (perhaps all) developers have permission to push a change back 16.176 - when they're ready for other people to see it.</para> 16.177 - 16.178 - <para id="x_45b">Under this model, it can still often make sense for people 16.179 - to pull changes directly from each other, without going 16.180 - through the central repository. Consider a case in which I 16.181 - have a tentative bug fix, but I am worried that if I were to 16.182 - publish it to the central repository, it might subsequently 16.183 - break everyone else's trees as they pull it. To reduce the 16.184 - potential for damage, I can ask you to clone my repository 16.185 - into a temporary repository of your own and test it. This 16.186 - lets us put off publishing the potentially unsafe change until 16.187 - it has had a little testing.</para> 16.188 - 16.189 - <para id="x_45c">If a team is hosting its own repository in this 16.190 - kind of scenario, people will usually use the 16.191 - <command>ssh</command> protocol to securely push changes to 16.192 - the central repository, as documented in <xref 16.193 - linkend="sec:collab:ssh"/>. It's also usual to publish a 16.194 - read-only copy of the repository over HTTP, as in 16.195 - <xref linkend="sec:collab:cgi"/>. Publishing over HTTP 16.196 - satisfies the needs of people who don't have push access, and 16.197 - those who want to use web browsers to browse the repository's 16.198 - history.</para> 16.199 - </sect2> 16.200 - 16.201 - <sect2> 16.202 - <title>A hosted central repository</title> 16.203 - 16.204 - <para id="x_6a1">A wonderful thing about public hosting services like 16.205 - <ulink url="http://bitbucket.org/">Bitbucket</ulink> is that 16.206 - not only do they handle the fiddly server configuration 16.207 - details, such as user accounts, authentication, and secure 16.208 - wire protocols, they provide additional infrastructure to make 16.209 - this model work well.</para> 16.210 - 16.211 - <para id="x_6a2">For instance, a well-engineered hosting service will let 16.212 - people clone their own copies of a repository with a single 16.213 - click. This lets people work in separate spaces and share 16.214 - their changes when they're ready.</para> 16.215 - 16.216 - <para id="x_6a3">In addition, a good hosting service will let people 16.217 - communicate with each other, for instance to say <quote>there 16.218 - are changes ready for you to review in this 16.219 - tree</quote>.</para> 16.220 - </sect2> 16.221 - 16.222 - <sect2> 16.223 - <title>Working with multiple branches</title> 16.224 - 16.225 - <para id="x_45d">Projects of any significant size naturally tend to make 16.226 - progress on several fronts simultaneously. In the case of 16.227 - software, it's common for a project to go through periodic 16.228 - official releases. A release might then go into 16.229 - <quote>maintenance mode</quote> for a while after its first 16.230 - publication; maintenance releases tend to contain only bug 16.231 - fixes, not new features. In parallel with these maintenance 16.232 - releases, one or more future releases may be under 16.233 - development. People normally use the word 16.234 - <quote>branch</quote> to refer to one of these many slightly 16.235 - different directions in which development is 16.236 - proceeding.</para> 16.237 - 16.238 - <para id="x_45e">Mercurial is particularly well suited to managing a number 16.239 - of simultaneous, but not identical, branches. Each 16.240 - <quote>development direction</quote> can live in its own 16.241 - central repository, and you can merge changes from one to 16.242 - another as the need arises. Because repositories are 16.243 - independent of each other, unstable changes in a development 16.244 - branch will never affect a stable branch unless someone 16.245 - explicitly merges those changes into the stable branch.</para> 16.246 - 16.247 - <para id="x_45f">Here's an example of how this can work in practice. Let's 16.248 - say you have one <quote>main branch</quote> on a central 16.249 - server.</para> 16.250 - 16.251 - &interaction.branching.init; 16.252 - 16.253 - <para id="x_460">People clone it, make changes locally, test them, and push 16.254 - them back.</para> 16.255 - 16.256 - <para id="x_461">Once the main branch reaches a release milestone, you can 16.257 - use the <command role="hg-cmd">hg tag</command> command to 16.258 - give a permanent name to the milestone revision.</para> 16.259 - 16.260 - &interaction.branching.tag; 16.261 - 16.262 - <para id="x_462">Let's say some ongoing 16.263 - development occurs on the main branch.</para> 16.264 - 16.265 - &interaction.branching.main; 16.266 - 16.267 - <para id="x_463">Using the tag that was recorded at the milestone, people 16.268 - who clone that repository at any time in the future can use 16.269 - <command role="hg-cmd">hg update</command> to get a copy of 16.270 - the working directory exactly as it was when that tagged 16.271 - revision was committed.</para> 16.272 - 16.273 - &interaction.branching.update; 16.274 - 16.275 - <para id="x_464">In addition, immediately after the main branch is tagged, 16.276 - we can then clone the main branch on the server to a new 16.277 - <quote>stable</quote> branch, also on the server.</para> 16.278 - 16.279 - &interaction.branching.clone; 16.280 - 16.281 - <para id="x_465">If we need to make a change to the stable 16.282 - branch, we can then clone <emphasis>that</emphasis> 16.283 - repository, make our changes, commit, and push our changes 16.284 - back there.</para> 16.285 - 16.286 - &interaction.branching.stable; 16.287 - 16.288 - <para id="x_466">Because Mercurial repositories are independent, and 16.289 - Mercurial doesn't move changes around automatically, the 16.290 - stable and main branches are <emphasis>isolated</emphasis> 16.291 - from each other. The changes that we made on the main branch 16.292 - don't <quote>leak</quote> to the stable branch, and vice 16.293 - versa.</para> 16.294 - 16.295 - <para id="x_467">We'll often want all of our bugfixes on the stable 16.296 - branch to show up on the main branch, too. Rather than 16.297 - rewrite a bugfix on the main branch, we can simply pull and 16.298 - merge changes from the stable to the main branch, and 16.299 - Mercurial will bring those bugfixes in for us.</para> 16.300 - 16.301 - &interaction.branching.merge; 16.302 - 16.303 - <para id="x_468">The main branch will still contain changes that 16.304 - are not on the stable branch, but it will also contain all of 16.305 - the bugfixes from the stable branch. The stable branch 16.306 - remains unaffected by these changes, since changes are only 16.307 - flowing from the stable to the main branch, and not the other 16.308 - way.</para> 16.309 - </sect2> 16.310 - 16.311 - <sect2> 16.312 - <title>Feature branches</title> 16.313 - 16.314 - <para id="x_469">For larger projects, an effective way to manage change is 16.315 - to break up a team into smaller groups. Each group has a 16.316 - shared branch of its own, cloned from a single 16.317 - <quote>master</quote> branch used by the entire project. 16.318 - People working on an individual branch are typically quite 16.319 - isolated from developments on other branches.</para> 16.320 - 16.321 - <figure id="fig:collab:feature-branches"> 16.322 - <title>Feature branches</title> 16.323 - <mediaobject> 16.324 - <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject> 16.325 - <textobject><phrase>XXX add text</phrase></textobject> 16.326 - </mediaobject> 16.327 - </figure> 16.328 - 16.329 - <para id="x_46b">When a particular feature is deemed to be in suitable 16.330 - shape, someone on that feature team pulls and merges from the 16.331 - master branch into the feature branch, then pushes back up to 16.332 - the master branch.</para> 16.333 - </sect2> 16.334 - 16.335 - <sect2> 16.336 - <title>The release train</title> 16.337 - 16.338 - <para id="x_46c">Some projects are organized on a <quote>train</quote> 16.339 - basis: a release is scheduled to happen every few months, and 16.340 - whatever features are ready when the <quote>train</quote> is 16.341 - ready to leave are allowed in.</para> 16.342 - 16.343 - <para id="x_46d">This model resembles working with feature branches. The 16.344 - difference is that when a feature branch misses a train, 16.345 - someone on the feature team pulls and merges the changes that 16.346 - went out on that train release into the feature branch, and 16.347 - the team continues its work on top of that release so that 16.348 - their feature can make the next release.</para> 16.349 - </sect2> 16.350 - 16.351 - <sect2> 16.352 - <title>The Linux kernel model</title> 16.353 - 16.354 - <para id="x_46e">The development of the Linux kernel has a shallow 16.355 - hierarchical structure, surrounded by a cloud of apparent 16.356 - chaos. Because most Linux developers use 16.357 - <command>git</command>, a distributed revision control tool 16.358 - with capabilities similar to Mercurial, it's useful to 16.359 - describe the way work flows in that environment; if you like 16.360 - the ideas, the approach translates well across tools.</para> 16.361 - 16.362 - <para id="x_46f">At the center of the community sits Linus Torvalds, the 16.363 - creator of Linux. He publishes a single source repository 16.364 - that is considered the <quote>authoritative</quote> current 16.365 - tree by the entire developer community. Anyone can clone 16.366 - Linus's tree, but he is very choosy about whose trees he pulls 16.367 - from.</para> 16.368 - 16.369 - <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>. 16.370 - As a general rule, he pulls whatever changes they publish, in 16.371 - most cases without even reviewing those changes. Some of 16.372 - those lieutenants are generally agreed to be 16.373 - <quote>maintainers</quote>, responsible for specific 16.374 - subsystems within the kernel. If a random kernel hacker wants 16.375 - to make a change to a subsystem that they want to end up in 16.376 - Linus's tree, they must find out who the subsystem's 16.377 - maintainer is, and ask that maintainer to take their change. 16.378 - If the maintainer reviews their changes and agrees to take 16.379 - them, they'll pass them along to Linus in due course.</para> 16.380 - 16.381 - <para id="x_471">Individual lieutenants have their own approaches to 16.382 - reviewing, accepting, and publishing changes; and for deciding 16.383 - when to feed them to Linus. In addition, there are several 16.384 - well known branches that people use for different purposes. 16.385 - For example, a few people maintain <quote>stable</quote> 16.386 - repositories of older versions of the kernel, to which they 16.387 - apply critical fixes as needed. Some maintainers publish 16.388 - multiple trees: one for experimental changes; one for changes 16.389 - that they are about to feed upstream; and so on. Others just 16.390 - publish a single tree.</para> 16.391 - 16.392 - <para id="x_472">This model has two notable features. The first is that 16.393 - it's <quote>pull only</quote>. You have to ask, convince, or 16.394 - beg another developer to take a change from you, because there 16.395 - are almost no trees to which more than one person can push, 16.396 - and there's no way to push changes into a tree that someone 16.397 - else controls.</para> 16.398 - 16.399 - <para id="x_473">The second is that it's based on reputation and acclaim. 16.400 - If you're an unknown, Linus will probably ignore changes from 16.401 - you without even responding. But a subsystem maintainer will 16.402 - probably review them, and will likely take them if they pass 16.403 - their criteria for suitability. The more <quote>good</quote> 16.404 - changes you contribute to a maintainer, the more likely they 16.405 - are to trust your judgment and accept your changes. If you're 16.406 - well-known and maintain a long-lived branch for something 16.407 - Linus hasn't yet accepted, people with similar interests may 16.408 - pull your changes regularly to keep up with your work.</para> 16.409 - 16.410 - <para id="x_474">Reputation and acclaim don't necessarily cross subsystem 16.411 - or <quote>people</quote> boundaries. If you're a respected 16.412 - but specialised storage hacker, and you try to fix a 16.413 - networking bug, that change will receive a level of scrutiny 16.414 - from a network maintainer comparable to a change from a 16.415 - complete stranger.</para> 16.416 - 16.417 - <para id="x_475">To people who come from more orderly project backgrounds, 16.418 - the comparatively chaotic Linux kernel development process 16.419 - often seems completely insane. It's subject to the whims of 16.420 - individuals; people make sweeping changes whenever they deem 16.421 - it appropriate; and the pace of development is astounding. 16.422 - And yet Linux is a highly successful, well-regarded piece of 16.423 - software.</para> 16.424 - </sect2> 16.425 - 16.426 - <sect2> 16.427 - <title>Pull-only versus shared-push collaboration</title> 16.428 - 16.429 - <para id="x_476">A perpetual source of heat in the open source community is 16.430 - whether a development model in which people only ever pull 16.431 - changes from others is <quote>better than</quote> one in which 16.432 - multiple people can push changes to a shared 16.433 - repository.</para> 16.434 - 16.435 - <para id="x_477">Typically, the backers of the shared-push model use tools 16.436 - that actively enforce this approach. If you're using a 16.437 - centralised revision control tool such as Subversion, there's 16.438 - no way to make a choice over which model you'll use: the tool 16.439 - gives you shared-push, and if you want to do anything else, 16.440 - you'll have to roll your own approach on top (such as applying 16.441 - a patch by hand).</para> 16.442 - 16.443 - <para id="x_478">A good distributed revision control tool will 16.444 - support both models. You and your collaborators can then 16.445 - structure how you work together based on your own needs and 16.446 - preferences, not on what contortions your tools force you 16.447 - into.</para> 16.448 - </sect2> 16.449 - <sect2> 16.450 - <title>Where collaboration meets branch management</title> 16.451 - 16.452 - <para id="x_479">Once you and your team set up some shared 16.453 - repositories and start propagating changes back and forth 16.454 - between local and shared repos, you begin to face a related, 16.455 - but slightly different challenge: that of managing the 16.456 - multiple directions in which your team may be moving at once. 16.457 - Even though this subject is intimately related to how your 16.458 - team collaborates, it's dense enough to merit treatment of its 16.459 - own, in <xref linkend="chap:branch"/>.</para> 16.460 - </sect2> 16.461 - </sect1> 16.462 - 16.463 - <sect1> 16.464 - <title>The technical side of sharing</title> 16.465 - 16.466 - <para id="x_47a">The remainder of this chapter is devoted to the question of 16.467 - sharing changes with your collaborators.</para> 16.468 - </sect1> 16.469 - 16.470 - <sect1 id="sec:collab:serve"> 16.471 - <title>Informal sharing with <command role="hg-cmd">hg 16.472 - serve</command></title> 16.473 - 16.474 - <para id="x_47b">Mercurial's <command role="hg-cmd">hg serve</command> 16.475 - command is wonderfully suited to small, tight-knit, and 16.476 - fast-paced group environments. It also provides a great way to 16.477 - get a feel for using Mercurial commands over a network.</para> 16.478 - 16.479 - <para id="x_47c">Run <command role="hg-cmd">hg serve</command> inside a 16.480 - repository, and in under a second it will bring up a specialised 16.481 - HTTP server; this will accept connections from any client, and 16.482 - serve up data for that repository until you terminate it. 16.483 - Anyone who knows the URL of the server you just started, and can 16.484 - talk to your computer over the network, can then use a web 16.485 - browser or Mercurial to read data from that repository. A URL 16.486 - for a <command role="hg-cmd">hg serve</command> instance running 16.487 - on a laptop is likely to look something like 16.488 - <literal>http://my-laptop.local:8000/</literal>.</para> 16.489 - 16.490 - <para id="x_47d">The <command role="hg-cmd">hg serve</command> command is 16.491 - <emphasis>not</emphasis> a general-purpose web server. It can do 16.492 - only two things:</para> 16.493 - <itemizedlist> 16.494 - <listitem><para id="x_47e">Allow people to browse the history of the 16.495 - repository it's serving, from their normal web 16.496 - browsers.</para> 16.497 - </listitem> 16.498 - <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people 16.499 - can <command role="hg-cmd">hg clone</command> or <command 16.500 - role="hg-cmd">hg pull</command> changes from that 16.501 - repository.</para> 16.502 - </listitem></itemizedlist> 16.503 - <para id="x_480">In particular, <command role="hg-cmd">hg serve</command> 16.504 - won't allow remote users to <emphasis>modify</emphasis> your 16.505 - repository. It's intended for read-only use.</para> 16.506 - 16.507 - <para id="x_481">If you're getting started with Mercurial, there's nothing to 16.508 - prevent you from using <command role="hg-cmd">hg serve</command> 16.509 - to serve up a repository on your own computer, then use commands 16.510 - like <command role="hg-cmd">hg clone</command>, <command 16.511 - role="hg-cmd">hg incoming</command>, and so on to talk to that 16.512 - server as if the repository was hosted remotely. This can help 16.513 - you to quickly get acquainted with using commands on 16.514 - network-hosted repositories.</para> 16.515 - 16.516 - <sect2> 16.517 - <title>A few things to keep in mind</title> 16.518 - 16.519 - <para id="x_482">Because it provides unauthenticated read access to all 16.520 - clients, you should only use <command role="hg-cmd">hg 16.521 - serve</command> in an environment where you either don't 16.522 - care, or have complete control over, who can access your 16.523 - network and pull data from your repository.</para> 16.524 - 16.525 - <para id="x_483">The <command role="hg-cmd">hg serve</command> command 16.526 - knows nothing about any firewall software you might have 16.527 - installed on your system or network. It cannot detect or 16.528 - control your firewall software. If other people are unable to 16.529 - talk to a running <command role="hg-cmd">hg serve</command> 16.530 - instance, the second thing you should do 16.531 - (<emphasis>after</emphasis> you make sure that they're using 16.532 - the correct URL) is check your firewall configuration.</para> 16.533 - 16.534 - <para id="x_484">By default, <command role="hg-cmd">hg serve</command> 16.535 - listens for incoming connections on port 8000. If another 16.536 - process is already listening on the port you want to use, you 16.537 - can specify a different port to listen on using the <option 16.538 - role="hg-opt-serve">-p</option> option.</para> 16.539 - 16.540 - <para id="x_485">Normally, when <command role="hg-cmd">hg serve</command> 16.541 - starts, it prints no output, which can be a bit unnerving. If 16.542 - you'd like to confirm that it is indeed running correctly, and 16.543 - find out what URL you should send to your collaborators, start 16.544 - it with the <option role="hg-opt-global">-v</option> 16.545 - option.</para> 16.546 - </sect2> 16.547 - </sect1> 16.548 - 16.549 - <sect1 id="sec:collab:ssh"> 16.550 - <title>Using the Secure Shell (ssh) protocol</title> 16.551 - 16.552 - <para id="x_486">You can pull and push changes securely over a network 16.553 - connection using the Secure Shell (<literal>ssh</literal>) 16.554 - protocol. To use this successfully, you may have to do a little 16.555 - bit of configuration on the client or server sides.</para> 16.556 - 16.557 - <para id="x_487">If you're not familiar with ssh, it's the name of 16.558 - both a command and a network protocol that let you securely 16.559 - communicate with another computer. To use it with Mercurial, 16.560 - you'll be setting up one or more user accounts on a server so 16.561 - that remote users can log in and execute commands.</para> 16.562 - 16.563 - <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll 16.564 - probably find some of the material that follows to be elementary 16.565 - in nature.)</para> 16.566 - 16.567 - <sect2> 16.568 - <title>How to read and write ssh URLs</title> 16.569 - 16.570 - <para id="x_489">An ssh URL tends to look like this:</para> 16.571 - <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting> 16.572 - <orderedlist> 16.573 - <listitem><para id="x_48a">The <quote><literal>ssh://</literal></quote> 16.574 - part tells Mercurial to use the ssh protocol.</para> 16.575 - </listitem> 16.576 - <listitem><para id="x_48b">The <quote><literal>bos@</literal></quote> 16.577 - component indicates what username to log into the server 16.578 - as. You can leave this out if the remote username is the 16.579 - same as your local username.</para> 16.580 - </listitem> 16.581 - <listitem><para id="x_48c">The 16.582 - <quote><literal>hg.serpentine.com</literal></quote> gives 16.583 - the hostname of the server to log into.</para> 16.584 - </listitem> 16.585 - <listitem><para id="x_48d">The <quote>:22</quote> identifies the port 16.586 - number to connect to the server on. The default port is 16.587 - 22, so you only need to specify a colon and port number if 16.588 - you're <emphasis>not</emphasis> using port 22.</para> 16.589 - </listitem> 16.590 - <listitem><para id="x_48e">The remainder of the URL is the local path to 16.591 - the repository on the server.</para> 16.592 - </listitem></orderedlist> 16.593 - 16.594 - <para id="x_48f">There's plenty of scope for confusion with the path 16.595 - component of ssh URLs, as there is no standard way for tools 16.596 - to interpret it. Some programs behave differently than others 16.597 - when dealing with these paths. This isn't an ideal situation, 16.598 - but it's unlikely to change. Please read the following 16.599 - paragraphs carefully.</para> 16.600 - 16.601 - <para id="x_490">Mercurial treats the path to a repository on the server as 16.602 - relative to the remote user's home directory. For example, if 16.603 - user <literal>foo</literal> on the server has a home directory 16.604 - of <filename class="directory">/home/foo</filename>, then an 16.605 - ssh URL that contains a path component of <filename 16.606 - class="directory">bar</filename> <emphasis>really</emphasis> 16.607 - refers to the directory <filename 16.608 - class="directory">/home/foo/bar</filename>.</para> 16.609 - 16.610 - <para id="x_491">If you want to specify a path relative to another user's 16.611 - home directory, you can use a path that starts with a tilde 16.612 - character followed by the user's name (let's call them 16.613 - <literal>otheruser</literal>), like this.</para> 16.614 - <programlisting>ssh://server/~otheruser/hg/repo</programlisting> 16.615 - 16.616 - <para id="x_492">And if you really want to specify an 16.617 - <emphasis>absolute</emphasis> path on the server, begin the 16.618 - path component with two slashes, as in this example.</para> 16.619 - <programlisting>ssh://server//absolute/path</programlisting> 16.620 - </sect2> 16.621 - 16.622 - <sect2> 16.623 - <title>Finding an ssh client for your system</title> 16.624 - 16.625 - <para id="x_493">Almost every Unix-like system comes with OpenSSH 16.626 - preinstalled. If you're using such a system, run 16.627 - <literal>which ssh</literal> to find out if the 16.628 - <command>ssh</command> command is installed (it's usually in 16.629 - <filename class="directory">/usr/bin</filename>). In the 16.630 - unlikely event that it isn't present, take a look at your 16.631 - system documentation to figure out how to install it.</para> 16.632 - 16.633 - <para id="x_494">On Windows, the TortoiseHg package is bundled 16.634 - with a version of Simon Tatham's excellent 16.635 - <command>plink</command> command, and you should not need to 16.636 - do any further configuration.</para> 16.637 - </sect2> 16.638 - 16.639 - <sect2> 16.640 - <title>Generating a key pair</title> 16.641 - 16.642 - <para id="x_499">To avoid the need to repetitively type a 16.643 - password every time you need to use your ssh client, I 16.644 - recommend generating a key pair.</para> 16.645 - 16.646 - <tip> 16.647 - <title>Key pairs are not mandatory</title> 16.648 - 16.649 - <para id="x_6a4">Mercurial knows nothing about ssh authentication or key 16.650 - pairs. You can, if you like, safely ignore this section and 16.651 - the one that follows until you grow tired of repeatedly 16.652 - typing ssh passwords.</para> 16.653 - </tip> 16.654 - 16.655 - <itemizedlist> 16.656 - <listitem> 16.657 - <para id="x_6a5">On a Unix-like system, the 16.658 - <command>ssh-keygen</command> command will do the 16.659 - trick.</para> 16.660 - <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need 16.661 - to download a command named <command>puttygen</command> 16.662 - from <ulink 16.663 - url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 16.664 - PuTTY web site</ulink> to generate a key pair. See 16.665 - <ulink 16.666 - url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 16.667 - <command>puttygen</command> documentation</ulink> for 16.668 - details of how use the command.</para> 16.669 - </listitem> 16.670 - </itemizedlist> 16.671 - 16.672 - <para id="x_49a">When you generate a key pair, it's usually 16.673 - <emphasis>highly</emphasis> advisable to protect it with a 16.674 - passphrase. (The only time that you might not want to do this 16.675 - is when you're using the ssh protocol for automated tasks on a 16.676 - secure network.)</para> 16.677 - 16.678 - <para id="x_49b">Simply generating a key pair isn't enough, however. 16.679 - You'll need to add the public key to the set of authorised 16.680 - keys for whatever user you're logging in remotely as. For 16.681 - servers using OpenSSH (the vast majority), this will mean 16.682 - adding the public key to a list in a file called <filename 16.683 - role="special">authorized_keys</filename> in their <filename 16.684 - role="special" class="directory">.ssh</filename> 16.685 - directory.</para> 16.686 - 16.687 - <para id="x_49c">On a Unix-like system, your public key will have a 16.688 - <filename>.pub</filename> extension. If you're using 16.689 - <command>puttygen</command> on Windows, you can save the 16.690 - public key to a file of your choosing, or paste it from the 16.691 - window it's displayed in straight into the <filename 16.692 - role="special">authorized_keys</filename> file.</para> 16.693 - </sect2> 16.694 - <sect2> 16.695 - <title>Using an authentication agent</title> 16.696 - 16.697 - <para id="x_49d">An authentication agent is a daemon that stores 16.698 - passphrases in memory (so it will forget passphrases if you 16.699 - log out and log back in again). An ssh client will notice if 16.700 - it's running, and query it for a passphrase. If there's no 16.701 - authentication agent running, or the agent doesn't store the 16.702 - necessary passphrase, you'll have to type your passphrase 16.703 - every time Mercurial tries to communicate with a server on 16.704 - your behalf (e.g. whenever you pull or push changes).</para> 16.705 - 16.706 - <para id="x_49e">The downside of storing passphrases in an agent is that 16.707 - it's possible for a well-prepared attacker to recover the 16.708 - plain text of your passphrases, in some cases even if your 16.709 - system has been power-cycled. You should make your own 16.710 - judgment as to whether this is an acceptable risk. It 16.711 - certainly saves a lot of repeated typing.</para> 16.712 - 16.713 - <itemizedlist> 16.714 - <listitem> 16.715 - <para id="x_49f">On Unix-like systems, the agent is called 16.716 - <command>ssh-agent</command>, and it's often run 16.717 - automatically for you when you log in. You'll need to use 16.718 - the <command>ssh-add</command> command to add passphrases 16.719 - to the agent's store.</para> 16.720 - </listitem> 16.721 - <listitem> 16.722 - <para id="x_6a7">On Windows, if you're using TortoiseHg, the 16.723 - <command>pageant</command> command acts as the agent. As 16.724 - with <command>puttygen</command>, you'll need to <ulink 16.725 - url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 16.726 - <command>pageant</command></ulink> from the PuTTY web 16.727 - site and read <ulink 16.728 - url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 16.729 - documentation</ulink>. The <command>pageant</command> 16.730 - command adds an icon to your system tray that will let you 16.731 - manage stored passphrases.</para> 16.732 - </listitem> 16.733 - </itemizedlist> 16.734 - </sect2> 16.735 - 16.736 - <sect2> 16.737 - <title>Configuring the server side properly</title> 16.738 - 16.739 - <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it, 16.740 - a variety of things can go wrong. Add Mercurial 16.741 - on top, and there's plenty more scope for head-scratching. 16.742 - Most of these potential problems occur on the server side, not 16.743 - the client side. The good news is that once you've gotten a 16.744 - configuration working, it will usually continue to work 16.745 - indefinitely.</para> 16.746 - 16.747 - <para id="x_4a1">Before you try using Mercurial to talk to an ssh server, 16.748 - it's best to make sure that you can use the normal 16.749 - <command>ssh</command> or <command>putty</command> command to 16.750 - talk to the server first. If you run into problems with using 16.751 - these commands directly, Mercurial surely won't work. Worse, 16.752 - it will obscure the underlying problem. Any time you want to 16.753 - debug ssh-related Mercurial problems, you should drop back to 16.754 - making sure that plain ssh client commands work first, 16.755 - <emphasis>before</emphasis> you worry about whether there's a 16.756 - problem with Mercurial.</para> 16.757 - 16.758 - <para id="x_4a2">The first thing to be sure of on the server side is that 16.759 - you can actually log in from another machine at all. If you 16.760 - can't use <command>ssh</command> or <command>putty</command> 16.761 - to log in, the error message you get may give you a few hints 16.762 - as to what's wrong. The most common problems are as 16.763 - follows.</para> 16.764 - <itemizedlist> 16.765 - <listitem><para id="x_4a3">If you get a <quote>connection refused</quote> 16.766 - error, either there isn't an SSH daemon running on the 16.767 - server at all, or it's inaccessible due to firewall 16.768 - configuration.</para> 16.769 - </listitem> 16.770 - <listitem><para id="x_4a4">If you get a <quote>no route to host</quote> 16.771 - error, you either have an incorrect address for the server 16.772 - or a seriously locked down firewall that won't admit its 16.773 - existence at all.</para> 16.774 - </listitem> 16.775 - <listitem><para id="x_4a5">If you get a <quote>permission denied</quote> 16.776 - error, you may have mistyped the username on the server, 16.777 - or you could have mistyped your key's passphrase or the 16.778 - remote user's password.</para> 16.779 - </listitem></itemizedlist> 16.780 - <para id="x_4a6">In summary, if you're having trouble talking to the 16.781 - server's ssh daemon, first make sure that one is running at 16.782 - all. On many systems it will be installed, but disabled, by 16.783 - default. Once you're done with this step, you should then 16.784 - check that the server's firewall is configured to allow 16.785 - incoming connections on the port the ssh daemon is listening 16.786 - on (usually 22). Don't worry about more exotic possibilities 16.787 - for misconfiguration until you've checked these two 16.788 - first.</para> 16.789 - 16.790 - <para id="x_4a7">If you're using an authentication agent on the client side 16.791 - to store passphrases for your keys, you ought to be able to 16.792 - log into the server without being prompted for a passphrase or 16.793 - a password. If you're prompted for a passphrase, there are a 16.794 - few possible culprits.</para> 16.795 - <itemizedlist> 16.796 - <listitem><para id="x_4a8">You might have forgotten to use 16.797 - <command>ssh-add</command> or <command>pageant</command> 16.798 - to store the passphrase.</para> 16.799 - </listitem> 16.800 - <listitem><para id="x_4a9">You might have stored the passphrase for the 16.801 - wrong key.</para> 16.802 - </listitem></itemizedlist> 16.803 - <para id="x_4aa">If you're being prompted for the remote user's password, 16.804 - there are another few possible problems to check.</para> 16.805 - <itemizedlist> 16.806 - <listitem><para id="x_4ab">Either the user's home directory or their 16.807 - <filename role="special" class="directory">.ssh</filename> 16.808 - directory might have excessively liberal permissions. As 16.809 - a result, the ssh daemon will not trust or read their 16.810 - <filename role="special">authorized_keys</filename> file. 16.811 - For example, a group-writable home or <filename 16.812 - role="special" class="directory">.ssh</filename> 16.813 - directory will often cause this symptom.</para> 16.814 - </listitem> 16.815 - <listitem><para id="x_4ac">The user's <filename 16.816 - role="special">authorized_keys</filename> file may have 16.817 - a problem. If anyone other than the user owns or can write 16.818 - to that file, the ssh daemon will not trust or read 16.819 - it.</para> 16.820 - </listitem></itemizedlist> 16.821 - 16.822 - <para id="x_4ad">In the ideal world, you should be able to run the 16.823 - following command successfully, and it should print exactly 16.824 - one line of output, the current date and time.</para> 16.825 - <programlisting>ssh myserver date</programlisting> 16.826 - 16.827 - <para id="x_4ae">If, on your server, you have login scripts that print 16.828 - banners or other junk even when running non-interactive 16.829 - commands like this, you should fix them before you continue, 16.830 - so that they only print output if they're run interactively. 16.831 - Otherwise these banners will at least clutter up Mercurial's 16.832 - output. Worse, they could potentially cause problems with 16.833 - running Mercurial commands remotely. Mercurial makes tries to 16.834 - detect and ignore banners in non-interactive 16.835 - <command>ssh</command> sessions, but it is not foolproof. (If 16.836 - you're editing your login scripts on your server, the usual 16.837 - way to see if a login script is running in an interactive 16.838 - shell is to check the return code from the command 16.839 - <literal>tty -s</literal>.)</para> 16.840 - 16.841 - <para id="x_4af">Once you've verified that plain old ssh is working with 16.842 - your server, the next step is to ensure that Mercurial runs on 16.843 - the server. The following command should run 16.844 - successfully:</para> 16.845 - 16.846 - <programlisting>ssh myserver hg version</programlisting> 16.847 - 16.848 - <para id="x_4b0">If you see an error message instead of normal <command 16.849 - role="hg-cmd">hg version</command> output, this is usually 16.850 - because you haven't installed Mercurial to <filename 16.851 - class="directory">/usr/bin</filename>. Don't worry if this 16.852 - is the case; you don't need to do that. But you should check 16.853 - for a few possible problems.</para> 16.854 - <itemizedlist> 16.855 - <listitem><para id="x_4b1">Is Mercurial really installed on the server at 16.856 - all? I know this sounds trivial, but it's worth 16.857 - checking!</para> 16.858 - </listitem> 16.859 - <listitem><para id="x_4b2">Maybe your shell's search path (usually set 16.860 - via the <envar>PATH</envar> environment variable) is 16.861 - simply misconfigured.</para> 16.862 - </listitem> 16.863 - <listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment 16.864 - variable is only being set to point to the location of the 16.865 - <command>hg</command> executable if the login session is 16.866 - interactive. This can happen if you're setting the path 16.867 - in the wrong shell login script. See your shell's 16.868 - documentation for details.</para> 16.869 - </listitem> 16.870 - <listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment 16.871 - variable may need to contain the path to the Mercurial 16.872 - Python modules. It might not be set at all; it could be 16.873 - incorrect; or it may be set only if the login is 16.874 - interactive.</para> 16.875 - </listitem></itemizedlist> 16.876 - 16.877 - <para id="x_4b5">If you can run <command role="hg-cmd">hg version</command> 16.878 - over an ssh connection, well done! You've got the server and 16.879 - client sorted out. You should now be able to use Mercurial to 16.880 - access repositories hosted by that username on that server. 16.881 - If you run into problems with Mercurial and ssh at this point, 16.882 - try using the <option role="hg-opt-global">--debug</option> 16.883 - option to get a clearer picture of what's going on.</para> 16.884 - </sect2> 16.885 - <sect2> 16.886 - <title>Using compression with ssh</title> 16.887 - 16.888 - <para id="x_4b6">Mercurial does not compress data when it uses the ssh 16.889 - protocol, because the ssh protocol can transparently compress 16.890 - data. However, the default behavior of ssh clients is 16.891 - <emphasis>not</emphasis> to request compression.</para> 16.892 - 16.893 - <para id="x_4b7">Over any network other than a fast LAN (even a wireless 16.894 - network), using compression is likely to significantly speed 16.895 - up Mercurial's network operations. For example, over a WAN, 16.896 - someone measured compression as reducing the amount of time 16.897 - required to clone a particularly large repository from 51 16.898 - minutes to 17 minutes.</para> 16.899 - 16.900 - <para id="x_4b8">Both <command>ssh</command> and <command>plink</command> 16.901 - accept a <option role="cmd-opt-ssh">-C</option> option which 16.902 - turns on compression. You can easily edit your <filename 16.903 - role="special">~/.hgrc</filename> to enable compression for 16.904 - all of Mercurial's uses of the ssh protocol. Here is how to 16.905 - do so for regular <command>ssh</command> on Unix-like systems, 16.906 - for example.</para> 16.907 - <programlisting>[ui] 16.908 -ssh = ssh -C</programlisting> 16.909 - 16.910 - <para id="x_4b9">If you use <command>ssh</command> on a 16.911 - Unix-like system, you can configure it to always use 16.912 - compression when talking to your server. To do this, edit 16.913 - your <filename role="special">.ssh/config</filename> file 16.914 - (which may not yet exist), as follows.</para> 16.915 - 16.916 - <programlisting>Host hg 16.917 - Compression yes 16.918 - HostName hg.example.com</programlisting> 16.919 - 16.920 - <para id="x_4ba">This defines a hostname alias, 16.921 - <literal>hg</literal>. When you use that hostname on the 16.922 - <command>ssh</command> command line or in a Mercurial 16.923 - <literal>ssh</literal>-protocol URL, it will cause 16.924 - <command>ssh</command> to connect to 16.925 - <literal>hg.example.com</literal> and use compression. This 16.926 - gives you both a shorter name to type and compression, each of 16.927 - which is a good thing in its own right.</para> 16.928 - </sect2> 16.929 - </sect1> 16.930 - 16.931 - <sect1 id="sec:collab:cgi"> 16.932 - <title>Serving over HTTP using CGI</title> 16.933 - 16.934 - <para id="x_6a8">The simplest way to host one or more repositories in a 16.935 - permanent way is to use a web server and Mercurial's CGI 16.936 - support.</para> 16.937 - 16.938 - <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's 16.939 - CGI interface can take anything from a few moments to several 16.940 - hours.</para> 16.941 - 16.942 - <para id="x_4bc">We'll begin with the simplest of examples, and work our way 16.943 - towards a more complex configuration. Even for the most basic 16.944 - case, you're almost certainly going to need to read and modify 16.945 - your web server's configuration.</para> 16.946 - 16.947 - <note> 16.948 - <title>High pain tolerance required</title> 16.949 - 16.950 - <para id="x_4bd">Configuring a web server is a complex, fiddly, 16.951 - and highly system-dependent activity. I can't possibly give 16.952 - you instructions that will cover anything like all of the 16.953 - cases you will encounter. Please use your discretion and 16.954 - judgment in following the sections below. Be prepared to make 16.955 - plenty of mistakes, and to spend a lot of time reading your 16.956 - server's error logs.</para> 16.957 - 16.958 - <para id="x_6a9">If you don't have a strong stomach for tweaking 16.959 - configurations over and over, or a compelling need to host 16.960 - your own services, you might want to try one of the public 16.961 - hosting services that I mentioned earlier.</para> 16.962 - </note> 16.963 - 16.964 - <sect2> 16.965 - <title>Web server configuration checklist</title> 16.966 - 16.967 - <para id="x_4be">Before you continue, do take a few moments to check a few 16.968 - aspects of your system's setup.</para> 16.969 - 16.970 - <orderedlist> 16.971 - <listitem><para id="x_4bf">Do you have a web server installed 16.972 - at all? Mac OS X and some Linux distributions ship with 16.973 - Apache, but many other systems may not have a web server 16.974 - installed.</para> 16.975 - </listitem> 16.976 - <listitem><para id="x_4c0">If you have a web server installed, is it 16.977 - actually running? On most systems, even if one is 16.978 - present, it will be disabled by default.</para> 16.979 - </listitem> 16.980 - <listitem><para id="x_4c1">Is your server configured to allow you to run 16.981 - CGI programs in the directory where you plan to do so? 16.982 - Most servers default to explicitly disabling the ability 16.983 - to run CGI programs.</para> 16.984 - </listitem></orderedlist> 16.985 - 16.986 - <para id="x_4c2">If you don't have a web server installed, and don't have 16.987 - substantial experience configuring Apache, you should consider 16.988 - using the <literal>lighttpd</literal> web server instead of 16.989 - Apache. Apache has a well-deserved reputation for baroque and 16.990 - confusing configuration. While <literal>lighttpd</literal> is 16.991 - less capable in some ways than Apache, most of these 16.992 - capabilities are not relevant to serving Mercurial 16.993 - repositories. And <literal>lighttpd</literal> is undeniably 16.994 - <emphasis>much</emphasis> easier to get started with than 16.995 - Apache.</para> 16.996 - </sect2> 16.997 - 16.998 - <sect2> 16.999 - <title>Basic CGI configuration</title> 16.1000 - 16.1001 - <para id="x_4c3">On Unix-like systems, it's common for users to have a 16.1002 - subdirectory named something like <filename 16.1003 - class="directory">public_html</filename> in their home 16.1004 - directory, from which they can serve up web pages. A file 16.1005 - named <filename>foo</filename> in this directory will be 16.1006 - accessible at a URL of the form 16.1007 - <literal>http://www.example.com/username/foo</literal>.</para> 16.1008 - 16.1009 - <para id="x_4c4">To get started, find the <filename 16.1010 - role="special">hgweb.cgi</filename> script that should be 16.1011 - present in your Mercurial installation. If you can't quickly 16.1012 - find a local copy on your system, simply download one from the 16.1013 - master Mercurial repository at <ulink 16.1014 - 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> 16.1015 - 16.1016 - <para id="x_4c5">You'll need to copy this script into your <filename 16.1017 - class="directory">public_html</filename> directory, and 16.1018 - ensure that it's executable.</para> 16.1019 - <programlisting>cp .../hgweb.cgi ~/public_html 16.1020 -chmod 755 ~/public_html/hgweb.cgi</programlisting> 16.1021 - <para id="x_4c6">The <literal>755</literal> argument to 16.1022 - <command>chmod</command> is a little more general than just 16.1023 - making the script executable: it ensures that the script is 16.1024 - executable by anyone, and that <quote>group</quote> and 16.1025 - <quote>other</quote> write permissions are 16.1026 - <emphasis>not</emphasis> set. If you were to leave those 16.1027 - write permissions enabled, Apache's <literal>suexec</literal> 16.1028 - subsystem would likely refuse to execute the script. In fact, 16.1029 - <literal>suexec</literal> also insists that the 16.1030 - <emphasis>directory</emphasis> in which the script resides 16.1031 - must not be writable by others.</para> 16.1032 - <programlisting>chmod 755 ~/public_html</programlisting> 16.1033 - 16.1034 - <sect3 id="sec:collab:wtf"> 16.1035 - <title>What could <emphasis>possibly</emphasis> go 16.1036 - wrong?</title> 16.1037 - 16.1038 - <para id="x_4c7">Once you've copied the CGI script into place, go into a 16.1039 - web browser, and try to open the URL <ulink 16.1040 - url="http://myhostname/ 16.1041 - myuser/hgweb.cgi">http://myhostname/ 16.1042 - myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace 16.1043 - yourself for instant failure. There's a high probability 16.1044 - that trying to visit this URL will fail, and there are many 16.1045 - possible reasons for this. In fact, you're likely to 16.1046 - stumble over almost every one of the possible errors below, 16.1047 - so please read carefully. The following are all of the 16.1048 - problems I ran into on a system running Fedora 7, with a 16.1049 - fresh installation of Apache, and a user account that I 16.1050 - created specially to perform this exercise.</para> 16.1051 - 16.1052 - <para id="x_4c8">Your web server may have per-user directories disabled. 16.1053 - If you're using Apache, search your config file for a 16.1054 - <literal>UserDir</literal> directive. If there's none 16.1055 - present, per-user directories will be disabled. If one 16.1056 - exists, but its value is <literal>disabled</literal>, then 16.1057 - per-user directories will be disabled. Otherwise, the 16.1058 - string after <literal>UserDir</literal> gives the name of 16.1059 - the subdirectory that Apache will look in under your home 16.1060 - directory, for example <filename 16.1061 - class="directory">public_html</filename>.</para> 16.1062 - 16.1063 - <para id="x_4c9">Your file access permissions may be too restrictive. 16.1064 - The web server must be able to traverse your home directory 16.1065 - and directories under your <filename 16.1066 - class="directory">public_html</filename> directory, and 16.1067 - read files under the latter too. Here's a quick recipe to 16.1068 - help you to make your permissions more appropriate.</para> 16.1069 - <programlisting>chmod 755 ~ 16.1070 -find ~/public_html -type d -print0 | xargs -0r chmod 755 16.1071 -find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting> 16.1072 - 16.1073 - <para id="x_4ca">The other possibility with permissions is that you might 16.1074 - get a completely empty window when you try to load the 16.1075 - script. In this case, it's likely that your access 16.1076 - permissions are <emphasis>too permissive</emphasis>. Apache's 16.1077 - <literal>suexec</literal> subsystem won't execute a script 16.1078 - that's group- or world-writable, for example.</para> 16.1079 - 16.1080 - <para id="x_4cb">Your web server may be configured to disallow execution 16.1081 - of CGI programs in your per-user web directory. Here's 16.1082 - Apache's default per-user configuration from my Fedora 16.1083 - system.</para> 16.1084 - 16.1085 - &ch06-apache-config.lst; 16.1086 - 16.1087 - <para id="x_4cc">If you find a similar-looking 16.1088 - <literal>Directory</literal> group in your Apache 16.1089 - configuration, the directive to look at inside it is 16.1090 - <literal>Options</literal>. Add <literal>ExecCGI</literal> 16.1091 - to the end of this list if it's missing, and restart the web 16.1092 - server.</para> 16.1093 - 16.1094 - <para id="x_4cd">If you find that Apache serves you the text of the CGI 16.1095 - script instead of executing it, you may need to either 16.1096 - uncomment (if already present) or add a directive like 16.1097 - this.</para> 16.1098 - <programlisting>AddHandler cgi-script .cgi</programlisting> 16.1099 - 16.1100 - <para id="x_4ce">The next possibility is that you might be served with a 16.1101 - colourful Python backtrace claiming that it can't import a 16.1102 - <literal>mercurial</literal>-related module. This is 16.1103 - actually progress! The server is now capable of executing 16.1104 - your CGI script. This error is only likely to occur if 16.1105 - you're running a private installation of Mercurial, instead 16.1106 - of a system-wide version. Remember that the web server runs 16.1107 - the CGI program without any of the environment variables 16.1108 - that you take for granted in an interactive session. If 16.1109 - this error happens to you, edit your copy of <filename 16.1110 - role="special">hgweb.cgi</filename> and follow the 16.1111 - directions inside it to correctly set your 16.1112 - <envar>PYTHONPATH</envar> environment variable.</para> 16.1113 - 16.1114 - <para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to by 16.1115 - served with another colourful Python backtrace: this one 16.1116 - will complain that it can't find <filename 16.1117 - class="directory">/path/to/repository</filename>. Edit 16.1118 - your <filename role="special">hgweb.cgi</filename> script 16.1119 - and replace the <filename 16.1120 - class="directory">/path/to/repository</filename> string 16.1121 - with the complete path to the repository you want to serve 16.1122 - up.</para> 16.1123 - 16.1124 - <para id="x_4d0">At this point, when you try to reload the page, you 16.1125 - should be presented with a nice HTML view of your 16.1126 - repository's history. Whew!</para> 16.1127 - </sect3> 16.1128 - 16.1129 - <sect3> 16.1130 - <title>Configuring lighttpd</title> 16.1131 - 16.1132 - <para id="x_4d1">To be exhaustive in my experiments, I tried configuring 16.1133 - the increasingly popular <literal>lighttpd</literal> web 16.1134 - server to serve the same repository as I described with 16.1135 - Apache above. I had already overcome all of the problems I 16.1136 - outlined with Apache, many of which are not server-specific. 16.1137 - As a result, I was fairly sure that my file and directory 16.1138 - permissions were good, and that my <filename 16.1139 - role="special">hgweb.cgi</filename> script was properly 16.1140 - edited.</para> 16.1141 - 16.1142 - <para id="x_4d2">Once I had Apache running, getting 16.1143 - <literal>lighttpd</literal> to serve the repository was a 16.1144 - snap (in other words, even if you're trying to use 16.1145 - <literal>lighttpd</literal>, you should read the Apache 16.1146 - section). I first had to edit the 16.1147 - <literal>mod_access</literal> section of its config file to 16.1148 - enable <literal>mod_cgi</literal> and 16.1149 - <literal>mod_userdir</literal>, both of which were disabled 16.1150 - by default on my system. I then added a few lines to the 16.1151 - end of the config file, to configure these modules.</para> 16.1152 - <programlisting>userdir.path = "public_html" 16.1153 -cgi.assign = (".cgi" => "" )</programlisting> 16.1154 - <para id="x_4d3">With this done, <literal>lighttpd</literal> ran 16.1155 - immediately for me. If I had configured 16.1156 - <literal>lighttpd</literal> before Apache, I'd almost 16.1157 - certainly have run into many of the same system-level 16.1158 - configuration problems as I did with Apache. However, I 16.1159 - found <literal>lighttpd</literal> to be noticeably easier to 16.1160 - configure than Apache, even though I've used Apache for over 16.1161 - a decade, and this was my first exposure to 16.1162 - <literal>lighttpd</literal>.</para> 16.1163 - </sect3> 16.1164 - </sect2> 16.1165 - 16.1166 - <sect2> 16.1167 - <title>Sharing multiple repositories with one CGI script</title> 16.1168 - 16.1169 - <para id="x_4d4">The <filename role="special">hgweb.cgi</filename> script 16.1170 - only lets you publish a single repository, which is an 16.1171 - annoying restriction. If you want to publish more than one 16.1172 - without wracking yourself with multiple copies of the same 16.1173 - script, each with different names, a better choice is to use 16.1174 - the <filename role="special">hgwebdir.cgi</filename> 16.1175 - script.</para> 16.1176 - 16.1177 - <para id="x_4d5">The procedure to configure <filename 16.1178 - role="special">hgwebdir.cgi</filename> is only a little more 16.1179 - involved than for <filename 16.1180 - role="special">hgweb.cgi</filename>. First, you must obtain 16.1181 - a copy of the script. If you don't have one handy, you can 16.1182 - download a copy from the master Mercurial repository at <ulink 16.1183 - 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> 16.1184 - 16.1185 - <para id="x_4d6">You'll need to copy this script into your <filename 16.1186 - class="directory">public_html</filename> directory, and 16.1187 - ensure that it's executable.</para> 16.1188 - 16.1189 - <programlisting>cp .../hgwebdir.cgi ~/public_html 16.1190 -chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting> 16.1191 - 16.1192 - <para id="x_4d7">With basic configuration out of the way, try to 16.1193 - visit <ulink url="http://myhostname/ 16.1194 - myuser/hgwebdir.cgi">http://myhostname/ 16.1195 - myuser/hgwebdir.cgi</ulink> in your browser. It should 16.1196 - display an empty list of repositories. If you get a blank 16.1197 - window or error message, try walking through the list of 16.1198 - potential problems in <xref 16.1199 - linkend="sec:collab:wtf"/>.</para> 16.1200 - 16.1201 - <para id="x_4d8">The <filename role="special">hgwebdir.cgi</filename> 16.1202 - script relies on an external configuration file. By default, 16.1203 - it searches for a file named <filename 16.1204 - role="special">hgweb.config</filename> in the same directory 16.1205 - as itself. You'll need to create this file, and make it 16.1206 - world-readable. The format of the file is similar to a 16.1207 - Windows <quote>ini</quote> file, as understood by Python's 16.1208 - <literal>ConfigParser</literal> 16.1209 - <citation>web:configparser</citation> module.</para> 16.1210 - 16.1211 - <para id="x_4d9">The easiest way to configure <filename 16.1212 - role="special">hgwebdir.cgi</filename> is with a section 16.1213 - named <literal>collections</literal>. This will automatically 16.1214 - publish <emphasis>every</emphasis> repository under the 16.1215 - directories you name. The section should look like 16.1216 - this:</para> 16.1217 - <programlisting>[collections] 16.1218 -/my/root = /my/root</programlisting> 16.1219 - <para id="x_4da">Mercurial interprets this by looking at the directory name 16.1220 - on the <emphasis>right</emphasis> hand side of the 16.1221 - <quote><literal>=</literal></quote> sign; finding repositories 16.1222 - in that directory hierarchy; and using the text on the 16.1223 - <emphasis>left</emphasis> to strip off matching text from the 16.1224 - names it will actually list in the web interface. The 16.1225 - remaining component of a path after this stripping has 16.1226 - occurred is called a <quote>virtual path</quote>.</para> 16.1227 - 16.1228 - <para id="x_4db">Given the example above, if we have a repository whose 16.1229 - local path is <filename 16.1230 - class="directory">/my/root/this/repo</filename>, the CGI 16.1231 - script will strip the leading <filename 16.1232 - class="directory">/my/root</filename> from the name, and 16.1233 - publish the repository with a virtual path of <filename 16.1234 - class="directory">this/repo</filename>. If the base URL for 16.1235 - our CGI script is <ulink url="http://myhostname/ 16.1236 - myuser/hgwebdir.cgi">http://myhostname/ 16.1237 - myuser/hgwebdir.cgi</ulink>, the complete URL for that 16.1238 - repository will be <ulink url="http://myhostname/ 16.1239 - myuser/hgwebdir.cgi/this/repo">http://myhostname/ 16.1240 - myuser/hgwebdir.cgi/this/repo</ulink>.</para> 16.1241 - 16.1242 - <para id="x_4dc">If we replace <filename 16.1243 - class="directory">/my/root</filename> on the left hand side 16.1244 - of this example with <filename 16.1245 - class="directory">/my</filename>, then <filename 16.1246 - role="special">hgwebdir.cgi</filename> will only strip off 16.1247 - <filename class="directory">/my</filename> from the repository 16.1248 - name, and will give us a virtual path of <filename 16.1249 - class="directory">root/this/repo</filename> instead of 16.1250 - <filename class="directory">this/repo</filename>.</para> 16.1251 - 16.1252 - <para id="x_4dd">The <filename role="special">hgwebdir.cgi</filename> 16.1253 - script will recursively search each directory listed in the 16.1254 - <literal>collections</literal> section of its configuration 16.1255 - file, but it will <literal>not</literal> recurse into the 16.1256 - repositories it finds.</para> 16.1257 - 16.1258 - <para id="x_4de">The <literal>collections</literal> mechanism makes it easy 16.1259 - to publish many repositories in a <quote>fire and 16.1260 - forget</quote> manner. You only need to set up the CGI 16.1261 - script and configuration file one time. Afterwards, you can 16.1262 - publish or unpublish a repository at any time by simply moving 16.1263 - it into, or out of, the directory hierarchy in which you've 16.1264 - configured <filename role="special">hgwebdir.cgi</filename> to 16.1265 - look.</para> 16.1266 - 16.1267 - <sect3> 16.1268 - <title>Explicitly specifying which repositories to 16.1269 - publish</title> 16.1270 - 16.1271 - <para id="x_4df">In addition to the <literal>collections</literal> 16.1272 - mechanism, the <filename 16.1273 - role="special">hgwebdir.cgi</filename> script allows you 16.1274 - to publish a specific list of repositories. To do so, 16.1275 - create a <literal>paths</literal> section, with contents of 16.1276 - the following form.</para> 16.1277 - <programlisting>[paths] 16.1278 -repo1 = /my/path/to/some/repo 16.1279 -repo2 = /some/path/to/another</programlisting> 16.1280 - <para id="x_4e0">In this case, the virtual path (the component that will 16.1281 - appear in a URL) is on the left hand side of each 16.1282 - definition, while the path to the repository is on the 16.1283 - right. Notice that there does not need to be any 16.1284 - relationship between the virtual path you choose and the 16.1285 - location of a repository in your filesystem.</para> 16.1286 - 16.1287 - <para id="x_4e1">If you wish, you can use both the 16.1288 - <literal>collections</literal> and <literal>paths</literal> 16.1289 - mechanisms simultaneously in a single configuration 16.1290 - file.</para> 16.1291 - 16.1292 - <note> 16.1293 - <title>Beware duplicate virtual paths</title> 16.1294 - 16.1295 - <para id="x_4e2"> If several repositories have the same 16.1296 - virtual path, <filename 16.1297 - role="special">hgwebdir.cgi</filename> will not report 16.1298 - an error. Instead, it will behave unpredictably.</para> 16.1299 - </note> 16.1300 - </sect3> 16.1301 - </sect2> 16.1302 - 16.1303 - <sect2> 16.1304 - <title>Downloading source archives</title> 16.1305 - 16.1306 - <para id="x_4e3">Mercurial's web interface lets users download an archive 16.1307 - of any revision. This archive will contain a snapshot of the 16.1308 - working directory as of that revision, but it will not contain 16.1309 - a copy of the repository data.</para> 16.1310 - 16.1311 - <para id="x_4e4">By default, this feature is not enabled. To enable it, 16.1312 - you'll need to add an <envar 16.1313 - role="rc-item-web">allow_archive</envar> item to the 16.1314 - <literal role="rc-web">web</literal> section of your <filename 16.1315 - role="special">~/.hgrc</filename>; see below for details.</para> 16.1316 - </sect2> 16.1317 - <sect2> 16.1318 - <title>Web configuration options</title> 16.1319 - 16.1320 - <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd">hg 16.1321 - serve</command> command, and the <filename 16.1322 - role="special">hgweb.cgi</filename> and <filename 16.1323 - role="special">hgwebdir.cgi</filename> scripts) have a 16.1324 - number of configuration options that you can set. These 16.1325 - belong in a section named <literal 16.1326 - role="rc-web">web</literal>.</para> 16.1327 - <itemizedlist> 16.1328 - <listitem><para id="x_4e6"><envar 16.1329 - role="rc-item-web">allow_archive</envar>: Determines 16.1330 - which (if any) archive download mechanisms Mercurial 16.1331 - supports. If you enable this feature, users of the web 16.1332 - interface will be able to download an archive of whatever 16.1333 - revision of a repository they are viewing. To enable the 16.1334 - archive feature, this item must take the form of a 16.1335 - sequence of words drawn from the list below.</para> 16.1336 - <itemizedlist> 16.1337 - <listitem><para id="x_4e7"><literal>bz2</literal>: A 16.1338 - <command>tar</command> archive, compressed using 16.1339 - <literal>bzip2</literal> compression. This has the 16.1340 - best compression ratio, but uses the most CPU time on 16.1341 - the server.</para> 16.1342 - </listitem> 16.1343 - <listitem><para id="x_4e8"><literal>gz</literal>: A 16.1344 - <command>tar</command> archive, compressed using 16.1345 - <literal>gzip</literal> compression.</para> 16.1346 - </listitem> 16.1347 - <listitem><para id="x_4e9"><literal>zip</literal>: A 16.1348 - <command>zip</command> archive, compressed using LZW 16.1349 - compression. This format has the worst compression 16.1350 - ratio, but is widely used in the Windows world.</para> 16.1351 - </listitem> 16.1352 - </itemizedlist> 16.1353 - <para id="x_4ea"> If you provide an empty list, or don't have an 16.1354 - <envar role="rc-item-web">allow_archive</envar> entry at 16.1355 - all, this feature will be disabled. Here is an example of 16.1356 - how to enable all three supported formats.</para> 16.1357 - <programlisting>[web] 16.1358 -allow_archive = bz2 gz zip</programlisting> 16.1359 - </listitem> 16.1360 - <listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>: 16.1361 - Boolean. Determines whether the web interface allows 16.1362 - remote users to <command role="hg-cmd">hg pull</command> 16.1363 - and <command role="hg-cmd">hg clone</command> this 16.1364 - repository over HTTP. If set to <literal>no</literal> or 16.1365 - <literal>false</literal>, only the 16.1366 - <quote>human-oriented</quote> portion of the web interface 16.1367 - is available.</para> 16.1368 - </listitem> 16.1369 - <listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>: 16.1370 - String. A free-form (but preferably brief) string 16.1371 - identifying the person or group in charge of the 16.1372 - repository. This often contains the name and email 16.1373 - address of a person or mailing list. It often makes sense 16.1374 - to place this entry in a repository's own <filename 16.1375 - role="special">.hg/hgrc</filename> file, but it can make 16.1376 - sense to use in a global <filename 16.1377 - role="special">~/.hgrc</filename> if every repository 16.1378 - has a single maintainer.</para> 16.1379 - </listitem> 16.1380 - <listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>: 16.1381 - Integer. The default maximum number of changesets to 16.1382 - display in a single page of output.</para> 16.1383 - </listitem> 16.1384 - <listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>: 16.1385 - Integer. The default maximum number of modified files to 16.1386 - display in a single page of output.</para> 16.1387 - </listitem> 16.1388 - <listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>: 16.1389 - Integer. If the web interface displays alternating 16.1390 - <quote>stripes</quote> to make it easier to visually align 16.1391 - rows when you are looking at a table, this number controls 16.1392 - the number of rows in each stripe.</para> 16.1393 - </listitem> 16.1394 - <listitem><para id="x_4f0"><envar 16.1395 - role="rc-item-web">style</envar>: Controls the template 16.1396 - Mercurial uses to display the web interface. Mercurial 16.1397 - ships with several web templates.</para> 16.1398 - <itemizedlist> 16.1399 - <listitem> 16.1400 - <para id="x_6aa"><literal>coal</literal> is monochromatic.</para> 16.1401 - </listitem> 16.1402 - <listitem> 16.1403 - <para id="x_6ab"><literal>gitweb</literal> emulates the visual 16.1404 - style of git's web interface.</para> 16.1405 - </listitem> 16.1406 - <listitem> 16.1407 - <para id="x_6ac"><literal>monoblue</literal> uses solid blues and 16.1408 - greys.</para> 16.1409 - </listitem> 16.1410 - <listitem> 16.1411 - <para id="x_6ad"><literal>paper</literal> is the default.</para> 16.1412 - </listitem> 16.1413 - <listitem> 16.1414 - <para id="x_6ae"><literal>spartan</literal> was the default for a 16.1415 - long time.</para> 16.1416 - </listitem> 16.1417 - </itemizedlist> 16.1418 - <para id="x_6af">You can 16.1419 - also specify a custom template of your own; see 16.1420 - <xref linkend="chap:template"/> for details. Here, you can 16.1421 - see how to enable the <literal>gitweb</literal> 16.1422 - style.</para> 16.1423 - <programlisting>[web] 16.1424 -style = gitweb</programlisting> 16.1425 - </listitem> 16.1426 - <listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>: 16.1427 - Path. The directory in which to search for template 16.1428 - files. By default, Mercurial searches in the directory in 16.1429 - which it was installed.</para> 16.1430 - </listitem></itemizedlist> 16.1431 - <para id="x_4f2">If you are using <filename 16.1432 - role="special">hgwebdir.cgi</filename>, you can place a few 16.1433 - configuration items in a <literal role="rc-web">web</literal> 16.1434 - section of the <filename 16.1435 - role="special">hgweb.config</filename> file instead of a 16.1436 - <filename role="special">~/.hgrc</filename> file, for 16.1437 - convenience. These items are <envar 16.1438 - role="rc-item-web">motd</envar> and <envar 16.1439 - role="rc-item-web">style</envar>.</para> 16.1440 - 16.1441 - <sect3> 16.1442 - <title>Options specific to an individual repository</title> 16.1443 - 16.1444 - <para id="x_4f3">A few <literal role="rc-web">web</literal> configuration 16.1445 - items ought to be placed in a repository's local <filename 16.1446 - role="special">.hg/hgrc</filename>, rather than a user's 16.1447 - or global <filename role="special">~/.hgrc</filename>.</para> 16.1448 - <itemizedlist> 16.1449 - <listitem><para id="x_4f4"><envar 16.1450 - role="rc-item-web">description</envar>: String. A 16.1451 - free-form (but preferably brief) string that describes 16.1452 - the contents or purpose of the repository.</para> 16.1453 - </listitem> 16.1454 - <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>: 16.1455 - String. The name to use for the repository in the web 16.1456 - interface. This overrides the default name, which is 16.1457 - the last component of the repository's path.</para> 16.1458 - </listitem></itemizedlist> 16.1459 - </sect3> 16.1460 - 16.1461 - <sect3> 16.1462 - <title>Options specific to the <command role="hg-cmd">hg 16.1463 - serve</command> command</title> 16.1464 - 16.1465 - <para id="x_4f6">Some of the items in the <literal 16.1466 - role="rc-web">web</literal> section of a <filename 16.1467 - role="special">~/.hgrc</filename> file are only for use 16.1468 - with the <command role="hg-cmd">hg serve</command> 16.1469 - command.</para> 16.1470 - <itemizedlist> 16.1471 - <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>: 16.1472 - Path. The name of a file into which to write an access 16.1473 - log. By default, the <command role="hg-cmd">hg 16.1474 - serve</command> command writes this information to 16.1475 - standard output, not to a file. Log entries are written 16.1476 - in the standard <quote>combined</quote> file format used 16.1477 - by almost all web servers.</para> 16.1478 - </listitem> 16.1479 - <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>: 16.1480 - String. The local address on which the server should 16.1481 - listen for incoming connections. By default, the server 16.1482 - listens on all addresses.</para> 16.1483 - </listitem> 16.1484 - <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>: 16.1485 - Path. The name of a file into which to write an error 16.1486 - log. By default, the <command role="hg-cmd">hg 16.1487 - serve</command> command writes this information to 16.1488 - standard error, not to a file.</para> 16.1489 - </listitem> 16.1490 - <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>: 16.1491 - Boolean. Whether to use the IPv6 protocol. By default, 16.1492 - IPv6 is not used.</para> 16.1493 - </listitem> 16.1494 - <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>: 16.1495 - Integer. The TCP port number on which the server should 16.1496 - listen. The default port number used is 8000.</para> 16.1497 - </listitem></itemizedlist> 16.1498 - </sect3> 16.1499 - 16.1500 - <sect3> 16.1501 - <title>Choosing the right <filename 16.1502 - role="special">~/.hgrc</filename> file to add <literal 16.1503 - role="rc-web">web</literal> items to</title> 16.1504 - 16.1505 - <para id="x_4fc">It is important to remember that a web server like 16.1506 - Apache or <literal>lighttpd</literal> will run under a user 16.1507 - ID that is different to yours. CGI scripts run by your 16.1508 - server, such as <filename 16.1509 - role="special">hgweb.cgi</filename>, will usually also run 16.1510 - under that user ID.</para> 16.1511 - 16.1512 - <para id="x_4fd">If you add <literal role="rc-web">web</literal> items to 16.1513 - your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that 16.1514 - <filename role="special">~/.hgrc</filename> file. Those 16.1515 - settings will thus only affect the behavior of the <command 16.1516 - role="hg-cmd">hg serve</command> command when you run it. 16.1517 - To cause CGI scripts to see your settings, either create a 16.1518 - <filename role="special">~/.hgrc</filename> file in the 16.1519 - home directory of the user ID that runs your web server, or 16.1520 - add those settings to a system-wide <filename 16.1521 - role="special">hgrc</filename> file.</para> 16.1522 - </sect3> 16.1523 - </sect2> 16.1524 - </sect1> 16.1525 - 16.1526 - <sect1> 16.1527 - <title>System-wide configuration</title> 16.1528 - 16.1529 - <para id="x_6b0">On Unix-like systems shared by multiple users (such as a 16.1530 - server to which people publish changes), it often makes sense to 16.1531 - set up some global default behaviors, such as what theme to use 16.1532 - in web interfaces.</para> 16.1533 - 16.1534 - <para id="x_6b1">If a file named <filename>/etc/mercurial/hgrc</filename> 16.1535 - exists, Mercurial will read it at startup time and apply any 16.1536 - configuration settings it finds in that file. It will also look 16.1537 - for files ending in a <literal>.rc</literal> extension in a 16.1538 - directory named <filename>/etc/mercurial/hgrc.d</filename>, and 16.1539 - apply any configuration settings it finds in each of those 16.1540 - files.</para> 16.1541 - 16.1542 - <sect2> 16.1543 - <title>Making Mercurial more trusting</title> 16.1544 - 16.1545 - <para id="x_6b2">One situation in which a global <filename>hgrc</filename> 16.1546 - can be useful is if users are pulling changes owned by other 16.1547 - users. By default, Mercurial will not trust most of the 16.1548 - configuration items in a <filename>.hg/hgrc</filename> file 16.1549 - inside a repository that is owned by a different user. If we 16.1550 - clone or pull changes from such a repository, Mercurial will 16.1551 - print a warning stating that it does not trust their 16.1552 - <filename>.hg/hgrc</filename>.</para> 16.1553 - 16.1554 - <para id="x_6b3">If everyone in a particular Unix group is on the same team 16.1555 - and <emphasis>should</emphasis> trust each other's 16.1556 - configuration settings, or we want to trust particular users, 16.1557 - we can override Mercurial's skeptical defaults by creating a 16.1558 - system-wide <filename>hgrc</filename> file such as the 16.1559 - following:</para> 16.1560 - 16.1561 - <programlisting># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc 16.1562 -[trusted] 16.1563 -# Trust all entries in any hgrc file owned by the "editors" or 16.1564 -# "www-data" groups. 16.1565 -groups = editors, www-data 16.1566 - 16.1567 -# Trust entries in hgrc files owned by the following users. 16.1568 -users = apache, bobo 16.1569 -</programlisting> 16.1570 - </sect2> 16.1571 - </sect1> 16.1572 -</chapter> 16.1573 - 16.1574 -<!-- 16.1575 -local variables: 16.1576 -sgml-parent-document: ("00book.xml" "book" "chapter") 16.1577 -end: 16.1578 --->
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/en/ch05-daily.xml Thu May 21 14:16:17 2009 +0800 17.3 @@ -0,0 +1,840 @@ 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 by default, <command 17.33 + role="hg-cmd">hg status</command> only tells you about 17.34 + <quote>interesting</quote> files&emdash;those that you have (for 17.35 + example) modified, removed, or renamed. If you have a repository 17.36 + that contains thousands of files, you will rarely want to know 17.37 + about files that Mercurial is tracking, but that have not 17.38 + changed. (You can still get this information; we'll return to 17.39 + 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 behavior 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 17.58 + the names of the files it added, whereas it didn't do so when 17.59 + we added the file named <filename>myfile.txt</filename> in the 17.60 + earlier 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. The assumption 17.64 + that Mercurial makes in such cases is that we know what we 17.65 + are 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 behavior is common to most Mercurial commands.</para> 17.73 + </sect2> 17.74 + 17.75 + <sect2> 17.76 + <title>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 + </sect2> 17.109 + </sect1> 17.110 + 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 17.115 + your repository, use the <command role="hg-cmd">hg 17.116 + remove</command> command. This deletes the file, and tells 17.117 + Mercurial to stop tracking it (which will occur at the next 17.118 + commit). A removed file is represented in the output of 17.119 + <command role="hg-cmd">hg status</command> with a 17.120 + <quote><literal>R</literal></quote>.</para> 17.121 + 17.122 + &interaction.daily.files.remove; 17.123 + 17.124 + <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file, 17.125 + Mercurial will no longer track changes to that file, even if you 17.126 + recreate a file with the same name in your working directory. 17.127 + If you do recreate a file with the same name and want Mercurial 17.128 + to track the new file, simply <command role="hg-cmd">hg 17.129 + add</command> it. Mercurial will know that the newly added 17.130 + file is not related to the old file of the same name.</para> 17.131 + 17.132 + <sect2> 17.133 + <title>Removing a file does not affect its history</title> 17.134 + 17.135 + <para id="x_1b1">It is important to understand that removing a file has 17.136 + only two effects.</para> 17.137 + <itemizedlist> 17.138 + <listitem><para id="x_1b2">It removes the current version of the file 17.139 + from the working directory.</para> 17.140 + </listitem> 17.141 + <listitem><para id="x_1b3">It stops Mercurial from tracking changes to 17.142 + the file, from the time of the next commit.</para> 17.143 + </listitem></itemizedlist> 17.144 + <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way 17.145 + alter the <emphasis>history</emphasis> of the file.</para> 17.146 + 17.147 + <para id="x_1b5">If you update the working directory to a 17.148 + changeset that was committed when it was still tracking a file 17.149 + that you later removed, the file will reappear in the working 17.150 + directory, with the contents it had when you committed that 17.151 + changeset. If you then update the working directory to a 17.152 + later changeset, in which the file had been removed, Mercurial 17.153 + will once again remove the file from the working 17.154 + directory.</para> 17.155 + </sect2> 17.156 + 17.157 + <sect2> 17.158 + <title>Missing files</title> 17.159 + 17.160 + <para id="x_1b6">Mercurial considers a file that you have deleted, but not 17.161 + used <command role="hg-cmd">hg remove</command> to delete, to 17.162 + be <emphasis>missing</emphasis>. A missing file is 17.163 + represented with <quote><literal>!</literal></quote> in the 17.164 + output of <command role="hg-cmd">hg status</command>. 17.165 + Mercurial commands will not generally do anything with missing 17.166 + files.</para> 17.167 + 17.168 + &interaction.daily.files.missing; 17.169 + 17.170 + <para id="x_1b7">If your repository contains a file that <command 17.171 + role="hg-cmd">hg status</command> reports as missing, and 17.172 + you want the file to stay gone, you can run <command 17.173 + role="hg-cmd">hg remove <option 17.174 + role="hg-opt-remove">--after</option></command> at any 17.175 + time later on, to tell Mercurial that you really did mean to 17.176 + remove the file.</para> 17.177 + 17.178 + &interaction.daily.files.remove-after; 17.179 + 17.180 + <para id="x_1b8">On the other hand, if you deleted the missing file by 17.181 + accident, give <command role="hg-cmd">hg revert</command> the 17.182 + name of the file to recover. It will reappear, in unmodified 17.183 + form.</para> 17.184 + 17.185 + &interaction.daily.files.recover-missing; 17.186 + </sect2> 17.187 + 17.188 + <sect2> 17.189 + <title>Aside: why tell Mercurial explicitly to remove a 17.190 + file?</title> 17.191 + 17.192 + <para id="x_1b9">You might wonder why Mercurial requires you to explicitly 17.193 + tell it that you are deleting a file. Early during the 17.194 + development of Mercurial, it let you delete a file however you 17.195 + pleased; Mercurial would notice the absence of the file 17.196 + automatically when you next ran a <command role="hg-cmd">hg 17.197 + commit</command>, and stop tracking the file. In practice, 17.198 + this made it too easy to accidentally remove a file without 17.199 + noticing.</para> 17.200 + </sect2> 17.201 + 17.202 + <sect2> 17.203 + <title>Useful shorthand&emdash;adding and removing files in one 17.204 + step</title> 17.205 + 17.206 + <para id="x_1ba">Mercurial offers a combination command, <command 17.207 + role="hg-cmd">hg addremove</command>, that adds untracked 17.208 + files and marks missing files as removed.</para> 17.209 + 17.210 + &interaction.daily.files.addremove; 17.211 + 17.212 + <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command 17.213 + also provides a <option role="hg-opt-commit">-A</option> 17.214 + option that performs this same add-and-remove, immediately 17.215 + followed by a commit.</para> 17.216 + 17.217 + &interaction.daily.files.commit-addremove; 17.218 + </sect2> 17.219 + </sect1> 17.220 + 17.221 + <sect1 id="chap:daily.copy"> 17.222 + <title>Copying files</title> 17.223 + 17.224 + <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg 17.225 + copy</command> command that lets you make a new copy of a 17.226 + file. When you copy a file using this command, Mercurial makes 17.227 + a record of the fact that the new file is a copy of the original 17.228 + file. It treats these copied files specially when you merge 17.229 + your work with someone else's.</para> 17.230 + 17.231 + <sect2> 17.232 + <title>The results of copying during a merge</title> 17.233 + 17.234 + <para id="x_1bd">What happens during a merge is that changes 17.235 + <quote>follow</quote> a copy. To best illustrate what this 17.236 + means, let's create an example. We'll start with the usual 17.237 + tiny repository that contains a single file.</para> 17.238 + 17.239 + &interaction.daily.copy.init; 17.240 + 17.241 + <para id="x_1be">We need to do some work in 17.242 + parallel, so that we'll have something to merge. So let's 17.243 + clone our repository.</para> 17.244 + 17.245 + &interaction.daily.copy.clone; 17.246 + 17.247 + <para id="x_1bf">Back in our initial repository, let's use the <command 17.248 + role="hg-cmd">hg copy</command> command to make a copy of 17.249 + the first file we created.</para> 17.250 + 17.251 + &interaction.daily.copy.copy; 17.252 + 17.253 + <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg 17.254 + status</command> command afterwards, the copied file looks 17.255 + just like a normal added file.</para> 17.256 + 17.257 + &interaction.daily.copy.status; 17.258 + 17.259 + <para id="x_1c1">But if we pass the <option 17.260 + role="hg-opt-status">-C</option> option to <command 17.261 + role="hg-cmd">hg status</command>, it prints another line of 17.262 + output: this is the file that our newly-added file was copied 17.263 + <emphasis>from</emphasis>.</para> 17.264 + 17.265 + &interaction.daily.copy.status-copy; 17.266 + 17.267 + <para id="x_1c2">Now, back in the repository we cloned, let's make a change 17.268 + in parallel. We'll add a line of content to the original file 17.269 + that we created.</para> 17.270 + 17.271 + &interaction.daily.copy.other; 17.272 + 17.273 + <para id="x_1c3">Now we have a modified <filename>file</filename> in this 17.274 + repository. When we pull the changes from the first 17.275 + repository, and merge the two heads, Mercurial will propagate 17.276 + the changes that we made locally to <filename>file</filename> 17.277 + into its copy, <filename>new-file</filename>.</para> 17.278 + 17.279 + &interaction.daily.copy.merge; 17.280 + </sect2> 17.281 + 17.282 + <sect2 id="sec:daily:why-copy"> 17.283 + <title>Why should changes follow copies?</title> 17.284 + 17.285 + <para id="x_1c4">This behavior&emdash;of changes to a file 17.286 + propagating out to copies of the file&emdash;might seem 17.287 + esoteric, but in most cases it's highly desirable.</para> 17.288 + 17.289 + <para id="x_1c5">First of all, remember that this propagation 17.290 + <emphasis>only</emphasis> happens when you merge. So if you 17.291 + <command role="hg-cmd">hg copy</command> a file, and 17.292 + subsequently modify the original file during the normal course 17.293 + of your work, nothing will happen.</para> 17.294 + 17.295 + <para id="x_1c6">The second thing to know is that modifications will only 17.296 + propagate across a copy as long as the changeset that you're 17.297 + merging changes from <emphasis>hasn't yet seen</emphasis> 17.298 + the copy.</para> 17.299 + 17.300 + <para id="x_1c7">The reason that Mercurial does this is as follows. Let's 17.301 + say I make an important bug fix in a source file, and commit 17.302 + my changes. Meanwhile, you've decided to <command 17.303 + role="hg-cmd">hg copy</command> the file in your repository, 17.304 + without knowing about the bug or having seen the fix, and you 17.305 + have started hacking on your copy of the file.</para> 17.306 + 17.307 + <para id="x_1c8">If you pulled and merged my changes, and Mercurial 17.308 + <emphasis>didn't</emphasis> propagate changes across copies, 17.309 + your new source file would now contain the bug, and unless you 17.310 + knew to propagate the bug fix by hand, the bug would 17.311 + <emphasis>remain</emphasis> in your copy of the file.</para> 17.312 + 17.313 + <para id="x_1c9">By automatically propagating the change that fixed the bug 17.314 + from the original file to the copy, Mercurial prevents this 17.315 + class of problem. To my knowledge, Mercurial is the 17.316 + <emphasis>only</emphasis> revision control system that 17.317 + propagates changes across copies like this.</para> 17.318 + 17.319 + <para id="x_1ca">Once your change history has a record that the copy and 17.320 + subsequent merge occurred, there's usually no further need to 17.321 + propagate changes from the original file to the copied file, 17.322 + and that's why Mercurial only propagates changes across copies 17.323 + at the first merge, and not afterwards.</para> 17.324 + </sect2> 17.325 + 17.326 + <sect2> 17.327 + <title>How to make changes <emphasis>not</emphasis> follow a 17.328 + copy</title> 17.329 + 17.330 + <para id="x_1cb">If, for some reason, you decide that this business of 17.331 + automatically propagating changes across copies is not for 17.332 + you, simply use your system's normal file copy command (on 17.333 + Unix-like systems, that's <command>cp</command>) to make a 17.334 + copy of a file, then <command role="hg-cmd">hg add</command> 17.335 + the new copy by hand. Before you do so, though, please do 17.336 + reread <xref linkend="sec:daily:why-copy"/>, and make 17.337 + an informed 17.338 + decision that this behavior is not appropriate to your 17.339 + specific case.</para> 17.340 + 17.341 + </sect2> 17.342 + <sect2> 17.343 + <title>Behavior of the <command role="hg-cmd">hg copy</command> 17.344 + command</title> 17.345 + 17.346 + <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command> 17.347 + command, Mercurial makes a copy of each source file as it 17.348 + currently stands in the working directory. This means that if 17.349 + you make some modifications to a file, then <command 17.350 + role="hg-cmd">hg copy</command> it without first having 17.351 + committed those changes, the new copy will also contain the 17.352 + modifications you have made up until that point. (I find this 17.353 + behavior a little counterintuitive, which is why I mention it 17.354 + here.)</para> 17.355 + 17.356 + <para id="x_1cd">The <command role="hg-cmd">hg copy</command> 17.357 + command acts similarly to the Unix <command>cp</command> 17.358 + command (you can use the <command role="hg-cmd">hg 17.359 + cp</command> alias if you prefer). We must supply two or 17.360 + more arguments, of which the last is treated as the 17.361 + <emphasis>destination</emphasis>, and all others are 17.362 + <emphasis>sources</emphasis>.</para> 17.363 + 17.364 + <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a 17.365 + single file as the source, and the destination does not exist, 17.366 + it creates a new file with that name.</para> 17.367 + 17.368 + &interaction.daily.copy.simple; 17.369 + 17.370 + <para id="x_1ce">If the destination is a directory, Mercurial copies its 17.371 + sources into that directory.</para> 17.372 + 17.373 + &interaction.daily.copy.dir-dest; 17.374 + 17.375 + <para id="x_1cf">Copying a directory is 17.376 + recursive, and preserves the directory structure of the 17.377 + source.</para> 17.378 + 17.379 + &interaction.daily.copy.dir-src; 17.380 + 17.381 + <para id="x_1d0">If the source and destination are both directories, the 17.382 + source tree is recreated in the destination directory.</para> 17.383 + 17.384 + &interaction.daily.copy.dir-src-dest; 17.385 + 17.386 + <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command> 17.387 + command, if you copy a file manually and then want Mercurial 17.388 + to know that you've copied the file, simply use the <option 17.389 + role="hg-opt-copy">--after</option> option to <command 17.390 + role="hg-cmd">hg copy</command>.</para> 17.391 + 17.392 + &interaction.daily.copy.after; 17.393 + </sect2> 17.394 + </sect1> 17.395 + 17.396 + <sect1> 17.397 + <title>Renaming files</title> 17.398 + 17.399 + <para id="x_1d2">It's rather more common to need to rename a file than to 17.400 + make a copy of it. The reason I discussed the <command 17.401 + role="hg-cmd">hg copy</command> command before talking about 17.402 + renaming files is that Mercurial treats a rename in essentially 17.403 + the same way as a copy. Therefore, knowing what Mercurial does 17.404 + when you copy a file tells you what to expect when you rename a 17.405 + file.</para> 17.406 + 17.407 + <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command> 17.408 + command, Mercurial makes a copy of each source file, then 17.409 + deletes it and marks the file as removed.</para> 17.410 + 17.411 + &interaction.daily.rename.rename; 17.412 + 17.413 + <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows 17.414 + the newly copied file as added, and the copied-from file as 17.415 + removed.</para> 17.416 + 17.417 + &interaction.daily.rename.status; 17.418 + 17.419 + <para id="x_1d5">As with the results of a <command role="hg-cmd">hg 17.420 + copy</command>, we must use the <option 17.421 + role="hg-opt-status">-C</option> option to <command 17.422 + role="hg-cmd">hg status</command> to see that the added file 17.423 + is really being tracked by Mercurial as a copy of the original, 17.424 + now removed, file.</para> 17.425 + 17.426 + &interaction.daily.rename.status-copy; 17.427 + 17.428 + <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and 17.429 + <command role="hg-cmd">hg copy</command>, you can tell Mercurial 17.430 + about a rename after the fact using the <option 17.431 + role="hg-opt-rename">--after</option> option. In most other 17.432 + respects, the behavior of the <command role="hg-cmd">hg 17.433 + rename</command> command, and the options it accepts, are 17.434 + similar to the <command role="hg-cmd">hg copy</command> 17.435 + command.</para> 17.436 + 17.437 + <para id="x_686">If you're familiar with the Unix command line, you'll be 17.438 + glad to know that <command role="hg-cmd">hg rename</command> 17.439 + command can be invoked as <command role="hg-cmd">hg 17.440 + mv</command>.</para> 17.441 + 17.442 + <sect2> 17.443 + <title>Renaming files and merging changes</title> 17.444 + 17.445 + <para id="x_1d7">Since Mercurial's rename is implemented as 17.446 + copy-and-remove, the same propagation of changes happens when 17.447 + you merge after a rename as after a copy.</para> 17.448 + 17.449 + <para id="x_1d8">If I modify a file, and you rename it to a new name, and 17.450 + then we merge our respective changes, my modifications to the 17.451 + file under its original name will be propagated into the file 17.452 + under its new name. (This is something you might expect to 17.453 + <quote>simply work,</quote> but not all revision control 17.454 + systems actually do this.)</para> 17.455 + 17.456 + <para id="x_1d9">Whereas having changes follow a copy is a feature where 17.457 + you can perhaps nod and say <quote>yes, that might be 17.458 + useful,</quote> it should be clear that having them follow a 17.459 + rename is definitely important. Without this facility, it 17.460 + would simply be too easy for changes to become orphaned when 17.461 + files are renamed.</para> 17.462 + </sect2> 17.463 + 17.464 + <sect2> 17.465 + <title>Divergent renames and merging</title> 17.466 + 17.467 + <para id="x_1da">The case of diverging names occurs when two developers 17.468 + start with a file&emdash;let's call it 17.469 + <filename>foo</filename>&emdash;in their respective 17.470 + repositories.</para> 17.471 + 17.472 + &interaction.rename.divergent.clone; 17.473 + 17.474 + <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para> 17.475 + 17.476 + &interaction.rename.divergent.rename.anne; 17.477 + 17.478 + <para id="x_1dc">Meanwhile, Bob renames it to 17.479 + <filename>quux</filename>. (Remember that <command 17.480 + role="hg-cmd">hg mv</command> is an alias for <command 17.481 + role="hg-cmd">hg rename</command>.)</para> 17.482 + 17.483 + &interaction.rename.divergent.rename.bob; 17.484 + 17.485 + <para id="x_1dd">I like to think of this as a conflict because each 17.486 + developer has expressed different intentions about what the 17.487 + file ought to be named.</para> 17.488 + 17.489 + <para id="x_1de">What do you think should happen when they merge their 17.490 + work? Mercurial's actual behavior is that it always preserves 17.491 + <emphasis>both</emphasis> names when it merges changesets that 17.492 + contain divergent renames.</para> 17.493 + 17.494 + &interaction.rename.divergent.merge; 17.495 + 17.496 + <para id="x_1df">Notice that while Mercurial warns about the divergent 17.497 + renames, it leaves it up to you to do something about the 17.498 + divergence after the merge.</para> 17.499 + </sect2> 17.500 + 17.501 + <sect2> 17.502 + <title>Convergent renames and merging</title> 17.503 + 17.504 + <para id="x_1e0">Another kind of rename conflict occurs when two people 17.505 + choose to rename different <emphasis>source</emphasis> files 17.506 + to the same <emphasis>destination</emphasis>. In this case, 17.507 + Mercurial runs its normal merge machinery, and lets you guide 17.508 + it to a suitable resolution.</para> 17.509 + </sect2> 17.510 + 17.511 + <sect2> 17.512 + <title>Other name-related corner cases</title> 17.513 + 17.514 + <para id="x_1e1">Mercurial has a longstanding bug in which it fails to 17.515 + handle a merge where one side has a file with a given name, 17.516 + while another has a directory with the same name. This is 17.517 + documented as <ulink role="hg-bug" 17.518 + url="http://www.selenic.com/mercurial/bts/issue29">issue 17.519 + 29</ulink>.</para> 17.520 + 17.521 + &interaction.issue29.go; 17.522 + 17.523 + </sect2> 17.524 + </sect1> 17.525 + 17.526 + <sect1> 17.527 + <title>Recovering from mistakes</title> 17.528 + 17.529 + <para id="x_1e2">Mercurial has some useful commands that will help you to 17.530 + recover from some common mistakes.</para> 17.531 + 17.532 + <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets 17.533 + you undo changes that you have made to your working directory. 17.534 + For example, if you <command role="hg-cmd">hg add</command> a 17.535 + file by accident, just run <command role="hg-cmd">hg 17.536 + revert</command> with the name of the file you added, and 17.537 + while the file won't be touched in any way, it won't be tracked 17.538 + for adding by Mercurial any longer, either. You can also use 17.539 + <command role="hg-cmd">hg revert</command> to get rid of 17.540 + erroneous changes to a file.</para> 17.541 + 17.542 + <para id="x_1e4">It is helpful to remember that the <command 17.543 + role="hg-cmd">hg revert</command> command is useful for 17.544 + changes that you have not yet committed. Once you've committed 17.545 + a change, if you decide it was a mistake, you can still do 17.546 + something about it, though your options may be more 17.547 + limited.</para> 17.548 + 17.549 + <para id="x_1e5">For more information about the <command 17.550 + role="hg-cmd">hg revert</command> command, and details about 17.551 + how to deal with changes you have already committed, see <xref 17.552 + linkend="chap:undo"/>.</para> 17.553 + </sect1> 17.554 + 17.555 + <sect1> 17.556 + <title>Dealing with tricky merges</title> 17.557 + 17.558 + <para id="x_687">In a complicated or large project, it's not unusual for a 17.559 + merge of two changesets to result in some headaches. Suppose 17.560 + there's a big source file that's been extensively edited by each 17.561 + side of a merge: this is almost inevitably going to result in 17.562 + conflicts, some of which can take a few tries to sort 17.563 + out.</para> 17.564 + 17.565 + <para id="x_688">Let's develop a simple case of this and see how to deal with 17.566 + it. We'll start off with a repository containing one file, and 17.567 + clone it twice.</para> 17.568 + 17.569 + &interaction.ch04-resolve.init; 17.570 + 17.571 + <para id="x_689">In one clone, we'll modify the file in one way.</para> 17.572 + 17.573 + &interaction.ch04-resolve.left; 17.574 + 17.575 + <para id="x_68a">In another, we'll modify the file differently.</para> 17.576 + 17.577 + &interaction.ch04-resolve.right; 17.578 + 17.579 + <para id="x_68b">Next, we'll pull each set of changes into our original 17.580 + repo.</para> 17.581 + 17.582 + &interaction.ch04-resolve.pull; 17.583 + 17.584 + <para id="x_68c">We expect our repository to now contain two heads.</para> 17.585 + 17.586 + &interaction.ch04-resolve.heads; 17.587 + 17.588 + <para id="x_68d">Normally, if we run <command role="hg-cmd">hg 17.589 + merge</command> at this point, it will drop us into a GUI that 17.590 + will let us manually resolve the conflicting edits to 17.591 + <filename>myfile.txt</filename>. However, to simplify things 17.592 + for presentation here, we'd like the merge to fail immediately 17.593 + instead. Here's one way we can do so.</para> 17.594 + 17.595 + &interaction.ch04-resolve.export; 17.596 + 17.597 + <para id="x_68e">We've told Mercurial's merge machinery to run the command 17.598 + <command>false</command> (which, as we desire, fails 17.599 + immediately) if it detects a merge that it can't sort out 17.600 + automatically.</para> 17.601 + 17.602 + <para id="x_68f">If we now fire up <command role="hg-cmd">hg 17.603 + merge</command>, it should grind to a halt and report a 17.604 + failure.</para> 17.605 + 17.606 + &interaction.ch04-resolve.merge; 17.607 + 17.608 + <para id="x_690">Even if we don't notice that the merge failed, Mercurial 17.609 + will prevent us from accidentally committing the result of a 17.610 + failed merge.</para> 17.611 + 17.612 + &interaction.ch04-resolve.cifail; 17.613 + 17.614 + <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in 17.615 + this case, it suggests that we use the unfamiliar <command 17.616 + role="hg-cmd">hg resolve</command> command. As usual, 17.617 + <command role="hg-cmd">hg help resolve</command> will print a 17.618 + helpful synopsis.</para> 17.619 + 17.620 + <sect2> 17.621 + <title>File resolution states</title> 17.622 + 17.623 + <para id="x_692">When a merge occurs, most files will usually remain 17.624 + unmodified. For each file where Mercurial has to do 17.625 + something, it tracks the state of the file.</para> 17.626 + 17.627 + <itemizedlist> 17.628 + <listitem> 17.629 + <para id="x_693">A <emphasis>resolved</emphasis> file has been 17.630 + successfully merged, either automatically by Mercurial or 17.631 + manually with human intervention.</para> 17.632 + </listitem> 17.633 + <listitem> 17.634 + <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged 17.635 + successfully, and needs more attention.</para> 17.636 + </listitem> 17.637 + </itemizedlist> 17.638 + 17.639 + <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the 17.640 + unresolved state after a merge, it considers the merge to have 17.641 + failed. Fortunately, we do not need to restart the entire 17.642 + merge from scratch.</para> 17.643 + 17.644 + <para id="x_696">The <option role="hg-opt-resolve">--list</option> or 17.645 + <option role="hg-opt-resolve">-l</option> option to <command 17.646 + role="hg-cmd">hg resolve</command> prints out the state of 17.647 + each merged file.</para> 17.648 + 17.649 + &interaction.ch04-resolve.list; 17.650 + 17.651 + <para id="x_697">In the output from <command role="hg-cmd">hg 17.652 + resolve</command>, a resolved file is marked with 17.653 + <literal>R</literal>, while an unresolved file is marked with 17.654 + <literal>U</literal>. If any files are listed with 17.655 + <literal>U</literal>, we know that an attempt to commit the 17.656 + results of the merge will fail.</para> 17.657 + </sect2> 17.658 + 17.659 + <sect2> 17.660 + <title>Resolving a file merge</title> 17.661 + 17.662 + <para id="x_698">We have several options to move a file from the unresolved 17.663 + into the resolved state. By far the most common is to rerun 17.664 + <command role="hg-cmd">hg resolve</command>. If we pass the 17.665 + names of individual files or directories, it will retry the 17.666 + merges of any unresolved files present in those locations. We 17.667 + can also pass the <option role="hg-opt-resolve">--all</option> 17.668 + or <option role="hg-opt-resolve">-a</option> option, which 17.669 + will retry the merges of <emphasis>all</emphasis> unresolved 17.670 + files.</para> 17.671 + 17.672 + <para id="x_699">Mercurial also lets us modify the resolution state of a 17.673 + file directly. We can manually mark a file as resolved using 17.674 + the <option role="hg-opt-resolve">--mark</option> option, or 17.675 + as unresolved using the <option 17.676 + role="hg-opt-resolve">--unmark</option> option. This allows 17.677 + us to clean up a particularly messy merge by hand, and to keep 17.678 + track of our progress with each file as we go.</para> 17.679 + </sect2> 17.680 + </sect1> 17.681 + 17.682 + <sect1> 17.683 + <title>More useful diffs</title> 17.684 + 17.685 + <para id="x_6c7">The default output of the <command role="hg-cmd">hg 17.686 + diff</command> command is backwards compatible with the 17.687 + regular <command>diff</command> command, but this has some 17.688 + drawbacks.</para> 17.689 + 17.690 + <para id="x_6c8">Consider the case where we use <command role="hg-cmd">hg 17.691 + rename</command> to rename a file.</para> 17.692 + 17.693 + &interaction.ch04-diff.rename.basic; 17.694 + 17.695 + <para id="x_6c9">The output of <command role="hg-cmd">hg diff</command> above 17.696 + obscures the fact that we simply renamed a file. The <command 17.697 + role="hg-cmd">hg diff</command> command accepts an option, 17.698 + <option>--git</option> or <option>-g</option>, to use a newer 17.699 + diff format that displays such information in a more readable 17.700 + form.</para> 17.701 + 17.702 + &interaction.ch04-diff.rename.git; 17.703 + 17.704 + <para id="x_6ca">This option also helps with a case that can otherwise be 17.705 + confusing: a file that appears to be modified according to 17.706 + <command role="hg-cmd">hg status</command>, but for which 17.707 + <command role="hg-cmd">hg diff</command> prints nothing. This 17.708 + situation can arise if we change the file's execute 17.709 + permissions.</para> 17.710 + 17.711 + &interaction.ch04-diff.chmod; 17.712 + 17.713 + <para id="x_6cb">The normal <command>diff</command> command pays no attention 17.714 + to file permissions, which is why <command role="hg-cmd">hg 17.715 + diff</command> prints nothing by default. If we supply it 17.716 + with the <option>-g</option> option, it tells us what really 17.717 + happened.</para> 17.718 + 17.719 + &interaction.ch04-diff.chmod.git; 17.720 + </sect1> 17.721 + 17.722 + <sect1> 17.723 + <title>Which files to manage, and which to avoid</title> 17.724 + 17.725 + <para id="x_6cc">Revision control systems are generally best at managing text 17.726 + files that are written by humans, such as source code, where the 17.727 + files do not change much from one revision to the next. Some 17.728 + centralized revision control systems can also deal tolerably 17.729 + well with binary files, such as bitmap images.</para> 17.730 + 17.731 + <para id="x_6cd">For instance, a game development team will typically manage 17.732 + both its source code and all of its binary assets (e.g. geometry 17.733 + data, textures, map layouts) in a revision control 17.734 + system.</para> 17.735 + 17.736 + <para id="x_6ce">Because it is usually impossible to merge two conflicting 17.737 + modifications to a binary file, centralized systems often 17.738 + provide a file locking mechanism that allow a user to say 17.739 + <quote>I am the only person who can edit this 17.740 + file</quote>.</para> 17.741 + 17.742 + <para id="x_6cf">Compared to a centralized system, a distributed revision 17.743 + control system changes some of the factors that guide decisions 17.744 + over which files to manage and how.</para> 17.745 + 17.746 + <para id="x_6d0">For instance, a distributed revision control system cannot, 17.747 + by its nature, offer a file locking facility. There is thus no 17.748 + built-in mechanism to prevent two people from making conflicting 17.749 + changes to a binary file. If you have a team where several 17.750 + people may be editing binary files frequently, it may not be a 17.751 + good idea to use Mercurial&emdash;or any other distributed 17.752 + revision control system&emdash;to manage those files.</para> 17.753 + 17.754 + <para id="x_6d1">When storing modifications to a file, Mercurial usually 17.755 + saves only the differences between the previous and current 17.756 + versions of the file. For most text files, this is extremely 17.757 + efficient. However, some files (particularly binary files) are 17.758 + laid out in such a way that even a small change to a file's 17.759 + logical content results in many or most of the bytes inside the 17.760 + file changing. For instance, compressed files are particularly 17.761 + susceptible to this. If the differences between each successive 17.762 + version of a file are always large, Mercurial will not be able 17.763 + to store the file's revision history very efficiently. This can 17.764 + affect both local storage needs and the amount of time it takes 17.765 + to clone a repository.</para> 17.766 + 17.767 + <para id="x_6d2">To get an idea of how this could affect you in practice, 17.768 + suppose you want to use Mercurial to manage an OpenOffice 17.769 + document. OpenOffice stores documents on disk as compressed zip 17.770 + files. Edit even a single letter of your document in OpenOffice, 17.771 + and almost every byte in the entire file will change when you 17.772 + save it. Now suppose that file is 2MB in size. Because most of 17.773 + the file changes every time you save, Mercurial will have to 17.774 + store all 2MB of the file every time you commit, even though 17.775 + from your perspective, perhaps only a few words are changing 17.776 + each time. A single frequently-edited file that is not friendly 17.777 + to Mercurial's storage assumptions can easily have an outsized 17.778 + effect on the size of the repository.</para> 17.779 + 17.780 + <para id="x_6d3">Even worse, if both you and someone else edit the OpenOffice 17.781 + document you're working on, there is no useful way to merge your 17.782 + work. In fact, there isn't even a good way to tell what the 17.783 + differences are between your respective changes.</para> 17.784 + 17.785 + <para id="x_6d4">There are thus a few clear recommendations about specific 17.786 + kinds of files to be very careful with.</para> 17.787 + 17.788 + <itemizedlist> 17.789 + <listitem> 17.790 + <para id="x_6d5">Files that are very large and incompressible, e.g. ISO 17.791 + CD-ROM images, will by virtue of sheer size make clones over 17.792 + a network very slow.</para> 17.793 + </listitem> 17.794 + <listitem> 17.795 + <para id="x_6d6">Files that change a lot from one revision to the next 17.796 + may be expensive to store if you edit them frequently, and 17.797 + conflicts due to concurrent edits may be difficult to 17.798 + resolve.</para> 17.799 + </listitem> 17.800 + </itemizedlist> 17.801 + </sect1> 17.802 + 17.803 + <sect1> 17.804 + <title>Backups and mirroring</title> 17.805 + 17.806 + <para id="x_6d7">Since Mercurial maintains a complete copy of history in each 17.807 + clone, everyone who uses Mercurial to collaborate on a project 17.808 + can potentially act as a source of backups in the event of a 17.809 + catastrophe. If a central repository becomes unavailable, you 17.810 + can construct a replacement simply by cloning a copy of the 17.811 + repository from one contributor, and pulling any changes they 17.812 + may not have seen from others.</para> 17.813 + 17.814 + <para id="x_6d8">It is simple to use Mercurial to perform off-site backups 17.815 + and remote mirrors. Set up a periodic job (e.g. via the 17.816 + <command>cron</command> command) on a remote server to pull 17.817 + changes from your master repositories every hour. This will 17.818 + only be tricky in the unlikely case that the number of master 17.819 + repositories you maintain changes frequently, in which case 17.820 + you'll need to do a little scripting to refresh the list of 17.821 + repositories to back up.</para> 17.822 + 17.823 + <para id="x_6d9">If you perform traditional backups of your master 17.824 + repositories to tape or disk, and you want to back up a 17.825 + repository named <filename>myrepo</filename>, use <command>hg 17.826 + clone -U myrepo myrepo.bak</command> to create a 17.827 + clone of <filename>myrepo</filename> before you start your 17.828 + backups. The <option>-U</option> option doesn't check out a 17.829 + working directory after the clone completes, since that would be 17.830 + superfluous and make the backup take longer.</para> 17.831 + 17.832 + <para id="x_6da">If you then back up <filename>myrepo.bak</filename> instead 17.833 + of <filename>myrepo</filename>, you will be guaranteed to have a 17.834 + consistent snapshot of your repository that won't be pushed to 17.835 + by an insomniac developer in mid-backup.</para> 17.836 + </sect1> 17.837 +</chapter> 17.838 + 17.839 +<!-- 17.840 +local variables: 17.841 +sgml-parent-document: ("00book.xml" "book" "chapter") 17.842 +end: 17.843 +-->
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/en/ch06-collab.xml Thu May 21 14:16:17 2009 +0800 18.3 @@ -0,0 +1,1565 @@ 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 id="x_44a">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 id="x_44b">Mercurial has a powerful web interface that provides several 18.20 + useful capabilities.</para> 18.21 + 18.22 + <para id="x_44c">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. You 18.26 + can even get a view of history that gives a graphical view of 18.27 + the relationships between individual changes and merges.</para> 18.28 + 18.29 + <para id="x_44d">Also for human consumption, the web interface provides 18.30 + Atom and RSS feeds of the changes in a repository. This lets you 18.31 + <quote>subscribe</quote> to a repository using your favorite 18.32 + feed reader, and be automatically notified of activity in that 18.33 + repository as soon as it happens. I find this capability much 18.34 + more convenient than the model of subscribing to a mailing list 18.35 + to which notifications are sent, as it requires no additional 18.36 + configuration on the part of whoever is serving the 18.37 + repository.</para> 18.38 + 18.39 + <para id="x_44e">The web interface also lets remote users clone a repository, 18.40 + pull changes from it, and (when the server is configured to 18.41 + permit it) push changes back to it. Mercurial's HTTP tunneling 18.42 + protocol aggressively compresses data, so that it works 18.43 + efficiently even over low-bandwidth network connections.</para> 18.44 + 18.45 + <para id="x_44f">The easiest way to get started with the web interface is to 18.46 + use your web browser to visit an existing repository, such as 18.47 + the master Mercurial repository at <ulink 18.48 + url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para> 18.49 + 18.50 + <para id="x_450">If you're interested in providing a web interface 18.51 + to your own repositories, there are several good ways to do 18.52 + this.</para> 18.53 + 18.54 + <para id="x_69d">The easiest and fastest way to get started in an informal 18.55 + environment is to use the <command role="hg-cmd">hg 18.56 + serve</command> command, which is best suited to short-term 18.57 + <quote>lightweight</quote> serving. See <xref 18.58 + linkend="sec:collab:serve"/> below for details of how to use 18.59 + this command.</para> 18.60 + 18.61 + <para id="x_69e">For longer-lived repositories that you'd like to 18.62 + have permanently available, there are several public hosting 18.63 + services available. Some are free to open source projects, 18.64 + while others offer paid commercial hosting. An up-to-date list 18.65 + is available at <ulink 18.66 + url="http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting">http://www.selenic.com/mercurial/wiki/index.cgi/MercurialHosting</ulink>.</para> 18.67 + 18.68 + <para id="x_6a0">If you would prefer to host your own repositories, Mercurial 18.69 + has built-in support for several popular hosting technologies, 18.70 + most notably CGI (Common Gateway Interface), and WSGI (Web 18.71 + Services Gateway Interface). See <xref 18.72 + linkend="sec:collab:cgi"/> for details of CGI and WSGI 18.73 + configuration.</para> 18.74 + </sect1> 18.75 + 18.76 + <sect1> 18.77 + <title>Collaboration models</title> 18.78 + 18.79 + <para id="x_451">With a suitably flexible tool, making decisions about 18.80 + workflow is much more of a social engineering challenge than a 18.81 + technical one. Mercurial imposes few limitations on how you can 18.82 + structure the flow of work in a project, so it's up to you and 18.83 + your group to set up and live with a model that matches your own 18.84 + particular needs.</para> 18.85 + 18.86 + <sect2> 18.87 + <title>Factors to keep in mind</title> 18.88 + 18.89 + <para id="x_452">The most important aspect of any model that you must keep 18.90 + in mind is how well it matches the needs and capabilities of 18.91 + the people who will be using it. This might seem 18.92 + self-evident; even so, you still can't afford to forget it for 18.93 + a moment.</para> 18.94 + 18.95 + <para id="x_453">I once put together a workflow model that seemed to make 18.96 + perfect sense to me, but that caused a considerable amount of 18.97 + consternation and strife within my development team. In spite 18.98 + of my attempts to explain why we needed a complex set of 18.99 + branches, and how changes ought to flow between them, a few 18.100 + team members revolted. Even though they were smart people, 18.101 + they didn't want to pay attention to the constraints we were 18.102 + operating under, or face the consequences of those constraints 18.103 + in the details of the model that I was advocating.</para> 18.104 + 18.105 + <para id="x_454">Don't sweep foreseeable social or technical problems under 18.106 + the rug. Whatever scheme you put into effect, you should plan 18.107 + for mistakes and problem scenarios. Consider adding automated 18.108 + machinery to prevent, or quickly recover from, trouble that 18.109 + you can anticipate. As an example, if you intend to have a 18.110 + branch with not-for-release changes in it, you'd do well to 18.111 + think early about the possibility that someone might 18.112 + accidentally merge those changes into a release branch. You 18.113 + could avoid this particular problem by writing a hook that 18.114 + prevents changes from being merged from an inappropriate 18.115 + branch.</para> 18.116 + </sect2> 18.117 + 18.118 + <sect2> 18.119 + <title>Informal anarchy</title> 18.120 + 18.121 + <para id="x_455">I wouldn't suggest an <quote>anything goes</quote> 18.122 + approach as something sustainable, but it's a model that's 18.123 + easy to grasp, and it works perfectly well in a few unusual 18.124 + situations.</para> 18.125 + 18.126 + <para id="x_456">As one example, many projects have a loose-knit group of 18.127 + collaborators who rarely physically meet each other. Some 18.128 + groups like to overcome the isolation of working at a distance 18.129 + by organizing occasional <quote>sprints</quote>. In a sprint, 18.130 + a number of people get together in a single location (a 18.131 + company's conference room, a hotel meeting room, that kind of 18.132 + place) and spend several days more or less locked in there, 18.133 + hacking intensely on a handful of projects.</para> 18.134 + 18.135 + <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the 18.136 + <command role="hg-cmd">hg serve</command> command, since 18.137 + <command role="hg-cmd">hg serve</command> does not require any 18.138 + fancy server infrastructure. You can get started with 18.139 + <command role="hg-cmd">hg serve</command> in moments, by 18.140 + reading <xref linkend="sec:collab:serve"/> below. Then simply 18.141 + tell the person next to you that you're running a server, send 18.142 + the URL to them in an instant message, and you immediately 18.143 + have a quick-turnaround way to work together. They can type 18.144 + your URL into their web browser and quickly review your 18.145 + changes; or they can pull a bugfix from you and verify it; or 18.146 + they can clone a branch containing a new feature and try it 18.147 + out.</para> 18.148 + 18.149 + <para id="x_458">The charm, and the problem, with doing things 18.150 + in an ad hoc fashion like this is that only people who know 18.151 + about your changes, and where they are, can see them. Such an 18.152 + informal approach simply doesn't scale beyond a handful 18.153 + people, because each individual needs to know about 18.154 + <emphasis>n</emphasis> different repositories to pull 18.155 + from.</para> 18.156 + </sect2> 18.157 + 18.158 + <sect2> 18.159 + <title>A single central repository</title> 18.160 + 18.161 + <para id="x_459">For smaller projects migrating from a centralised revision 18.162 + control tool, perhaps the easiest way to get started is to 18.163 + have changes flow through a single shared central repository. 18.164 + This is also the most common <quote>building block</quote> for 18.165 + more ambitious workflow schemes.</para> 18.166 + 18.167 + <para id="x_45a">Contributors start by cloning a copy of this repository. 18.168 + They can pull changes from it whenever they need to, and some 18.169 + (perhaps all) developers have permission to push a change back 18.170 + when they're ready for other people to see it.</para> 18.171 + 18.172 + <para id="x_45b">Under this model, it can still often make sense for people 18.173 + to pull changes directly from each other, without going 18.174 + through the central repository. Consider a case in which I 18.175 + have a tentative bug fix, but I am worried that if I were to 18.176 + publish it to the central repository, it might subsequently 18.177 + break everyone else's trees as they pull it. To reduce the 18.178 + potential for damage, I can ask you to clone my repository 18.179 + into a temporary repository of your own and test it. This 18.180 + lets us put off publishing the potentially unsafe change until 18.181 + it has had a little testing.</para> 18.182 + 18.183 + <para id="x_45c">If a team is hosting its own repository in this 18.184 + kind of scenario, people will usually use the 18.185 + <command>ssh</command> protocol to securely push changes to 18.186 + the central repository, as documented in <xref 18.187 + linkend="sec:collab:ssh"/>. It's also usual to publish a 18.188 + read-only copy of the repository over HTTP, as in 18.189 + <xref linkend="sec:collab:cgi"/>. Publishing over HTTP 18.190 + satisfies the needs of people who don't have push access, and 18.191 + those who want to use web browsers to browse the repository's 18.192 + history.</para> 18.193 + </sect2> 18.194 + 18.195 + <sect2> 18.196 + <title>A hosted central repository</title> 18.197 + 18.198 + <para id="x_6a1">A wonderful thing about public hosting services like 18.199 + <ulink url="http://bitbucket.org/">Bitbucket</ulink> is that 18.200 + not only do they handle the fiddly server configuration 18.201 + details, such as user accounts, authentication, and secure 18.202 + wire protocols, they provide additional infrastructure to make 18.203 + this model work well.</para> 18.204 + 18.205 + <para id="x_6a2">For instance, a well-engineered hosting service will let 18.206 + people clone their own copies of a repository with a single 18.207 + click. This lets people work in separate spaces and share 18.208 + their changes when they're ready.</para> 18.209 + 18.210 + <para id="x_6a3">In addition, a good hosting service will let people 18.211 + communicate with each other, for instance to say <quote>there 18.212 + are changes ready for you to review in this 18.213 + tree</quote>.</para> 18.214 + </sect2> 18.215 + 18.216 + <sect2> 18.217 + <title>Working with multiple branches</title> 18.218 + 18.219 + <para id="x_45d">Projects of any significant size naturally tend to make 18.220 + progress on several fronts simultaneously. In the case of 18.221 + software, it's common for a project to go through periodic 18.222 + official releases. A release might then go into 18.223 + <quote>maintenance mode</quote> for a while after its first 18.224 + publication; maintenance releases tend to contain only bug 18.225 + fixes, not new features. In parallel with these maintenance 18.226 + releases, one or more future releases may be under 18.227 + development. People normally use the word 18.228 + <quote>branch</quote> to refer to one of these many slightly 18.229 + different directions in which development is 18.230 + proceeding.</para> 18.231 + 18.232 + <para id="x_45e">Mercurial is particularly well suited to managing a number 18.233 + of simultaneous, but not identical, branches. Each 18.234 + <quote>development direction</quote> can live in its own 18.235 + central repository, and you can merge changes from one to 18.236 + another as the need arises. Because repositories are 18.237 + independent of each other, unstable changes in a development 18.238 + branch will never affect a stable branch unless someone 18.239 + explicitly merges those changes into the stable branch.</para> 18.240 + 18.241 + <para id="x_45f">Here's an example of how this can work in practice. Let's 18.242 + say you have one <quote>main branch</quote> on a central 18.243 + server.</para> 18.244 + 18.245 + &interaction.branching.init; 18.246 + 18.247 + <para id="x_460">People clone it, make changes locally, test them, and push 18.248 + them back.</para> 18.249 + 18.250 + <para id="x_461">Once the main branch reaches a release milestone, you can 18.251 + use the <command role="hg-cmd">hg tag</command> command to 18.252 + give a permanent name to the milestone revision.</para> 18.253 + 18.254 + &interaction.branching.tag; 18.255 + 18.256 + <para id="x_462">Let's say some ongoing 18.257 + development occurs on the main branch.</para> 18.258 + 18.259 + &interaction.branching.main; 18.260 + 18.261 + <para id="x_463">Using the tag that was recorded at the milestone, people 18.262 + who clone that repository at any time in the future can use 18.263 + <command role="hg-cmd">hg update</command> to get a copy of 18.264 + the working directory exactly as it was when that tagged 18.265 + revision was committed.</para> 18.266 + 18.267 + &interaction.branching.update; 18.268 + 18.269 + <para id="x_464">In addition, immediately after the main branch is tagged, 18.270 + we can then clone the main branch on the server to a new 18.271 + <quote>stable</quote> branch, also on the server.</para> 18.272 + 18.273 + &interaction.branching.clone; 18.274 + 18.275 + <para id="x_465">If we need to make a change to the stable 18.276 + branch, we can then clone <emphasis>that</emphasis> 18.277 + repository, make our changes, commit, and push our changes 18.278 + back there.</para> 18.279 + 18.280 + &interaction.branching.stable; 18.281 + 18.282 + <para id="x_466">Because Mercurial repositories are independent, and 18.283 + Mercurial doesn't move changes around automatically, the 18.284 + stable and main branches are <emphasis>isolated</emphasis> 18.285 + from each other. The changes that we made on the main branch 18.286 + don't <quote>leak</quote> to the stable branch, and vice 18.287 + versa.</para> 18.288 + 18.289 + <para id="x_467">We'll often want all of our bugfixes on the stable 18.290 + branch to show up on the main branch, too. Rather than 18.291 + rewrite a bugfix on the main branch, we can simply pull and 18.292 + merge changes from the stable to the main branch, and 18.293 + Mercurial will bring those bugfixes in for us.</para> 18.294 + 18.295 + &interaction.branching.merge; 18.296 + 18.297 + <para id="x_468">The main branch will still contain changes that 18.298 + are not on the stable branch, but it will also contain all of 18.299 + the bugfixes from the stable branch. The stable branch 18.300 + remains unaffected by these changes, since changes are only 18.301 + flowing from the stable to the main branch, and not the other 18.302 + way.</para> 18.303 + </sect2> 18.304 + 18.305 + <sect2> 18.306 + <title>Feature branches</title> 18.307 + 18.308 + <para id="x_469">For larger projects, an effective way to manage change is 18.309 + to break up a team into smaller groups. Each group has a 18.310 + shared branch of its own, cloned from a single 18.311 + <quote>master</quote> branch used by the entire project. 18.312 + People working on an individual branch are typically quite 18.313 + isolated from developments on other branches.</para> 18.314 + 18.315 + <figure id="fig:collab:feature-branches"> 18.316 + <title>Feature branches</title> 18.317 + <mediaobject> 18.318 + <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject> 18.319 + <textobject><phrase>XXX add text</phrase></textobject> 18.320 + </mediaobject> 18.321 + </figure> 18.322 + 18.323 + <para id="x_46b">When a particular feature is deemed to be in suitable 18.324 + shape, someone on that feature team pulls and merges from the 18.325 + master branch into the feature branch, then pushes back up to 18.326 + the master branch.</para> 18.327 + </sect2> 18.328 + 18.329 + <sect2> 18.330 + <title>The release train</title> 18.331 + 18.332 + <para id="x_46c">Some projects are organized on a <quote>train</quote> 18.333 + basis: a release is scheduled to happen every few months, and 18.334 + whatever features are ready when the <quote>train</quote> is 18.335 + ready to leave are allowed in.</para> 18.336 + 18.337 + <para id="x_46d">This model resembles working with feature branches. The 18.338 + difference is that when a feature branch misses a train, 18.339 + someone on the feature team pulls and merges the changes that 18.340 + went out on that train release into the feature branch, and 18.341 + the team continues its work on top of that release so that 18.342 + their feature can make the next release.</para> 18.343 + </sect2> 18.344 + 18.345 + <sect2> 18.346 + <title>The Linux kernel model</title> 18.347 + 18.348 + <para id="x_46e">The development of the Linux kernel has a shallow 18.349 + hierarchical structure, surrounded by a cloud of apparent 18.350 + chaos. Because most Linux developers use 18.351 + <command>git</command>, a distributed revision control tool 18.352 + with capabilities similar to Mercurial, it's useful to 18.353 + describe the way work flows in that environment; if you like 18.354 + the ideas, the approach translates well across tools.</para> 18.355 + 18.356 + <para id="x_46f">At the center of the community sits Linus Torvalds, the 18.357 + creator of Linux. He publishes a single source repository 18.358 + that is considered the <quote>authoritative</quote> current 18.359 + tree by the entire developer community. Anyone can clone 18.360 + Linus's tree, but he is very choosy about whose trees he pulls 18.361 + from.</para> 18.362 + 18.363 + <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>. 18.364 + As a general rule, he pulls whatever changes they publish, in 18.365 + most cases without even reviewing those changes. Some of 18.366 + those lieutenants are generally agreed to be 18.367 + <quote>maintainers</quote>, responsible for specific 18.368 + subsystems within the kernel. If a random kernel hacker wants 18.369 + to make a change to a subsystem that they want to end up in 18.370 + Linus's tree, they must find out who the subsystem's 18.371 + maintainer is, and ask that maintainer to take their change. 18.372 + If the maintainer reviews their changes and agrees to take 18.373 + them, they'll pass them along to Linus in due course.</para> 18.374 + 18.375 + <para id="x_471">Individual lieutenants have their own approaches to 18.376 + reviewing, accepting, and publishing changes; and for deciding 18.377 + when to feed them to Linus. In addition, there are several 18.378 + well known branches that people use for different purposes. 18.379 + For example, a few people maintain <quote>stable</quote> 18.380 + repositories of older versions of the kernel, to which they 18.381 + apply critical fixes as needed. Some maintainers publish 18.382 + multiple trees: one for experimental changes; one for changes 18.383 + that they are about to feed upstream; and so on. Others just 18.384 + publish a single tree.</para> 18.385 + 18.386 + <para id="x_472">This model has two notable features. The first is that 18.387 + it's <quote>pull only</quote>. You have to ask, convince, or 18.388 + beg another developer to take a change from you, because there 18.389 + are almost no trees to which more than one person can push, 18.390 + and there's no way to push changes into a tree that someone 18.391 + else controls.</para> 18.392 + 18.393 + <para id="x_473">The second is that it's based on reputation and acclaim. 18.394 + If you're an unknown, Linus will probably ignore changes from 18.395 + you without even responding. But a subsystem maintainer will 18.396 + probably review them, and will likely take them if they pass 18.397 + their criteria for suitability. The more <quote>good</quote> 18.398 + changes you contribute to a maintainer, the more likely they 18.399 + are to trust your judgment and accept your changes. If you're 18.400 + well-known and maintain a long-lived branch for something 18.401 + Linus hasn't yet accepted, people with similar interests may 18.402 + pull your changes regularly to keep up with your work.</para> 18.403 + 18.404 + <para id="x_474">Reputation and acclaim don't necessarily cross subsystem 18.405 + or <quote>people</quote> boundaries. If you're a respected 18.406 + but specialised storage hacker, and you try to fix a 18.407 + networking bug, that change will receive a level of scrutiny 18.408 + from a network maintainer comparable to a change from a 18.409 + complete stranger.</para> 18.410 + 18.411 + <para id="x_475">To people who come from more orderly project backgrounds, 18.412 + the comparatively chaotic Linux kernel development process 18.413 + often seems completely insane. It's subject to the whims of 18.414 + individuals; people make sweeping changes whenever they deem 18.415 + it appropriate; and the pace of development is astounding. 18.416 + And yet Linux is a highly successful, well-regarded piece of 18.417 + software.</para> 18.418 + </sect2> 18.419 + 18.420 + <sect2> 18.421 + <title>Pull-only versus shared-push collaboration</title> 18.422 + 18.423 + <para id="x_476">A perpetual source of heat in the open source community is 18.424 + whether a development model in which people only ever pull 18.425 + changes from others is <quote>better than</quote> one in which 18.426 + multiple people can push changes to a shared 18.427 + repository.</para> 18.428 + 18.429 + <para id="x_477">Typically, the backers of the shared-push model use tools 18.430 + that actively enforce this approach. If you're using a 18.431 + centralised revision control tool such as Subversion, there's 18.432 + no way to make a choice over which model you'll use: the tool 18.433 + gives you shared-push, and if you want to do anything else, 18.434 + you'll have to roll your own approach on top (such as applying 18.435 + a patch by hand).</para> 18.436 + 18.437 + <para id="x_478">A good distributed revision control tool will 18.438 + support both models. You and your collaborators can then 18.439 + structure how you work together based on your own needs and 18.440 + preferences, not on what contortions your tools force you 18.441 + into.</para> 18.442 + </sect2> 18.443 + <sect2> 18.444 + <title>Where collaboration meets branch management</title> 18.445 + 18.446 + <para id="x_479">Once you and your team set up some shared 18.447 + repositories and start propagating changes back and forth 18.448 + between local and shared repos, you begin to face a related, 18.449 + but slightly different challenge: that of managing the 18.450 + multiple directions in which your team may be moving at once. 18.451 + Even though this subject is intimately related to how your 18.452 + team collaborates, it's dense enough to merit treatment of its 18.453 + own, in <xref linkend="chap:branch"/>.</para> 18.454 + </sect2> 18.455 + </sect1> 18.456 + 18.457 + <sect1> 18.458 + <title>The technical side of sharing</title> 18.459 + 18.460 + <para id="x_47a">The remainder of this chapter is devoted to the question of 18.461 + sharing changes with your collaborators.</para> 18.462 + </sect1> 18.463 + 18.464 + <sect1 id="sec:collab:serve"> 18.465 + <title>Informal sharing with <command role="hg-cmd">hg 18.466 + serve</command></title> 18.467 + 18.468 + <para id="x_47b">Mercurial's <command role="hg-cmd">hg serve</command> 18.469 + command is wonderfully suited to small, tight-knit, and 18.470 + fast-paced group environments. It also provides a great way to 18.471 + get a feel for using Mercurial commands over a network.</para> 18.472 + 18.473 + <para id="x_47c">Run <command role="hg-cmd">hg serve</command> inside a 18.474 + repository, and in under a second it will bring up a specialised 18.475 + HTTP server; this will accept connections from any client, and 18.476 + serve up data for that repository until you terminate it. 18.477 + Anyone who knows the URL of the server you just started, and can 18.478 + talk to your computer over the network, can then use a web 18.479 + browser or Mercurial to read data from that repository. A URL 18.480 + for a <command role="hg-cmd">hg serve</command> instance running 18.481 + on a laptop is likely to look something like 18.482 + <literal>http://my-laptop.local:8000/</literal>.</para> 18.483 + 18.484 + <para id="x_47d">The <command role="hg-cmd">hg serve</command> command is 18.485 + <emphasis>not</emphasis> a general-purpose web server. It can do 18.486 + only two things:</para> 18.487 + <itemizedlist> 18.488 + <listitem><para id="x_47e">Allow people to browse the history of the 18.489 + repository it's serving, from their normal web 18.490 + browsers.</para> 18.491 + </listitem> 18.492 + <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people 18.493 + can <command role="hg-cmd">hg clone</command> or <command 18.494 + role="hg-cmd">hg pull</command> changes from that 18.495 + repository.</para> 18.496 + </listitem></itemizedlist> 18.497 + <para id="x_480">In particular, <command role="hg-cmd">hg serve</command> 18.498 + won't allow remote users to <emphasis>modify</emphasis> your 18.499 + repository. It's intended for read-only use.</para> 18.500 + 18.501 + <para id="x_481">If you're getting started with Mercurial, there's nothing to 18.502 + prevent you from using <command role="hg-cmd">hg serve</command> 18.503 + to serve up a repository on your own computer, then use commands 18.504 + like <command role="hg-cmd">hg clone</command>, <command 18.505 + role="hg-cmd">hg incoming</command>, and so on to talk to that 18.506 + server as if the repository was hosted remotely. This can help 18.507 + you to quickly get acquainted with using commands on 18.508 + network-hosted repositories.</para> 18.509 + 18.510 + <sect2> 18.511 + <title>A few things to keep in mind</title> 18.512 + 18.513 + <para id="x_482">Because it provides unauthenticated read access to all 18.514 + clients, you should only use <command role="hg-cmd">hg 18.515 + serve</command> in an environment where you either don't 18.516 + care, or have complete control over, who can access your 18.517 + network and pull data from your repository.</para> 18.518 + 18.519 + <para id="x_483">The <command role="hg-cmd">hg serve</command> command 18.520 + knows nothing about any firewall software you might have 18.521 + installed on your system or network. It cannot detect or 18.522 + control your firewall software. If other people are unable to 18.523 + talk to a running <command role="hg-cmd">hg serve</command> 18.524 + instance, the second thing you should do 18.525 + (<emphasis>after</emphasis> you make sure that they're using 18.526 + the correct URL) is check your firewall configuration.</para> 18.527 + 18.528 + <para id="x_484">By default, <command role="hg-cmd">hg serve</command> 18.529 + listens for incoming connections on port 8000. If another 18.530 + process is already listening on the port you want to use, you 18.531 + can specify a different port to listen on using the <option 18.532 + role="hg-opt-serve">-p</option> option.</para> 18.533 + 18.534 + <para id="x_485">Normally, when <command role="hg-cmd">hg serve</command> 18.535 + starts, it prints no output, which can be a bit unnerving. If 18.536 + you'd like to confirm that it is indeed running correctly, and 18.537 + find out what URL you should send to your collaborators, start 18.538 + it with the <option role="hg-opt-global">-v</option> 18.539 + option.</para> 18.540 + </sect2> 18.541 + </sect1> 18.542 + 18.543 + <sect1 id="sec:collab:ssh"> 18.544 + <title>Using the Secure Shell (ssh) protocol</title> 18.545 + 18.546 + <para id="x_486">You can pull and push changes securely over a network 18.547 + connection using the Secure Shell (<literal>ssh</literal>) 18.548 + protocol. To use this successfully, you may have to do a little 18.549 + bit of configuration on the client or server sides.</para> 18.550 + 18.551 + <para id="x_487">If you're not familiar with ssh, it's the name of 18.552 + both a command and a network protocol that let you securely 18.553 + communicate with another computer. To use it with Mercurial, 18.554 + you'll be setting up one or more user accounts on a server so 18.555 + that remote users can log in and execute commands.</para> 18.556 + 18.557 + <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll 18.558 + probably find some of the material that follows to be elementary 18.559 + in nature.)</para> 18.560 + 18.561 + <sect2> 18.562 + <title>How to read and write ssh URLs</title> 18.563 + 18.564 + <para id="x_489">An ssh URL tends to look like this:</para> 18.565 + <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting> 18.566 + <orderedlist> 18.567 + <listitem><para id="x_48a">The <quote><literal>ssh://</literal></quote> 18.568 + part tells Mercurial to use the ssh protocol.</para> 18.569 + </listitem> 18.570 + <listitem><para id="x_48b">The <quote><literal>bos@</literal></quote> 18.571 + component indicates what username to log into the server 18.572 + as. You can leave this out if the remote username is the 18.573 + same as your local username.</para> 18.574 + </listitem> 18.575 + <listitem><para id="x_48c">The 18.576 + <quote><literal>hg.serpentine.com</literal></quote> gives 18.577 + the hostname of the server to log into.</para> 18.578 + </listitem> 18.579 + <listitem><para id="x_48d">The <quote>:22</quote> identifies the port 18.580 + number to connect to the server on. The default port is 18.581 + 22, so you only need to specify a colon and port number if 18.582 + you're <emphasis>not</emphasis> using port 22.</para> 18.583 + </listitem> 18.584 + <listitem><para id="x_48e">The remainder of the URL is the local path to 18.585 + the repository on the server.</para> 18.586 + </listitem></orderedlist> 18.587 + 18.588 + <para id="x_48f">There's plenty of scope for confusion with the path 18.589 + component of ssh URLs, as there is no standard way for tools 18.590 + to interpret it. Some programs behave differently than others 18.591 + when dealing with these paths. This isn't an ideal situation, 18.592 + but it's unlikely to change. Please read the following 18.593 + paragraphs carefully.</para> 18.594 + 18.595 + <para id="x_490">Mercurial treats the path to a repository on the server as 18.596 + relative to the remote user's home directory. For example, if 18.597 + user <literal>foo</literal> on the server has a home directory 18.598 + of <filename class="directory">/home/foo</filename>, then an 18.599 + ssh URL that contains a path component of <filename 18.600 + class="directory">bar</filename> <emphasis>really</emphasis> 18.601 + refers to the directory <filename 18.602 + class="directory">/home/foo/bar</filename>.</para> 18.603 + 18.604 + <para id="x_491">If you want to specify a path relative to another user's 18.605 + home directory, you can use a path that starts with a tilde 18.606 + character followed by the user's name (let's call them 18.607 + <literal>otheruser</literal>), like this.</para> 18.608 + <programlisting>ssh://server/~otheruser/hg/repo</programlisting> 18.609 + 18.610 + <para id="x_492">And if you really want to specify an 18.611 + <emphasis>absolute</emphasis> path on the server, begin the 18.612 + path component with two slashes, as in this example.</para> 18.613 + <programlisting>ssh://server//absolute/path</programlisting> 18.614 + </sect2> 18.615 + 18.616 + <sect2> 18.617 + <title>Finding an ssh client for your system</title> 18.618 + 18.619 + <para id="x_493">Almost every Unix-like system comes with OpenSSH 18.620 + preinstalled. If you're using such a system, run 18.621 + <literal>which ssh</literal> to find out if the 18.622 + <command>ssh</command> command is installed (it's usually in 18.623 + <filename class="directory">/usr/bin</filename>). In the 18.624 + unlikely event that it isn't present, take a look at your 18.625 + system documentation to figure out how to install it.</para> 18.626 + 18.627 + <para id="x_494">On Windows, the TortoiseHg package is bundled 18.628 + with a version of Simon Tatham's excellent 18.629 + <command>plink</command> command, and you should not need to 18.630 + do any further configuration.</para> 18.631 + </sect2> 18.632 + 18.633 + <sect2> 18.634 + <title>Generating a key pair</title> 18.635 + 18.636 + <para id="x_499">To avoid the need to repetitively type a 18.637 + password every time you need to use your ssh client, I 18.638 + recommend generating a key pair.</para> 18.639 + 18.640 + <tip> 18.641 + <title>Key pairs are not mandatory</title> 18.642 + 18.643 + <para id="x_6a4">Mercurial knows nothing about ssh authentication or key 18.644 + pairs. You can, if you like, safely ignore this section and 18.645 + the one that follows until you grow tired of repeatedly 18.646 + typing ssh passwords.</para> 18.647 + </tip> 18.648 + 18.649 + <itemizedlist> 18.650 + <listitem> 18.651 + <para id="x_6a5">On a Unix-like system, the 18.652 + <command>ssh-keygen</command> command will do the 18.653 + trick.</para> 18.654 + <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need 18.655 + to download a command named <command>puttygen</command> 18.656 + from <ulink 18.657 + url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 18.658 + PuTTY web site</ulink> to generate a key pair. See 18.659 + <ulink 18.660 + url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 18.661 + <command>puttygen</command> documentation</ulink> for 18.662 + details of how use the command.</para> 18.663 + </listitem> 18.664 + </itemizedlist> 18.665 + 18.666 + <para id="x_49a">When you generate a key pair, it's usually 18.667 + <emphasis>highly</emphasis> advisable to protect it with a 18.668 + passphrase. (The only time that you might not want to do this 18.669 + is when you're using the ssh protocol for automated tasks on a 18.670 + secure network.)</para> 18.671 + 18.672 + <para id="x_49b">Simply generating a key pair isn't enough, however. 18.673 + You'll need to add the public key to the set of authorised 18.674 + keys for whatever user you're logging in remotely as. For 18.675 + servers using OpenSSH (the vast majority), this will mean 18.676 + adding the public key to a list in a file called <filename 18.677 + role="special">authorized_keys</filename> in their <filename 18.678 + role="special" class="directory">.ssh</filename> 18.679 + directory.</para> 18.680 + 18.681 + <para id="x_49c">On a Unix-like system, your public key will have a 18.682 + <filename>.pub</filename> extension. If you're using 18.683 + <command>puttygen</command> on Windows, you can save the 18.684 + public key to a file of your choosing, or paste it from the 18.685 + window it's displayed in straight into the <filename 18.686 + role="special">authorized_keys</filename> file.</para> 18.687 + </sect2> 18.688 + <sect2> 18.689 + <title>Using an authentication agent</title> 18.690 + 18.691 + <para id="x_49d">An authentication agent is a daemon that stores 18.692 + passphrases in memory (so it will forget passphrases if you 18.693 + log out and log back in again). An ssh client will notice if 18.694 + it's running, and query it for a passphrase. If there's no 18.695 + authentication agent running, or the agent doesn't store the 18.696 + necessary passphrase, you'll have to type your passphrase 18.697 + every time Mercurial tries to communicate with a server on 18.698 + your behalf (e.g. whenever you pull or push changes).</para> 18.699 + 18.700 + <para id="x_49e">The downside of storing passphrases in an agent is that 18.701 + it's possible for a well-prepared attacker to recover the 18.702 + plain text of your passphrases, in some cases even if your 18.703 + system has been power-cycled. You should make your own 18.704 + judgment as to whether this is an acceptable risk. It 18.705 + certainly saves a lot of repeated typing.</para> 18.706 + 18.707 + <itemizedlist> 18.708 + <listitem> 18.709 + <para id="x_49f">On Unix-like systems, the agent is called 18.710 + <command>ssh-agent</command>, and it's often run 18.711 + automatically for you when you log in. You'll need to use 18.712 + the <command>ssh-add</command> command to add passphrases 18.713 + to the agent's store.</para> 18.714 + </listitem> 18.715 + <listitem> 18.716 + <para id="x_6a7">On Windows, if you're using TortoiseHg, the 18.717 + <command>pageant</command> command acts as the agent. As 18.718 + with <command>puttygen</command>, you'll need to <ulink 18.719 + url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 18.720 + <command>pageant</command></ulink> from the PuTTY web 18.721 + site and read <ulink 18.722 + url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 18.723 + documentation</ulink>. The <command>pageant</command> 18.724 + command adds an icon to your system tray that will let you 18.725 + manage stored passphrases.</para> 18.726 + </listitem> 18.727 + </itemizedlist> 18.728 + </sect2> 18.729 + 18.730 + <sect2> 18.731 + <title>Configuring the server side properly</title> 18.732 + 18.733 + <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it, 18.734 + a variety of things can go wrong. Add Mercurial 18.735 + on top, and there's plenty more scope for head-scratching. 18.736 + Most of these potential problems occur on the server side, not 18.737 + the client side. The good news is that once you've gotten a 18.738 + configuration working, it will usually continue to work 18.739 + indefinitely.</para> 18.740 + 18.741 + <para id="x_4a1">Before you try using Mercurial to talk to an ssh server, 18.742 + it's best to make sure that you can use the normal 18.743 + <command>ssh</command> or <command>putty</command> command to 18.744 + talk to the server first. If you run into problems with using 18.745 + these commands directly, Mercurial surely won't work. Worse, 18.746 + it will obscure the underlying problem. Any time you want to 18.747 + debug ssh-related Mercurial problems, you should drop back to 18.748 + making sure that plain ssh client commands work first, 18.749 + <emphasis>before</emphasis> you worry about whether there's a 18.750 + problem with Mercurial.</para> 18.751 + 18.752 + <para id="x_4a2">The first thing to be sure of on the server side is that 18.753 + you can actually log in from another machine at all. If you 18.754 + can't use <command>ssh</command> or <command>putty</command> 18.755 + to log in, the error message you get may give you a few hints 18.756 + as to what's wrong. The most common problems are as 18.757 + follows.</para> 18.758 + <itemizedlist> 18.759 + <listitem><para id="x_4a3">If you get a <quote>connection refused</quote> 18.760 + error, either there isn't an SSH daemon running on the 18.761 + server at all, or it's inaccessible due to firewall 18.762 + configuration.</para> 18.763 + </listitem> 18.764 + <listitem><para id="x_4a4">If you get a <quote>no route to host</quote> 18.765 + error, you either have an incorrect address for the server 18.766 + or a seriously locked down firewall that won't admit its 18.767 + existence at all.</para> 18.768 + </listitem> 18.769 + <listitem><para id="x_4a5">If you get a <quote>permission denied</quote> 18.770 + error, you may have mistyped the username on the server, 18.771 + or you could have mistyped your key's passphrase or the 18.772 + remote user's password.</para> 18.773 + </listitem></itemizedlist> 18.774 + <para id="x_4a6">In summary, if you're having trouble talking to the 18.775 + server's ssh daemon, first make sure that one is running at 18.776 + all. On many systems it will be installed, but disabled, by 18.777 + default. Once you're done with this step, you should then 18.778 + check that the server's firewall is configured to allow 18.779 + incoming connections on the port the ssh daemon is listening 18.780 + on (usually 22). Don't worry about more exotic possibilities 18.781 + for misconfiguration until you've checked these two 18.782 + first.</para> 18.783 + 18.784 + <para id="x_4a7">If you're using an authentication agent on the client side 18.785 + to store passphrases for your keys, you ought to be able to 18.786 + log into the server without being prompted for a passphrase or 18.787 + a password. If you're prompted for a passphrase, there are a 18.788 + few possible culprits.</para> 18.789 + <itemizedlist> 18.790 + <listitem><para id="x_4a8">You might have forgotten to use 18.791 + <command>ssh-add</command> or <command>pageant</command> 18.792 + to store the passphrase.</para> 18.793 + </listitem> 18.794 + <listitem><para id="x_4a9">You might have stored the passphrase for the 18.795 + wrong key.</para> 18.796 + </listitem></itemizedlist> 18.797 + <para id="x_4aa">If you're being prompted for the remote user's password, 18.798 + there are another few possible problems to check.</para> 18.799 + <itemizedlist> 18.800 + <listitem><para id="x_4ab">Either the user's home directory or their 18.801 + <filename role="special" class="directory">.ssh</filename> 18.802 + directory might have excessively liberal permissions. As 18.803 + a result, the ssh daemon will not trust or read their 18.804 + <filename role="special">authorized_keys</filename> file. 18.805 + For example, a group-writable home or <filename 18.806 + role="special" class="directory">.ssh</filename> 18.807 + directory will often cause this symptom.</para> 18.808 + </listitem> 18.809 + <listitem><para id="x_4ac">The user's <filename 18.810 + role="special">authorized_keys</filename> file may have 18.811 + a problem. If anyone other than the user owns or can write 18.812 + to that file, the ssh daemon will not trust or read 18.813 + it.</para> 18.814 + </listitem></itemizedlist> 18.815 + 18.816 + <para id="x_4ad">In the ideal world, you should be able to run the 18.817 + following command successfully, and it should print exactly 18.818 + one line of output, the current date and time.</para> 18.819 + <programlisting>ssh myserver date</programlisting> 18.820 + 18.821 + <para id="x_4ae">If, on your server, you have login scripts that print 18.822 + banners or other junk even when running non-interactive 18.823 + commands like this, you should fix them before you continue, 18.824 + so that they only print output if they're run interactively. 18.825 + Otherwise these banners will at least clutter up Mercurial's 18.826 + output. Worse, they could potentially cause problems with 18.827 + running Mercurial commands remotely. Mercurial tries to 18.828 + detect and ignore banners in non-interactive 18.829 + <command>ssh</command> sessions, but it is not foolproof. (If 18.830 + you're editing your login scripts on your server, the usual 18.831 + way to see if a login script is running in an interactive 18.832 + shell is to check the return code from the command 18.833 + <literal>tty -s</literal>.)</para> 18.834 + 18.835 + <para id="x_4af">Once you've verified that plain old ssh is working with 18.836 + your server, the next step is to ensure that Mercurial runs on 18.837 + the server. The following command should run 18.838 + successfully:</para> 18.839 + 18.840 + <programlisting>ssh myserver hg version</programlisting> 18.841 + 18.842 + <para id="x_4b0">If you see an error message instead of normal <command 18.843 + role="hg-cmd">hg version</command> output, this is usually 18.844 + because you haven't installed Mercurial to <filename 18.845 + class="directory">/usr/bin</filename>. Don't worry if this 18.846 + is the case; you don't need to do that. But you should check 18.847 + for a few possible problems.</para> 18.848 + <itemizedlist> 18.849 + <listitem><para id="x_4b1">Is Mercurial really installed on the server at 18.850 + all? I know this sounds trivial, but it's worth 18.851 + checking!</para> 18.852 + </listitem> 18.853 + <listitem><para id="x_4b2">Maybe your shell's search path (usually set 18.854 + via the <envar>PATH</envar> environment variable) is 18.855 + simply misconfigured.</para> 18.856 + </listitem> 18.857 + <listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment 18.858 + variable is only being set to point to the location of the 18.859 + <command>hg</command> executable if the login session is 18.860 + interactive. This can happen if you're setting the path 18.861 + in the wrong shell login script. See your shell's 18.862 + documentation for details.</para> 18.863 + </listitem> 18.864 + <listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> environment 18.865 + variable may need to contain the path to the Mercurial 18.866 + Python modules. It might not be set at all; it could be 18.867 + incorrect; or it may be set only if the login is 18.868 + interactive.</para> 18.869 + </listitem></itemizedlist> 18.870 + 18.871 + <para id="x_4b5">If you can run <command role="hg-cmd">hg version</command> 18.872 + over an ssh connection, well done! You've got the server and 18.873 + client sorted out. You should now be able to use Mercurial to 18.874 + access repositories hosted by that username on that server. 18.875 + If you run into problems with Mercurial and ssh at this point, 18.876 + try using the <option role="hg-opt-global">--debug</option> 18.877 + option to get a clearer picture of what's going on.</para> 18.878 + </sect2> 18.879 + <sect2> 18.880 + <title>Using compression with ssh</title> 18.881 + 18.882 + <para id="x_4b6">Mercurial does not compress data when it uses the ssh 18.883 + protocol, because the ssh protocol can transparently compress 18.884 + data. However, the default behavior of ssh clients is 18.885 + <emphasis>not</emphasis> to request compression.</para> 18.886 + 18.887 + <para id="x_4b7">Over any network other than a fast LAN (even a wireless 18.888 + network), using compression is likely to significantly speed 18.889 + up Mercurial's network operations. For example, over a WAN, 18.890 + someone measured compression as reducing the amount of time 18.891 + required to clone a particularly large repository from 51 18.892 + minutes to 17 minutes.</para> 18.893 + 18.894 + <para id="x_4b8">Both <command>ssh</command> and <command>plink</command> 18.895 + accept a <option role="cmd-opt-ssh">-C</option> option which 18.896 + turns on compression. You can easily edit your <filename 18.897 + role="special">~/.hgrc</filename> to enable compression for 18.898 + all of Mercurial's uses of the ssh protocol. Here is how to 18.899 + do so for regular <command>ssh</command> on Unix-like systems, 18.900 + for example.</para> 18.901 + <programlisting>[ui] 18.902 +ssh = ssh -C</programlisting> 18.903 + 18.904 + <para id="x_4b9">If you use <command>ssh</command> on a 18.905 + Unix-like system, you can configure it to always use 18.906 + compression when talking to your server. To do this, edit 18.907 + your <filename role="special">.ssh/config</filename> file 18.908 + (which may not yet exist), as follows.</para> 18.909 + 18.910 + <programlisting>Host hg 18.911 + Compression yes 18.912 + HostName hg.example.com</programlisting> 18.913 + 18.914 + <para id="x_4ba">This defines a hostname alias, 18.915 + <literal>hg</literal>. When you use that hostname on the 18.916 + <command>ssh</command> command line or in a Mercurial 18.917 + <literal>ssh</literal>-protocol URL, it will cause 18.918 + <command>ssh</command> to connect to 18.919 + <literal>hg.example.com</literal> and use compression. This 18.920 + gives you both a shorter name to type and compression, each of 18.921 + which is a good thing in its own right.</para> 18.922 + </sect2> 18.923 + </sect1> 18.924 + 18.925 + <sect1 id="sec:collab:cgi"> 18.926 + <title>Serving over HTTP using CGI</title> 18.927 + 18.928 + <para id="x_6a8">The simplest way to host one or more repositories in a 18.929 + permanent way is to use a web server and Mercurial's CGI 18.930 + support.</para> 18.931 + 18.932 + <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's 18.933 + CGI interface can take anything from a few moments to several 18.934 + hours.</para> 18.935 + 18.936 + <para id="x_4bc">We'll begin with the simplest of examples, and work our way 18.937 + towards a more complex configuration. Even for the most basic 18.938 + case, you're almost certainly going to need to read and modify 18.939 + your web server's configuration.</para> 18.940 + 18.941 + <note> 18.942 + <title>High pain tolerance required</title> 18.943 + 18.944 + <para id="x_4bd">Configuring a web server is a complex, fiddly, 18.945 + and highly system-dependent activity. I can't possibly give 18.946 + you instructions that will cover anything like all of the 18.947 + cases you will encounter. Please use your discretion and 18.948 + judgment in following the sections below. Be prepared to make 18.949 + plenty of mistakes, and to spend a lot of time reading your 18.950 + server's error logs.</para> 18.951 + 18.952 + <para id="x_6a9">If you don't have a strong stomach for tweaking 18.953 + configurations over and over, or a compelling need to host 18.954 + your own services, you might want to try one of the public 18.955 + hosting services that I mentioned earlier.</para> 18.956 + </note> 18.957 + 18.958 + <sect2> 18.959 + <title>Web server configuration checklist</title> 18.960 + 18.961 + <para id="x_4be">Before you continue, do take a few moments to check a few 18.962 + aspects of your system's setup.</para> 18.963 + 18.964 + <orderedlist> 18.965 + <listitem><para id="x_4bf">Do you have a web server installed 18.966 + at all? Mac OS X and some Linux distributions ship with 18.967 + Apache, but many other systems may not have a web server 18.968 + installed.</para> 18.969 + </listitem> 18.970 + <listitem><para id="x_4c0">If you have a web server installed, is it 18.971 + actually running? On most systems, even if one is 18.972 + present, it will be disabled by default.</para> 18.973 + </listitem> 18.974 + <listitem><para id="x_4c1">Is your server configured to allow you to run 18.975 + CGI programs in the directory where you plan to do so? 18.976 + Most servers default to explicitly disabling the ability 18.977 + to run CGI programs.</para> 18.978 + </listitem></orderedlist> 18.979 + 18.980 + <para id="x_4c2">If you don't have a web server installed, and don't have 18.981 + substantial experience configuring Apache, you should consider 18.982 + using the <literal>lighttpd</literal> web server instead of 18.983 + Apache. Apache has a well-deserved reputation for baroque and 18.984 + confusing configuration. While <literal>lighttpd</literal> is 18.985 + less capable in some ways than Apache, most of these 18.986 + capabilities are not relevant to serving Mercurial 18.987 + repositories. And <literal>lighttpd</literal> is undeniably 18.988 + <emphasis>much</emphasis> easier to get started with than 18.989 + Apache.</para> 18.990 + </sect2> 18.991 + 18.992 + <sect2> 18.993 + <title>Basic CGI configuration</title> 18.994 + 18.995 + <para id="x_4c3">On Unix-like systems, it's common for users to have a 18.996 + subdirectory named something like <filename 18.997 + class="directory">public_html</filename> in their home 18.998 + directory, from which they can serve up web pages. A file 18.999 + named <filename>foo</filename> in this directory will be 18.1000 + accessible at a URL of the form 18.1001 + <literal>http://www.example.com/username/foo</literal>.</para> 18.1002 + 18.1003 + <para id="x_4c4">To get started, find the <filename 18.1004 + role="special">hgweb.cgi</filename> script that should be 18.1005 + present in your Mercurial installation. If you can't quickly 18.1006 + find a local copy on your system, simply download one from the 18.1007 + master Mercurial repository at <ulink 18.1008 + 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.1009 + 18.1010 + <para id="x_4c5">You'll need to copy this script into your <filename 18.1011 + class="directory">public_html</filename> directory, and 18.1012 + ensure that it's executable.</para> 18.1013 + <programlisting>cp .../hgweb.cgi ~/public_html 18.1014 +chmod 755 ~/public_html/hgweb.cgi</programlisting> 18.1015 + <para id="x_4c6">The <literal>755</literal> argument to 18.1016 + <command>chmod</command> is a little more general than just 18.1017 + making the script executable: it ensures that the script is 18.1018 + executable by anyone, and that <quote>group</quote> and 18.1019 + <quote>other</quote> write permissions are 18.1020 + <emphasis>not</emphasis> set. If you were to leave those 18.1021 + write permissions enabled, Apache's <literal>suexec</literal> 18.1022 + subsystem would likely refuse to execute the script. In fact, 18.1023 + <literal>suexec</literal> also insists that the 18.1024 + <emphasis>directory</emphasis> in which the script resides 18.1025 + must not be writable by others.</para> 18.1026 + <programlisting>chmod 755 ~/public_html</programlisting> 18.1027 + 18.1028 + <sect3 id="sec:collab:wtf"> 18.1029 + <title>What could <emphasis>possibly</emphasis> go 18.1030 + wrong?</title> 18.1031 + 18.1032 + <para id="x_4c7">Once you've copied the CGI script into place, 18.1033 + go into a web browser, and try to open the URL 18.1034 + <literal>http://myhostname/~myuser/hgweb.cgi</literal>, 18.1035 + <emphasis>but</emphasis> brace yourself for instant failure. 18.1036 + There's a high probability that trying to visit this URL 18.1037 + will fail, and there are many possible reasons for this. In 18.1038 + fact, you're likely to stumble over almost every one of the 18.1039 + possible errors below, so please read carefully. The 18.1040 + following are all of the problems I ran into on a system 18.1041 + running Fedora 7, with a fresh installation of Apache, and a 18.1042 + user account that I created specially to perform this 18.1043 + exercise.</para> 18.1044 + 18.1045 + <para id="x_4c8">Your web server may have per-user directories disabled. 18.1046 + If you're using Apache, search your config file for a 18.1047 + <literal>UserDir</literal> directive. If there's none 18.1048 + present, per-user directories will be disabled. If one 18.1049 + exists, but its value is <literal>disabled</literal>, then 18.1050 + per-user directories will be disabled. Otherwise, the 18.1051 + string after <literal>UserDir</literal> gives the name of 18.1052 + the subdirectory that Apache will look in under your home 18.1053 + directory, for example <filename 18.1054 + class="directory">public_html</filename>.</para> 18.1055 + 18.1056 + <para id="x_4c9">Your file access permissions may be too restrictive. 18.1057 + The web server must be able to traverse your home directory 18.1058 + and directories under your <filename 18.1059 + class="directory">public_html</filename> directory, and 18.1060 + read files under the latter too. Here's a quick recipe to 18.1061 + help you to make your permissions more appropriate.</para> 18.1062 + <programlisting>chmod 755 ~ 18.1063 +find ~/public_html -type d -print0 | xargs -0r chmod 755 18.1064 +find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting> 18.1065 + 18.1066 + <para id="x_4ca">The other possibility with permissions is that you might 18.1067 + get a completely empty window when you try to load the 18.1068 + script. In this case, it's likely that your access 18.1069 + permissions are <emphasis>too permissive</emphasis>. Apache's 18.1070 + <literal>suexec</literal> subsystem won't execute a script 18.1071 + that's group- or world-writable, for example.</para> 18.1072 + 18.1073 + <para id="x_4cb">Your web server may be configured to disallow execution 18.1074 + of CGI programs in your per-user web directory. Here's 18.1075 + Apache's default per-user configuration from my Fedora 18.1076 + system.</para> 18.1077 + 18.1078 + &ch06-apache-config.lst; 18.1079 + 18.1080 + <para id="x_4cc">If you find a similar-looking 18.1081 + <literal>Directory</literal> group in your Apache 18.1082 + configuration, the directive to look at inside it is 18.1083 + <literal>Options</literal>. Add <literal>ExecCGI</literal> 18.1084 + to the end of this list if it's missing, and restart the web 18.1085 + server.</para> 18.1086 + 18.1087 + <para id="x_4cd">If you find that Apache serves you the text of the CGI 18.1088 + script instead of executing it, you may need to either 18.1089 + uncomment (if already present) or add a directive like 18.1090 + this.</para> 18.1091 + <programlisting>AddHandler cgi-script .cgi</programlisting> 18.1092 + 18.1093 + <para id="x_4ce">The next possibility is that you might be served with a 18.1094 + colourful Python backtrace claiming that it can't import a 18.1095 + <literal>mercurial</literal>-related module. This is 18.1096 + actually progress! The server is now capable of executing 18.1097 + your CGI script. This error is only likely to occur if 18.1098 + you're running a private installation of Mercurial, instead 18.1099 + of a system-wide version. Remember that the web server runs 18.1100 + the CGI program without any of the environment variables 18.1101 + that you take for granted in an interactive session. If 18.1102 + this error happens to you, edit your copy of <filename 18.1103 + role="special">hgweb.cgi</filename> and follow the 18.1104 + directions inside it to correctly set your 18.1105 + <envar>PYTHONPATH</envar> environment variable.</para> 18.1106 + 18.1107 + <para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to be 18.1108 + served with another colourful Python backtrace: this one 18.1109 + will complain that it can't find <filename 18.1110 + class="directory">/path/to/repository</filename>. Edit 18.1111 + your <filename role="special">hgweb.cgi</filename> script 18.1112 + and replace the <filename 18.1113 + class="directory">/path/to/repository</filename> string 18.1114 + with the complete path to the repository you want to serve 18.1115 + up.</para> 18.1116 + 18.1117 + <para id="x_4d0">At this point, when you try to reload the page, you 18.1118 + should be presented with a nice HTML view of your 18.1119 + repository's history. Whew!</para> 18.1120 + </sect3> 18.1121 + 18.1122 + <sect3> 18.1123 + <title>Configuring lighttpd</title> 18.1124 + 18.1125 + <para id="x_4d1">To be exhaustive in my experiments, I tried configuring 18.1126 + the increasingly popular <literal>lighttpd</literal> web 18.1127 + server to serve the same repository as I described with 18.1128 + Apache above. I had already overcome all of the problems I 18.1129 + outlined with Apache, many of which are not server-specific. 18.1130 + As a result, I was fairly sure that my file and directory 18.1131 + permissions were good, and that my <filename 18.1132 + role="special">hgweb.cgi</filename> script was properly 18.1133 + edited.</para> 18.1134 + 18.1135 + <para id="x_4d2">Once I had Apache running, getting 18.1136 + <literal>lighttpd</literal> to serve the repository was a 18.1137 + snap (in other words, even if you're trying to use 18.1138 + <literal>lighttpd</literal>, you should read the Apache 18.1139 + section). I first had to edit the 18.1140 + <literal>mod_access</literal> section of its config file to 18.1141 + enable <literal>mod_cgi</literal> and 18.1142 + <literal>mod_userdir</literal>, both of which were disabled 18.1143 + by default on my system. I then added a few lines to the 18.1144 + end of the config file, to configure these modules.</para> 18.1145 + <programlisting>userdir.path = "public_html" 18.1146 +cgi.assign = (".cgi" => "" )</programlisting> 18.1147 + <para id="x_4d3">With this done, <literal>lighttpd</literal> ran 18.1148 + immediately for me. If I had configured 18.1149 + <literal>lighttpd</literal> before Apache, I'd almost 18.1150 + certainly have run into many of the same system-level 18.1151 + configuration problems as I did with Apache. However, I 18.1152 + found <literal>lighttpd</literal> to be noticeably easier to 18.1153 + configure than Apache, even though I've used Apache for over 18.1154 + a decade, and this was my first exposure to 18.1155 + <literal>lighttpd</literal>.</para> 18.1156 + </sect3> 18.1157 + </sect2> 18.1158 + 18.1159 + <sect2> 18.1160 + <title>Sharing multiple repositories with one CGI script</title> 18.1161 + 18.1162 + <para id="x_4d4">The <filename role="special">hgweb.cgi</filename> script 18.1163 + only lets you publish a single repository, which is an 18.1164 + annoying restriction. If you want to publish more than one 18.1165 + without wracking yourself with multiple copies of the same 18.1166 + script, each with different names, a better choice is to use 18.1167 + the <filename role="special">hgwebdir.cgi</filename> 18.1168 + script.</para> 18.1169 + 18.1170 + <para id="x_4d5">The procedure to configure <filename 18.1171 + role="special">hgwebdir.cgi</filename> is only a little more 18.1172 + involved than for <filename 18.1173 + role="special">hgweb.cgi</filename>. First, you must obtain 18.1174 + a copy of the script. If you don't have one handy, you can 18.1175 + download a copy from the master Mercurial repository at <ulink 18.1176 + 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.1177 + 18.1178 + <para id="x_4d6">You'll need to copy this script into your <filename 18.1179 + class="directory">public_html</filename> directory, and 18.1180 + ensure that it's executable.</para> 18.1181 + 18.1182 + <programlisting>cp .../hgwebdir.cgi ~/public_html 18.1183 +chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting> 18.1184 + 18.1185 + <para id="x_4d7">With basic configuration out of the way, try to 18.1186 + visit <literal>http://myhostname/~myuser/hgwebdir.cgi</literal> 18.1187 + in your browser. It should 18.1188 + display an empty list of repositories. If you get a blank 18.1189 + window or error message, try walking through the list of 18.1190 + potential problems in <xref 18.1191 + linkend="sec:collab:wtf"/>.</para> 18.1192 + 18.1193 + <para id="x_4d8">The <filename role="special">hgwebdir.cgi</filename> 18.1194 + script relies on an external configuration file. By default, 18.1195 + it searches for a file named <filename 18.1196 + role="special">hgweb.config</filename> in the same directory 18.1197 + as itself. You'll need to create this file, and make it 18.1198 + world-readable. The format of the file is similar to a 18.1199 + Windows <quote>ini</quote> file, as understood by Python's 18.1200 + <literal>ConfigParser</literal> 18.1201 + <citation>web:configparser</citation> module.</para> 18.1202 + 18.1203 + <para id="x_4d9">The easiest way to configure <filename 18.1204 + role="special">hgwebdir.cgi</filename> is with a section 18.1205 + named <literal>collections</literal>. This will automatically 18.1206 + publish <emphasis>every</emphasis> repository under the 18.1207 + directories you name. The section should look like 18.1208 + this:</para> 18.1209 + <programlisting>[collections] 18.1210 +/my/root = /my/root</programlisting> 18.1211 + <para id="x_4da">Mercurial interprets this by looking at the directory name 18.1212 + on the <emphasis>right</emphasis> hand side of the 18.1213 + <quote><literal>=</literal></quote> sign; finding repositories 18.1214 + in that directory hierarchy; and using the text on the 18.1215 + <emphasis>left</emphasis> to strip off matching text from the 18.1216 + names it will actually list in the web interface. The 18.1217 + remaining component of a path after this stripping has 18.1218 + occurred is called a <quote>virtual path</quote>.</para> 18.1219 + 18.1220 + <para id="x_4db">Given the example above, if we have a 18.1221 + repository whose local path is <filename 18.1222 + class="directory">/my/root/this/repo</filename>, the CGI 18.1223 + script will strip the leading <filename 18.1224 + class="directory">/my/root</filename> from the name, and 18.1225 + publish the repository with a virtual path of <filename 18.1226 + class="directory">this/repo</filename>. If the base URL for 18.1227 + our CGI script is 18.1228 + <literal>http://myhostname/~myuser/hgwebdir.cgi</literal>, the 18.1229 + complete URL for that repository will be 18.1230 + <literal>http://myhostname/~myuser/hgwebdir.cgi/this/repo</literal>.</para> 18.1231 + 18.1232 + <para id="x_4dc">If we replace <filename 18.1233 + class="directory">/my/root</filename> on the left hand side 18.1234 + of this example with <filename 18.1235 + class="directory">/my</filename>, then <filename 18.1236 + role="special">hgwebdir.cgi</filename> will only strip off 18.1237 + <filename class="directory">/my</filename> from the repository 18.1238 + name, and will give us a virtual path of <filename 18.1239 + class="directory">root/this/repo</filename> instead of 18.1240 + <filename class="directory">this/repo</filename>.</para> 18.1241 + 18.1242 + <para id="x_4dd">The <filename role="special">hgwebdir.cgi</filename> 18.1243 + script will recursively search each directory listed in the 18.1244 + <literal>collections</literal> section of its configuration 18.1245 + file, but it will <literal>not</literal> recurse into the 18.1246 + repositories it finds.</para> 18.1247 + 18.1248 + <para id="x_4de">The <literal>collections</literal> mechanism makes it easy 18.1249 + to publish many repositories in a <quote>fire and 18.1250 + forget</quote> manner. You only need to set up the CGI 18.1251 + script and configuration file one time. Afterwards, you can 18.1252 + publish or unpublish a repository at any time by simply moving 18.1253 + it into, or out of, the directory hierarchy in which you've 18.1254 + configured <filename role="special">hgwebdir.cgi</filename> to 18.1255 + look.</para> 18.1256 + 18.1257 + <sect3> 18.1258 + <title>Explicitly specifying which repositories to 18.1259 + publish</title> 18.1260 + 18.1261 + <para id="x_4df">In addition to the <literal>collections</literal> 18.1262 + mechanism, the <filename 18.1263 + role="special">hgwebdir.cgi</filename> script allows you 18.1264 + to publish a specific list of repositories. To do so, 18.1265 + create a <literal>paths</literal> section, with contents of 18.1266 + the following form.</para> 18.1267 + <programlisting>[paths] 18.1268 +repo1 = /my/path/to/some/repo 18.1269 +repo2 = /some/path/to/another</programlisting> 18.1270 + <para id="x_4e0">In this case, the virtual path (the component that will 18.1271 + appear in a URL) is on the left hand side of each 18.1272 + definition, while the path to the repository is on the 18.1273 + right. Notice that there does not need to be any 18.1274 + relationship between the virtual path you choose and the 18.1275 + location of a repository in your filesystem.</para> 18.1276 + 18.1277 + <para id="x_4e1">If you wish, you can use both the 18.1278 + <literal>collections</literal> and <literal>paths</literal> 18.1279 + mechanisms simultaneously in a single configuration 18.1280 + file.</para> 18.1281 + 18.1282 + <note> 18.1283 + <title>Beware duplicate virtual paths</title> 18.1284 + 18.1285 + <para id="x_4e2"> If several repositories have the same 18.1286 + virtual path, <filename 18.1287 + role="special">hgwebdir.cgi</filename> will not report 18.1288 + an error. Instead, it will behave unpredictably.</para> 18.1289 + </note> 18.1290 + </sect3> 18.1291 + </sect2> 18.1292 + 18.1293 + <sect2> 18.1294 + <title>Downloading source archives</title> 18.1295 + 18.1296 + <para id="x_4e3">Mercurial's web interface lets users download an archive 18.1297 + of any revision. This archive will contain a snapshot of the 18.1298 + working directory as of that revision, but it will not contain 18.1299 + a copy of the repository data.</para> 18.1300 + 18.1301 + <para id="x_4e4">By default, this feature is not enabled. To enable it, 18.1302 + you'll need to add an <envar 18.1303 + role="rc-item-web">allow_archive</envar> item to the 18.1304 + <literal role="rc-web">web</literal> section of your <filename 18.1305 + role="special">~/.hgrc</filename>; see below for details.</para> 18.1306 + </sect2> 18.1307 + <sect2> 18.1308 + <title>Web configuration options</title> 18.1309 + 18.1310 + <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd">hg 18.1311 + serve</command> command, and the <filename 18.1312 + role="special">hgweb.cgi</filename> and <filename 18.1313 + role="special">hgwebdir.cgi</filename> scripts) have a 18.1314 + number of configuration options that you can set. These 18.1315 + belong in a section named <literal 18.1316 + role="rc-web">web</literal>.</para> 18.1317 + <itemizedlist> 18.1318 + <listitem><para id="x_4e6"><envar 18.1319 + role="rc-item-web">allow_archive</envar>: Determines 18.1320 + which (if any) archive download mechanisms Mercurial 18.1321 + supports. If you enable this feature, users of the web 18.1322 + interface will be able to download an archive of whatever 18.1323 + revision of a repository they are viewing. To enable the 18.1324 + archive feature, this item must take the form of a 18.1325 + sequence of words drawn from the list below.</para> 18.1326 + <itemizedlist> 18.1327 + <listitem><para id="x_4e7"><literal>bz2</literal>: A 18.1328 + <command>tar</command> archive, compressed using 18.1329 + <literal>bzip2</literal> compression. This has the 18.1330 + best compression ratio, but uses the most CPU time on 18.1331 + the server.</para> 18.1332 + </listitem> 18.1333 + <listitem><para id="x_4e8"><literal>gz</literal>: A 18.1334 + <command>tar</command> archive, compressed using 18.1335 + <literal>gzip</literal> compression.</para> 18.1336 + </listitem> 18.1337 + <listitem><para id="x_4e9"><literal>zip</literal>: A 18.1338 + <command>zip</command> archive, compressed using LZW 18.1339 + compression. This format has the worst compression 18.1340 + ratio, but is widely used in the Windows world.</para> 18.1341 + </listitem> 18.1342 + </itemizedlist> 18.1343 + <para id="x_4ea"> If you provide an empty list, or don't have an 18.1344 + <envar role="rc-item-web">allow_archive</envar> entry at 18.1345 + all, this feature will be disabled. Here is an example of 18.1346 + how to enable all three supported formats.</para> 18.1347 + <programlisting>[web] 18.1348 +allow_archive = bz2 gz zip</programlisting> 18.1349 + </listitem> 18.1350 + <listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>: 18.1351 + Boolean. Determines whether the web interface allows 18.1352 + remote users to <command role="hg-cmd">hg pull</command> 18.1353 + and <command role="hg-cmd">hg clone</command> this 18.1354 + repository over HTTP. If set to <literal>no</literal> or 18.1355 + <literal>false</literal>, only the 18.1356 + <quote>human-oriented</quote> portion of the web interface 18.1357 + is available.</para> 18.1358 + </listitem> 18.1359 + <listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>: 18.1360 + String. A free-form (but preferably brief) string 18.1361 + identifying the person or group in charge of the 18.1362 + repository. This often contains the name and email 18.1363 + address of a person or mailing list. It often makes sense 18.1364 + to place this entry in a repository's own <filename 18.1365 + role="special">.hg/hgrc</filename> file, but it can make 18.1366 + sense to use in a global <filename 18.1367 + role="special">~/.hgrc</filename> if every repository 18.1368 + has a single maintainer.</para> 18.1369 + </listitem> 18.1370 + <listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>: 18.1371 + Integer. The default maximum number of changesets to 18.1372 + display in a single page of output.</para> 18.1373 + </listitem> 18.1374 + <listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>: 18.1375 + Integer. The default maximum number of modified files to 18.1376 + display in a single page of output.</para> 18.1377 + </listitem> 18.1378 + <listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>: 18.1379 + Integer. If the web interface displays alternating 18.1380 + <quote>stripes</quote> to make it easier to visually align 18.1381 + rows when you are looking at a table, this number controls 18.1382 + the number of rows in each stripe.</para> 18.1383 + </listitem> 18.1384 + <listitem><para id="x_4f0"><envar 18.1385 + role="rc-item-web">style</envar>: Controls the template 18.1386 + Mercurial uses to display the web interface. Mercurial 18.1387 + ships with several web templates.</para> 18.1388 + <itemizedlist> 18.1389 + <listitem> 18.1390 + <para id="x_6aa"><literal>coal</literal> is monochromatic.</para> 18.1391 + </listitem> 18.1392 + <listitem> 18.1393 + <para id="x_6ab"><literal>gitweb</literal> emulates the visual 18.1394 + style of git's web interface.</para> 18.1395 + </listitem> 18.1396 + <listitem> 18.1397 + <para id="x_6ac"><literal>monoblue</literal> uses solid blues and 18.1398 + greys.</para> 18.1399 + </listitem> 18.1400 + <listitem> 18.1401 + <para id="x_6ad"><literal>paper</literal> is the default.</para> 18.1402 + </listitem> 18.1403 + <listitem> 18.1404 + <para id="x_6ae"><literal>spartan</literal> was the default for a 18.1405 + long time.</para> 18.1406 + </listitem> 18.1407 + </itemizedlist> 18.1408 + <para id="x_6af">You can 18.1409 + also specify a custom template of your own; see 18.1410 + <xref linkend="chap:template"/> for details. Here, you can 18.1411 + see how to enable the <literal>gitweb</literal> 18.1412 + style.</para> 18.1413 + <programlisting>[web] 18.1414 +style = gitweb</programlisting> 18.1415 + </listitem> 18.1416 + <listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>: 18.1417 + Path. The directory in which to search for template 18.1418 + files. By default, Mercurial searches in the directory in 18.1419 + which it was installed.</para> 18.1420 + </listitem></itemizedlist> 18.1421 + <para id="x_4f2">If you are using <filename 18.1422 + role="special">hgwebdir.cgi</filename>, you can place a few 18.1423 + configuration items in a <literal role="rc-web">web</literal> 18.1424 + section of the <filename 18.1425 + role="special">hgweb.config</filename> file instead of a 18.1426 + <filename role="special">~/.hgrc</filename> file, for 18.1427 + convenience. These items are <envar 18.1428 + role="rc-item-web">motd</envar> and <envar 18.1429 + role="rc-item-web">style</envar>.</para> 18.1430 + 18.1431 + <sect3> 18.1432 + <title>Options specific to an individual repository</title> 18.1433 + 18.1434 + <para id="x_4f3">A few <literal role="rc-web">web</literal> configuration 18.1435 + items ought to be placed in a repository's local <filename 18.1436 + role="special">.hg/hgrc</filename>, rather than a user's 18.1437 + or global <filename role="special">~/.hgrc</filename>.</para> 18.1438 + <itemizedlist> 18.1439 + <listitem><para id="x_4f4"><envar 18.1440 + role="rc-item-web">description</envar>: String. A 18.1441 + free-form (but preferably brief) string that describes 18.1442 + the contents or purpose of the repository.</para> 18.1443 + </listitem> 18.1444 + <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>: 18.1445 + String. The name to use for the repository in the web 18.1446 + interface. This overrides the default name, which is 18.1447 + the last component of the repository's path.</para> 18.1448 + </listitem></itemizedlist> 18.1449 + </sect3> 18.1450 + 18.1451 + <sect3> 18.1452 + <title>Options specific to the <command role="hg-cmd">hg 18.1453 + serve</command> command</title> 18.1454 + 18.1455 + <para id="x_4f6">Some of the items in the <literal 18.1456 + role="rc-web">web</literal> section of a <filename 18.1457 + role="special">~/.hgrc</filename> file are only for use 18.1458 + with the <command role="hg-cmd">hg serve</command> 18.1459 + command.</para> 18.1460 + <itemizedlist> 18.1461 + <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>: 18.1462 + Path. The name of a file into which to write an access 18.1463 + log. By default, the <command role="hg-cmd">hg 18.1464 + serve</command> command writes this information to 18.1465 + standard output, not to a file. Log entries are written 18.1466 + in the standard <quote>combined</quote> file format used 18.1467 + by almost all web servers.</para> 18.1468 + </listitem> 18.1469 + <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>: 18.1470 + String. The local address on which the server should 18.1471 + listen for incoming connections. By default, the server 18.1472 + listens on all addresses.</para> 18.1473 + </listitem> 18.1474 + <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>: 18.1475 + Path. The name of a file into which to write an error 18.1476 + log. By default, the <command role="hg-cmd">hg 18.1477 + serve</command> command writes this information to 18.1478 + standard error, not to a file.</para> 18.1479 + </listitem> 18.1480 + <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>: 18.1481 + Boolean. Whether to use the IPv6 protocol. By default, 18.1482 + IPv6 is not used.</para> 18.1483 + </listitem> 18.1484 + <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>: 18.1485 + Integer. The TCP port number on which the server should 18.1486 + listen. The default port number used is 8000.</para> 18.1487 + </listitem></itemizedlist> 18.1488 + </sect3> 18.1489 + 18.1490 + <sect3> 18.1491 + <title>Choosing the right <filename 18.1492 + role="special">~/.hgrc</filename> file to add <literal 18.1493 + role="rc-web">web</literal> items to</title> 18.1494 + 18.1495 + <para id="x_4fc">It is important to remember that a web server like 18.1496 + Apache or <literal>lighttpd</literal> will run under a user 18.1497 + ID that is different to yours. CGI scripts run by your 18.1498 + server, such as <filename 18.1499 + role="special">hgweb.cgi</filename>, will usually also run 18.1500 + under that user ID.</para> 18.1501 + 18.1502 + <para id="x_4fd">If you add <literal role="rc-web">web</literal> items to 18.1503 + your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that 18.1504 + <filename role="special">~/.hgrc</filename> file. Those 18.1505 + settings will thus only affect the behavior of the <command 18.1506 + role="hg-cmd">hg serve</command> command when you run it. 18.1507 + To cause CGI scripts to see your settings, either create a 18.1508 + <filename role="special">~/.hgrc</filename> file in the 18.1509 + home directory of the user ID that runs your web server, or 18.1510 + add those settings to a system-wide <filename 18.1511 + role="special">hgrc</filename> file.</para> 18.1512 + </sect3> 18.1513 + </sect2> 18.1514 + </sect1> 18.1515 + 18.1516 + <sect1> 18.1517 + <title>System-wide configuration</title> 18.1518 + 18.1519 + <para id="x_6b0">On Unix-like systems shared by multiple users (such as a 18.1520 + server to which people publish changes), it often makes sense to 18.1521 + set up some global default behaviors, such as what theme to use 18.1522 + in web interfaces.</para> 18.1523 + 18.1524 + <para id="x_6b1">If a file named <filename>/etc/mercurial/hgrc</filename> 18.1525 + exists, Mercurial will read it at startup time and apply any 18.1526 + configuration settings it finds in that file. It will also look 18.1527 + for files ending in a <literal>.rc</literal> extension in a 18.1528 + directory named <filename>/etc/mercurial/hgrc.d</filename>, and 18.1529 + apply any configuration settings it finds in each of those 18.1530 + files.</para> 18.1531 + 18.1532 + <sect2> 18.1533 + <title>Making Mercurial more trusting</title> 18.1534 + 18.1535 + <para id="x_6b2">One situation in which a global <filename>hgrc</filename> 18.1536 + can be useful is if users are pulling changes owned by other 18.1537 + users. By default, Mercurial will not trust most of the 18.1538 + configuration items in a <filename>.hg/hgrc</filename> file 18.1539 + inside a repository that is owned by a different user. If we 18.1540 + clone or pull changes from such a repository, Mercurial will 18.1541 + print a warning stating that it does not trust their 18.1542 + <filename>.hg/hgrc</filename>.</para> 18.1543 + 18.1544 + <para id="x_6b3">If everyone in a particular Unix group is on the same team 18.1545 + and <emphasis>should</emphasis> trust each other's 18.1546 + configuration settings, or we want to trust particular users, 18.1547 + we can override Mercurial's skeptical defaults by creating a 18.1548 + system-wide <filename>hgrc</filename> file such as the 18.1549 + following:</para> 18.1550 + 18.1551 + <programlisting># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc 18.1552 +[trusted] 18.1553 +# Trust all entries in any hgrc file owned by the "editors" or 18.1554 +# "www-data" groups. 18.1555 +groups = editors, www-data 18.1556 + 18.1557 +# Trust entries in hgrc files owned by the following users. 18.1558 +users = apache, bobo 18.1559 +</programlisting> 18.1560 + </sect2> 18.1561 + </sect1> 18.1562 +</chapter> 18.1563 + 18.1564 +<!-- 18.1565 +local variables: 18.1566 +sgml-parent-document: ("00book.xml" "book" "chapter") 18.1567 +end: 18.1568 +-->
19.1 --- a/en/ch06-filenames.xml Sat Apr 18 11:52:33 2009 +0800 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,450 +0,0 @@ 19.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 19.5 - 19.6 -<chapter id="chap:names"> 19.7 - <?dbhtml filename="file-names-and-pattern-matching.html"?> 19.8 - <title>File names and pattern matching</title> 19.9 - 19.10 - <para id="x_543">Mercurial provides mechanisms that let you work with file 19.11 - names in a consistent and expressive way.</para> 19.12 - 19.13 - <sect1> 19.14 - <title>Simple file naming</title> 19.15 - 19.16 - <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the 19.17 - hood</quote> to handle file names. Every command behaves 19.18 - uniformly with respect to file names. The way in which commands 19.19 - work with file names is as follows.</para> 19.20 - 19.21 - <para id="x_545">If you explicitly name real files on the command line, 19.22 - Mercurial works with exactly those files, as you would expect. 19.23 - &interaction.filenames.files;</para> 19.24 - 19.25 - <para id="x_546">When you provide a directory name, Mercurial will interpret 19.26 - this as <quote>operate on every file in this directory and its 19.27 - subdirectories</quote>. Mercurial traverses the files and 19.28 - subdirectories in a directory in alphabetical order. When it 19.29 - encounters a subdirectory, it will traverse that subdirectory 19.30 - before continuing with the current directory.</para> 19.31 - 19.32 - &interaction.filenames.dirs; 19.33 - </sect1> 19.34 - 19.35 - <sect1> 19.36 - <title>Running commands without any file names</title> 19.37 - 19.38 - <para id="x_547">Mercurial's commands that work with file names have useful 19.39 - default behaviors when you invoke them without providing any 19.40 - file names or patterns. What kind of behavior you should 19.41 - expect depends on what the command does. Here are a few rules 19.42 - of thumb you can use to predict what a command is likely to do 19.43 - if you don't give it any names to work with.</para> 19.44 - <itemizedlist> 19.45 - <listitem><para id="x_548">Most commands will operate on the entire working 19.46 - directory. This is what the <command role="hg-cmd">hg 19.47 - add</command> command does, for example.</para> 19.48 - </listitem> 19.49 - <listitem><para id="x_549">If the command has effects that are difficult or 19.50 - impossible to reverse, it will force you to explicitly 19.51 - provide at least one name or pattern (see below). This 19.52 - protects you from accidentally deleting files by running 19.53 - <command role="hg-cmd">hg remove</command> with no 19.54 - arguments, for example.</para> 19.55 - </listitem></itemizedlist> 19.56 - 19.57 - <para id="x_54a">It's easy to work around these default behaviors if they 19.58 - don't suit you. If a command normally operates on the whole 19.59 - working directory, you can invoke it on just the current 19.60 - directory and its subdirectories by giving it the name 19.61 - <quote><filename class="directory">.</filename></quote>.</para> 19.62 - 19.63 - &interaction.filenames.wdir-subdir; 19.64 - 19.65 - <para id="x_54b">Along the same lines, some commands normally print file 19.66 - names relative to the root of the repository, even if you're 19.67 - invoking them from a subdirectory. Such a command will print 19.68 - file names relative to your subdirectory if you give it explicit 19.69 - names. Here, we're going to run <command role="hg-cmd">hg 19.70 - status</command> from a subdirectory, and get it to operate on 19.71 - the entire working directory while printing file names relative 19.72 - to our subdirectory, by passing it the output of the <command 19.73 - role="hg-cmd">hg root</command> command.</para> 19.74 - 19.75 - &interaction.filenames.wdir-relname; 19.76 - </sect1> 19.77 - 19.78 - <sect1> 19.79 - <title>Telling you what's going on</title> 19.80 - 19.81 - <para id="x_54c">The <command role="hg-cmd">hg add</command> example in the 19.82 - preceding section illustrates something else that's helpful 19.83 - about Mercurial commands. If a command operates on a file that 19.84 - you didn't name explicitly on the command line, it will usually 19.85 - print the name of the file, so that you will not be surprised 19.86 - what's going on.</para> 19.87 - 19.88 - <para id="x_54d">The principle here is of <emphasis>least 19.89 - surprise</emphasis>. If you've exactly named a file on the 19.90 - command line, there's no point in repeating it back at you. If 19.91 - Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g. 19.92 - because you provided no names, or a directory, or a pattern (see 19.93 - below), it is safest to tell you what files it's operating on.</para> 19.94 - 19.95 - <para id="x_54e">For commands that behave this way, you can silence them 19.96 - using the <option role="hg-opt-global">-q</option> option. You 19.97 - can also get them to print the name of every file, even those 19.98 - you've named explicitly, using the <option 19.99 - role="hg-opt-global">-v</option> option.</para> 19.100 - </sect1> 19.101 - 19.102 - <sect1> 19.103 - <title>Using patterns to identify files</title> 19.104 - 19.105 - <para id="x_54f">In addition to working with file and directory names, 19.106 - Mercurial lets you use <emphasis>patterns</emphasis> to identify 19.107 - files. Mercurial's pattern handling is expressive.</para> 19.108 - 19.109 - <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of 19.110 - matching file names to patterns normally falls to the shell. On 19.111 - these systems, you must explicitly tell Mercurial that a name is 19.112 - a pattern. On Windows, the shell does not expand patterns, so 19.113 - Mercurial will automatically identify names that are patterns, 19.114 - and expand them for you.</para> 19.115 - 19.116 - <para id="x_551">To provide a pattern in place of a regular name on the 19.117 - command line, the mechanism is simple:</para> 19.118 - <programlisting>syntax:patternbody</programlisting> 19.119 - <para id="x_552">That is, a pattern is identified by a short text string that 19.120 - says what kind of pattern this is, followed by a colon, followed 19.121 - by the actual pattern.</para> 19.122 - 19.123 - <para id="x_553">Mercurial supports two kinds of pattern syntax. The most 19.124 - frequently used is called <literal>glob</literal>; this is the 19.125 - same kind of pattern matching used by the Unix shell, and should 19.126 - be familiar to Windows command prompt users, too.</para> 19.127 - 19.128 - <para id="x_554">When Mercurial does automatic pattern matching on Windows, 19.129 - it uses <literal>glob</literal> syntax. You can thus omit the 19.130 - <quote><literal>glob:</literal></quote> prefix on Windows, but 19.131 - it's safe to use it, too.</para> 19.132 - 19.133 - <para id="x_555">The <literal>re</literal> syntax is more powerful; it lets 19.134 - you specify patterns using regular expressions, also known as 19.135 - regexps.</para> 19.136 - 19.137 - <para id="x_556">By the way, in the examples that follow, notice that I'm 19.138 - careful to wrap all of my patterns in quote characters, so that 19.139 - they won't get expanded by the shell before Mercurial sees 19.140 - them.</para> 19.141 - 19.142 - <sect2> 19.143 - <title>Shell-style <literal>glob</literal> patterns</title> 19.144 - 19.145 - <para id="x_557">This is an overview of the kinds of patterns you can use 19.146 - when you're matching on glob patterns.</para> 19.147 - 19.148 - <para id="x_558">The <quote><literal>*</literal></quote> character matches 19.149 - any string, within a single directory.</para> 19.150 - 19.151 - &interaction.filenames.glob.star; 19.152 - 19.153 - <para id="x_559">The <quote><literal>**</literal></quote> pattern matches 19.154 - any string, and crosses directory boundaries. It's not a 19.155 - standard Unix glob token, but it's accepted by several popular 19.156 - Unix shells, and is very useful.</para> 19.157 - 19.158 - &interaction.filenames.glob.starstar; 19.159 - 19.160 - <para id="x_55a">The <quote><literal>?</literal></quote> pattern matches 19.161 - any single character.</para> 19.162 - 19.163 - &interaction.filenames.glob.question; 19.164 - 19.165 - <para id="x_55b">The <quote><literal>[</literal></quote> character begins a 19.166 - <emphasis>character class</emphasis>. This matches any single 19.167 - character within the class. The class ends with a 19.168 - <quote><literal>]</literal></quote> character. A class may 19.169 - contain multiple <emphasis>range</emphasis>s of the form 19.170 - <quote><literal>a-f</literal></quote>, which is shorthand for 19.171 - <quote><literal>abcdef</literal></quote>.</para> 19.172 - 19.173 - &interaction.filenames.glob.range; 19.174 - 19.175 - <para id="x_55c">If the first character after the 19.176 - <quote><literal>[</literal></quote> in a character class is a 19.177 - <quote><literal>!</literal></quote>, it 19.178 - <emphasis>negates</emphasis> the class, making it match any 19.179 - single character not in the class.</para> 19.180 - 19.181 - <para id="x_55d">A <quote><literal>{</literal></quote> begins a group of 19.182 - subpatterns, where the whole group matches if any subpattern 19.183 - in the group matches. The <quote><literal>,</literal></quote> 19.184 - character separates subpatterns, and 19.185 - <quote><literal>}</literal></quote> ends the group.</para> 19.186 - 19.187 - &interaction.filenames.glob.group; 19.188 - 19.189 - <sect3> 19.190 - <title>Watch out!</title> 19.191 - 19.192 - <para id="x_55e">Don't forget that if you want to match a pattern in any 19.193 - directory, you should not be using the 19.194 - <quote><literal>*</literal></quote> match-any token, as this 19.195 - will only match within one directory. Instead, use the 19.196 - <quote><literal>**</literal></quote> token. This small 19.197 - example illustrates the difference between the two.</para> 19.198 - 19.199 - &interaction.filenames.glob.star-starstar; 19.200 - </sect3> 19.201 - </sect2> 19.202 - 19.203 - <sect2> 19.204 - <title>Regular expression matching with <literal>re</literal> 19.205 - patterns</title> 19.206 - 19.207 - <para id="x_55f">Mercurial accepts the same regular expression syntax as 19.208 - the Python programming language (it uses Python's regexp 19.209 - engine internally). This is based on the Perl language's 19.210 - regexp syntax, which is the most popular dialect in use (it's 19.211 - also used in Java, for example).</para> 19.212 - 19.213 - <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail 19.214 - here, as regexps are not often used. Perl-style regexps are 19.215 - in any case already exhaustively documented on a multitude of 19.216 - web sites, and in many books. Instead, I will focus here on a 19.217 - few things you should know if you find yourself needing to use 19.218 - regexps with Mercurial.</para> 19.219 - 19.220 - <para id="x_561">A regexp is matched against an entire file name, relative 19.221 - to the root of the repository. In other words, even if you're 19.222 - already in subbdirectory <filename 19.223 - class="directory">foo</filename>, if you want to match files 19.224 - under this directory, your pattern must start with 19.225 - <quote><literal>foo/</literal></quote>.</para> 19.226 - 19.227 - <para id="x_562">One thing to note, if you're familiar with Perl-style 19.228 - regexps, is that Mercurial's are <emphasis>rooted</emphasis>. 19.229 - That is, a regexp starts matching against the beginning of a 19.230 - string; it doesn't look for a match anywhere within the 19.231 - string. To match anywhere in a string, start your pattern 19.232 - with <quote><literal>.*</literal></quote>.</para> 19.233 - </sect2> 19.234 - </sect1> 19.235 - 19.236 - <sect1> 19.237 - <title>Filtering files</title> 19.238 - 19.239 - <para id="x_563">Not only does Mercurial give you a variety of ways to 19.240 - specify files; it lets you further winnow those files using 19.241 - <emphasis>filters</emphasis>. Commands that work with file 19.242 - names accept two filtering options.</para> 19.243 - <itemizedlist> 19.244 - <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or 19.245 - <option role="hg-opt-global">--include</option>, lets you 19.246 - specify a pattern that file names must match in order to be 19.247 - processed.</para> 19.248 - </listitem> 19.249 - <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or 19.250 - <option role="hg-opt-global">--exclude</option>, gives you a 19.251 - way to <emphasis>avoid</emphasis> processing files, if they 19.252 - match this pattern.</para> 19.253 - </listitem></itemizedlist> 19.254 - <para id="x_566">You can provide multiple <option 19.255 - role="hg-opt-global">-I</option> and <option 19.256 - role="hg-opt-global">-X</option> options on the command line, 19.257 - and intermix them as you please. Mercurial interprets the 19.258 - patterns you provide using glob syntax by default (but you can 19.259 - use regexps if you need to).</para> 19.260 - 19.261 - <para id="x_567">You can read a <option role="hg-opt-global">-I</option> 19.262 - filter as <quote>process only the files that match this 19.263 - filter</quote>.</para> 19.264 - 19.265 - &interaction.filenames.filter.include; 19.266 - 19.267 - <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best 19.268 - read as <quote>process only the files that don't match this 19.269 - pattern</quote>.</para> 19.270 - 19.271 - &interaction.filenames.filter.exclude; 19.272 - </sect1> 19.273 - 19.274 - <sect1> 19.275 - <title>Permanently ignoring unwanted files and directories</title> 19.276 - 19.277 - <para id="x_569">When you create a new repository, the chances are 19.278 - that over time it will grow to contain files that ought to 19.279 - <emphasis>not</emphasis> be managed by Mercurial, but which you 19.280 - don't want to see listed every time you run <command>hg 19.281 - status</command>. For instance, <quote>build products</quote> 19.282 - are files that are created as part of a build but which should 19.283 - not be managed by a revision control system. The most common 19.284 - build products are output files produced by software tools such 19.285 - as compilers. As another example, many text editors litter a 19.286 - directory with lock files, temporary working files, and backup 19.287 - files, which it also makes no sense to manage.</para> 19.288 - 19.289 - <para id="x_6b4">To have Mercurial permanently ignore such files, create a 19.290 - file named <filename>.hgignore</filename> in the root of your 19.291 - repository. You <emphasis>should</emphasis> <command>hg 19.292 - add</command> this file so that it gets tracked with the rest of 19.293 - your repository contents, since your collaborators will probably 19.294 - find it useful too.</para> 19.295 - 19.296 - <para id="x_6b5">By default, the <filename>.hgignore</filename> file should 19.297 - contain a list of regular expressions, one per line. Empty 19.298 - lines are skipped. Most people prefer to describe the files they 19.299 - want to ignore using the <quote>glob</quote> syntax that we 19.300 - described above, so a typical <filename>.hgignore</filename> 19.301 - file will start with this directive:</para> 19.302 - 19.303 - <programlisting>syntax: glob</programlisting> 19.304 - 19.305 - <para id="x_6b6">This tells Mercurial to interpret the lines that follow as 19.306 - glob patterns, not regular expressions.</para> 19.307 - 19.308 - <para id="x_6b7">Here is a typical-looking <filename>.hgignore</filename> 19.309 - file.</para> 19.310 - 19.311 - <programlisting>syntax: glob 19.312 -# This line is a comment, and will be skipped. 19.313 -# Empty lines are skipped too. 19.314 - 19.315 -# Backup files left behind by the Emacs editor. 19.316 -*~ 19.317 - 19.318 -# Lock files used by the Emacs editor. 19.319 -# Notice that the "#" character is quoted with a backslash. 19.320 -# This prevents it from being interpreted as starting a comment. 19.321 -.\#* 19.322 - 19.323 -# Temporary files used by the vim editor. 19.324 -.*.swp 19.325 - 19.326 -# A hidden file created by the Mac OS X Finder. 19.327 -.DS_Store 19.328 -</programlisting> 19.329 - </sect1> 19.330 - 19.331 - <sect1 id="sec:names:case"> 19.332 - <title>Case sensitivity</title> 19.333 - 19.334 - <para id="x_56a">If you're working in a mixed development environment that 19.335 - contains both Linux (or other Unix) systems and Macs or Windows 19.336 - systems, you should keep in the back of your mind the knowledge 19.337 - that they treat the case (<quote>N</quote> versus 19.338 - <quote>n</quote>) of file names in incompatible ways. This is 19.339 - not very likely to affect you, and it's easy to deal with if it 19.340 - does, but it could surprise you if you don't know about 19.341 - it.</para> 19.342 - 19.343 - <para id="x_56b">Operating systems and filesystems differ in the way they 19.344 - handle the <emphasis>case</emphasis> of characters in file and 19.345 - directory names. There are three common ways to handle case in 19.346 - names.</para> 19.347 - <itemizedlist> 19.348 - <listitem><para id="x_56c">Completely case insensitive. Uppercase and 19.349 - lowercase versions of a letter are treated as identical, 19.350 - both when creating a file and during subsequent accesses. 19.351 - This is common on older DOS-based systems.</para> 19.352 - </listitem> 19.353 - <listitem><para id="x_56d">Case preserving, but insensitive. When a file 19.354 - or directory is created, the case of its name is stored, and 19.355 - can be retrieved and displayed by the operating system. 19.356 - When an existing file is being looked up, its case is 19.357 - ignored. This is the standard arrangement on Windows and 19.358 - MacOS. The names <filename>foo</filename> and 19.359 - <filename>FoO</filename> identify the same file. This 19.360 - treatment of uppercase and lowercase letters as 19.361 - interchangeable is also referred to as <emphasis>case 19.362 - folding</emphasis>.</para> 19.363 - </listitem> 19.364 - <listitem><para id="x_56e">Case sensitive. The case of a name is 19.365 - significant at all times. The names <filename>foo</filename> 19.366 - and {FoO} identify different files. This is the way Linux 19.367 - and Unix systems normally work.</para> 19.368 - </listitem></itemizedlist> 19.369 - 19.370 - <para id="x_56f">On Unix-like systems, it is possible to have any or all of 19.371 - the above ways of handling case in action at once. For example, 19.372 - if you use a USB thumb drive formatted with a FAT32 filesystem 19.373 - on a Linux system, Linux will handle names on that filesystem in 19.374 - a case preserving, but insensitive, way.</para> 19.375 - 19.376 - <sect2> 19.377 - <title>Safe, portable repository storage</title> 19.378 - 19.379 - <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case 19.380 - safe</emphasis>. It translates file names so that they can 19.381 - be safely stored on both case sensitive and case insensitive 19.382 - filesystems. This means that you can use normal file copying 19.383 - tools to transfer a Mercurial repository onto, for example, a 19.384 - USB thumb drive, and safely move that drive and repository 19.385 - back and forth between a Mac, a PC running Windows, and a 19.386 - Linux box.</para> 19.387 - 19.388 - </sect2> 19.389 - <sect2> 19.390 - <title>Detecting case conflicts</title> 19.391 - 19.392 - <para id="x_571">When operating in the working directory, Mercurial honours 19.393 - the naming policy of the filesystem where the working 19.394 - directory is located. If the filesystem is case preserving, 19.395 - but insensitive, Mercurial will treat names that differ only 19.396 - in case as the same.</para> 19.397 - 19.398 - <para id="x_572">An important aspect of this approach is that it is 19.399 - possible to commit a changeset on a case sensitive (typically 19.400 - Linux or Unix) filesystem that will cause trouble for users on 19.401 - case insensitive (usually Windows and MacOS) users. If a 19.402 - Linux user commits changes to two files, one named 19.403 - <filename>myfile.c</filename> and the other named 19.404 - <filename>MyFile.C</filename>, they will be stored correctly 19.405 - in the repository. And in the working directories of other 19.406 - Linux users, they will be correctly represented as separate 19.407 - files.</para> 19.408 - 19.409 - <para id="x_573">If a Windows or Mac user pulls this change, they will not 19.410 - initially have a problem, because Mercurial's repository 19.411 - storage mechanism is case safe. However, once they try to 19.412 - <command role="hg-cmd">hg update</command> the working 19.413 - directory to that changeset, or <command role="hg-cmd">hg 19.414 - merge</command> with that changeset, Mercurial will spot the 19.415 - conflict between the two file names that the filesystem would 19.416 - treat as the same, and forbid the update or merge from 19.417 - occurring.</para> 19.418 - </sect2> 19.419 - 19.420 - <sect2> 19.421 - <title>Fixing a case conflict</title> 19.422 - 19.423 - <para id="x_574">If you are using Windows or a Mac in a mixed environment 19.424 - where some of your collaborators are using Linux or Unix, and 19.425 - Mercurial reports a case folding conflict when you try to 19.426 - <command role="hg-cmd">hg update</command> or <command 19.427 - role="hg-cmd">hg merge</command>, the procedure to fix the 19.428 - problem is simple.</para> 19.429 - 19.430 - <para id="x_575">Just find a nearby Linux or Unix box, clone the problem 19.431 - repository onto it, and use Mercurial's <command 19.432 - role="hg-cmd">hg rename</command> command to change the 19.433 - names of any offending files or directories so that they will 19.434 - no longer cause case folding conflicts. Commit this change, 19.435 - <command role="hg-cmd">hg pull</command> or <command 19.436 - role="hg-cmd">hg push</command> it across to your Windows or 19.437 - MacOS system, and <command role="hg-cmd">hg update</command> 19.438 - to the revision with the non-conflicting names.</para> 19.439 - 19.440 - <para id="x_576">The changeset with case-conflicting names will remain in 19.441 - your project's history, and you still won't be able to 19.442 - <command role="hg-cmd">hg update</command> your working 19.443 - directory to that changeset on a Windows or MacOS system, but 19.444 - you can continue development unimpeded.</para> 19.445 - </sect2> 19.446 - </sect1> 19.447 -</chapter> 19.448 - 19.449 -<!-- 19.450 -local variables: 19.451 -sgml-parent-document: ("00book.xml" "book" "chapter") 19.452 -end: 19.453 --->
20.1 --- a/en/ch07-branch.xml Sat Apr 18 11:52:33 2009 +0800 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,532 +0,0 @@ 20.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 20.5 - 20.6 -<chapter id="chap:branch"> 20.7 - <?dbhtml filename="managing-releases-and-branchy-development.html"?> 20.8 - <title>Managing releases and branchy development</title> 20.9 - 20.10 - <para id="x_369">Mercurial provides several mechanisms for you to manage a 20.11 - project that is making progress on multiple fronts at once. To 20.12 - understand these mechanisms, let's first take a brief look at a 20.13 - fairly normal software project structure.</para> 20.14 - 20.15 - <para id="x_36a">Many software projects issue periodic <quote>major</quote> 20.16 - releases that contain substantial new features. In parallel, they 20.17 - may issue <quote>minor</quote> releases. These are usually 20.18 - identical to the major releases off which they're based, but with 20.19 - a few bugs fixed.</para> 20.20 - 20.21 - <para id="x_36b">In this chapter, we'll start by talking about how to keep 20.22 - records of project milestones such as releases. We'll then 20.23 - continue on to talk about the flow of work between different 20.24 - phases of a project, and how Mercurial can help you to isolate and 20.25 - manage this work.</para> 20.26 - 20.27 - <sect1> 20.28 - <title>Giving a persistent name to a revision</title> 20.29 - 20.30 - <para id="x_36c">Once you decide that you'd like to call a particular 20.31 - revision a <quote>release</quote>, it's a good idea to record 20.32 - the identity of that revision. This will let you reproduce that 20.33 - release at a later date, for whatever purpose you might need at 20.34 - the time (reproducing a bug, porting to a new platform, etc). 20.35 - &interaction.tag.init;</para> 20.36 - 20.37 - <para id="x_36d">Mercurial lets you give a permanent name to any revision 20.38 - using the <command role="hg-cmd">hg tag</command> command. Not 20.39 - surprisingly, these names are called <quote>tags</quote>.</para> 20.40 - 20.41 - &interaction.tag.tag; 20.42 - 20.43 - <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote> 20.44 - for a revision. Tags exist purely for your convenience, so that 20.45 - you have a handy permanent way to refer to a revision; Mercurial 20.46 - doesn't interpret the tag names you use in any way. Neither 20.47 - does Mercurial place any restrictions on the name of a tag, 20.48 - beyond a few that are necessary to ensure that a tag can be 20.49 - parsed unambiguously. A tag name cannot contain any of the 20.50 - following characters:</para> 20.51 - <itemizedlist> 20.52 - <listitem><para id="x_36f">Colon (ASCII 58, 20.53 - <quote><literal>:</literal></quote>)</para> 20.54 - </listitem> 20.55 - <listitem><para id="x_370">Carriage return (ASCII 13, 20.56 - <quote><literal>\r</literal></quote>)</para> 20.57 - </listitem> 20.58 - <listitem><para id="x_371">Newline (ASCII 10, 20.59 - <quote><literal>\n</literal></quote>)</para> 20.60 - </listitem></itemizedlist> 20.61 - 20.62 - <para id="x_372">You can use the <command role="hg-cmd">hg tags</command> 20.63 - command to display the tags present in your repository. In the 20.64 - output, each tagged revision is identified first by its name, 20.65 - then by revision number, and finally by the unique hash of the 20.66 - revision.</para> 20.67 - 20.68 - &interaction.tag.tags; 20.69 - 20.70 - <para id="x_373">Notice that <literal>tip</literal> is listed in the output 20.71 - of <command role="hg-cmd">hg tags</command>. The 20.72 - <literal>tip</literal> tag is a special <quote>floating</quote> 20.73 - tag, which always identifies the newest revision in the 20.74 - repository.</para> 20.75 - 20.76 - <para id="x_374">In the output of the <command role="hg-cmd">hg 20.77 - tags</command> command, tags are listed in reverse order, by 20.78 - revision number. This usually means that recent tags are listed 20.79 - before older tags. It also means that <literal>tip</literal> is 20.80 - always going to be the first tag listed in the output of 20.81 - <command role="hg-cmd">hg tags</command>.</para> 20.82 - 20.83 - <para id="x_375">When you run <command role="hg-cmd">hg log</command>, if it 20.84 - displays a revision that has tags associated with it, it will 20.85 - print those tags.</para> 20.86 - 20.87 - &interaction.tag.log; 20.88 - 20.89 - <para id="x_376">Any time you need to provide a revision ID to a Mercurial 20.90 - command, the command will accept a tag name in its place. 20.91 - Internally, Mercurial will translate your tag name into the 20.92 - corresponding revision ID, then use that.</para> 20.93 - 20.94 - &interaction.tag.log.v1.0; 20.95 - 20.96 - <para id="x_377">There's no limit on the number of tags you can have in a 20.97 - repository, or on the number of tags that a single revision can 20.98 - have. As a practical matter, it's not a great idea to have 20.99 - <quote>too many</quote> (a number which will vary from project 20.100 - to project), simply because tags are supposed to help you to 20.101 - find revisions. If you have lots of tags, the ease of using 20.102 - them to identify revisions diminishes rapidly.</para> 20.103 - 20.104 - <para id="x_378">For example, if your project has milestones as frequent as 20.105 - every few days, it's perfectly reasonable to tag each one of 20.106 - those. But if you have a continuous build system that makes 20.107 - sure every revision can be built cleanly, you'd be introducing a 20.108 - lot of noise if you were to tag every clean build. Instead, you 20.109 - could tag failed builds (on the assumption that they're rare!), 20.110 - or simply not use tags to track buildability.</para> 20.111 - 20.112 - <para id="x_379">If you want to remove a tag that you no longer want, use 20.113 - <command role="hg-cmd">hg tag --remove</command>.</para> 20.114 - 20.115 - &interaction.tag.remove; 20.116 - 20.117 - <para id="x_37a">You can also modify a tag at any time, so that it identifies 20.118 - a different revision, by simply issuing a new <command 20.119 - role="hg-cmd">hg tag</command> command. You'll have to use the 20.120 - <option role="hg-opt-tag">-f</option> option to tell Mercurial 20.121 - that you <emphasis>really</emphasis> want to update the 20.122 - tag.</para> 20.123 - 20.124 - &interaction.tag.replace; 20.125 - 20.126 - <para id="x_37b">There will still be a permanent record of the previous 20.127 - identity of the tag, but Mercurial will no longer use it. 20.128 - There's thus no penalty to tagging the wrong revision; all you 20.129 - have to do is turn around and tag the correct revision once you 20.130 - discover your error.</para> 20.131 - 20.132 - <para id="x_37c">Mercurial stores tags in a normal revision-controlled file 20.133 - in your repository. If you've created any tags, you'll find 20.134 - them in a file in the root of your repository named <filename 20.135 - role="special">.hgtags</filename>. When you run the <command 20.136 - role="hg-cmd">hg tag</command> command, Mercurial modifies 20.137 - this file, then automatically commits the change to it. This 20.138 - means that every time you run <command role="hg-cmd">hg 20.139 - tag</command>, you'll see a corresponding changeset in the 20.140 - output of <command role="hg-cmd">hg log</command>.</para> 20.141 - 20.142 - &interaction.tag.tip; 20.143 - 20.144 - <sect2> 20.145 - <title>Handling tag conflicts during a merge</title> 20.146 - 20.147 - <para id="x_37d">You won't often need to care about the <filename 20.148 - role="special">.hgtags</filename> file, but it sometimes 20.149 - makes its presence known during a merge. The format of the 20.150 - file is simple: it consists of a series of lines. Each line 20.151 - starts with a changeset hash, followed by a space, followed by 20.152 - the name of a tag.</para> 20.153 - 20.154 - <para id="x_37e">If you're resolving a conflict in the <filename 20.155 - role="special">.hgtags</filename> file during a merge, 20.156 - there's one twist to modifying the <filename 20.157 - role="special">.hgtags</filename> file: when Mercurial is 20.158 - parsing the tags in a repository, it 20.159 - <emphasis>never</emphasis> reads the working copy of the 20.160 - <filename role="special">.hgtags</filename> file. Instead, it 20.161 - reads the <emphasis>most recently committed</emphasis> 20.162 - revision of the file.</para> 20.163 - 20.164 - <para id="x_37f">An unfortunate consequence of this design is that you 20.165 - can't actually verify that your merged <filename 20.166 - role="special">.hgtags</filename> file is correct until 20.167 - <emphasis>after</emphasis> you've committed a change. So if 20.168 - you find yourself resolving a conflict on <filename 20.169 - role="special">.hgtags</filename> during a merge, be sure to 20.170 - run <command role="hg-cmd">hg tags</command> after you commit. 20.171 - If it finds an error in the <filename 20.172 - role="special">.hgtags</filename> file, it will report the 20.173 - location of the error, which you can then fix and commit. You 20.174 - should then run <command role="hg-cmd">hg tags</command> 20.175 - again, just to be sure that your fix is correct.</para> 20.176 - </sect2> 20.177 - 20.178 - <sect2> 20.179 - <title>Tags and cloning</title> 20.180 - 20.181 - <para id="x_380">You may have noticed that the <command role="hg-cmd">hg 20.182 - clone</command> command has a <option 20.183 - role="hg-opt-clone">-r</option> option that lets you clone 20.184 - an exact copy of the repository as of a particular changeset. 20.185 - The new clone will not contain any project history that comes 20.186 - after the revision you specified. This has an interaction 20.187 - with tags that can surprise the unwary.</para> 20.188 - 20.189 - <para id="x_381">Recall that a tag is stored as a revision to the <filename 20.190 - role="special">.hgtags</filename> file, so that when you 20.191 - create a tag, the changeset in which it's recorded necessarily 20.192 - refers to an older changeset. When you run <command 20.193 - role="hg-cmd">hg clone -r foo</command> to clone a 20.194 - repository as of tag <literal>foo</literal>, the new clone 20.195 - <emphasis>will not contain the history that created the 20.196 - tag</emphasis> that you used to clone the repository. The 20.197 - result is that you'll get exactly the right subset of the 20.198 - project's history in the new repository, but 20.199 - <emphasis>not</emphasis> the tag you might have 20.200 - expected.</para> 20.201 - </sect2> 20.202 - 20.203 - <sect2> 20.204 - <title>When permanent tags are too much</title> 20.205 - 20.206 - <para id="x_382">Since Mercurial's tags are revision controlled and carried 20.207 - around with a project's history, everyone you work with will 20.208 - see the tags you create. But giving names to revisions has 20.209 - uses beyond simply noting that revision 20.210 - <literal>4237e45506ee</literal> is really 20.211 - <literal>v2.0.2</literal>. If you're trying to track down a 20.212 - subtle bug, you might want a tag to remind you of something 20.213 - like <quote>Anne saw the symptoms with this 20.214 - revision</quote>.</para> 20.215 - 20.216 - <para id="x_383">For cases like this, what you might want to use are 20.217 - <emphasis>local</emphasis> tags. You can create a local tag 20.218 - with the <option role="hg-opt-tag">-l</option> option to the 20.219 - <command role="hg-cmd">hg tag</command> command. This will 20.220 - store the tag in a file called <filename 20.221 - role="special">.hg/localtags</filename>. Unlike <filename 20.222 - role="special">.hgtags</filename>, <filename 20.223 - role="special">.hg/localtags</filename> is not revision 20.224 - controlled. Any tags you create using <option 20.225 - role="hg-opt-tag">-l</option> remain strictly local to the 20.226 - repository you're currently working in.</para> 20.227 - </sect2> 20.228 - </sect1> 20.229 - 20.230 - <sect1> 20.231 - <title>The flow of changes&emdash;big picture vs. little</title> 20.232 - 20.233 - <para id="x_384">To return to the outline I sketched at the beginning of a 20.234 - chapter, let's think about a project that has multiple 20.235 - concurrent pieces of work under development at once.</para> 20.236 - 20.237 - <para id="x_385">There might be a push for a new <quote>main</quote> release; 20.238 - a new minor bugfix release to the last main release; and an 20.239 - unexpected <quote>hot fix</quote> to an old release that is now 20.240 - in maintenance mode.</para> 20.241 - 20.242 - <para id="x_386">The usual way people refer to these different concurrent 20.243 - directions of development is as <quote>branches</quote>. 20.244 - However, we've already seen numerous times that Mercurial treats 20.245 - <emphasis>all of history</emphasis> as a series of branches and 20.246 - merges. Really, what we have here is two ideas that are 20.247 - peripherally related, but which happen to share a name.</para> 20.248 - <itemizedlist> 20.249 - <listitem><para id="x_387"><quote>Big picture</quote> branches represent 20.250 - the sweep of a project's evolution; people give them names, 20.251 - and talk about them in conversation.</para> 20.252 - </listitem> 20.253 - <listitem><para id="x_388"><quote>Little picture</quote> branches are 20.254 - artefacts of the day-to-day activity of developing and 20.255 - merging changes. They expose the narrative of how the code 20.256 - was developed.</para> 20.257 - </listitem></itemizedlist> 20.258 - </sect1> 20.259 - 20.260 - <sect1> 20.261 - <title>Managing big-picture branches in repositories</title> 20.262 - 20.263 - <para id="x_389">The easiest way to isolate a <quote>big picture</quote> 20.264 - branch in Mercurial is in a dedicated repository. If you have 20.265 - an existing shared repository&emdash;let's call it 20.266 - <literal>myproject</literal>&emdash;that reaches a 20.267 - <quote>1.0</quote> milestone, you can start to prepare for 20.268 - future maintenance releases on top of version 1.0 by tagging the 20.269 - revision from which you prepared the 1.0 release.</para> 20.270 - 20.271 - &interaction.branch-repo.tag; 20.272 - 20.273 - <para id="x_38a">You can then clone a new shared 20.274 - <literal>myproject-1.0.1</literal> repository as of that 20.275 - tag.</para> 20.276 - 20.277 - &interaction.branch-repo.clone; 20.278 - 20.279 - <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought 20.280 - to go into an upcoming 1.0.1 minor release, they clone the 20.281 - <literal>myproject-1.0.1</literal> repository, make their 20.282 - changes, and push them back.</para> 20.283 - 20.284 - &interaction.branch-repo.bugfix; 20.285 - 20.286 - <para id="x_38c">Meanwhile, development for 20.287 - the next major release can continue, isolated and unabated, in 20.288 - the <literal>myproject</literal> repository.</para> 20.289 - 20.290 - &interaction.branch-repo.new; 20.291 - </sect1> 20.292 - 20.293 - <sect1> 20.294 - <title>Don't repeat yourself: merging across branches</title> 20.295 - 20.296 - <para id="x_38d">In many cases, if you have a bug to fix on a maintenance 20.297 - branch, the chances are good that the bug exists on your 20.298 - project's main branch (and possibly other maintenance branches, 20.299 - too). It's a rare developer who wants to fix the same bug 20.300 - multiple times, so let's look at a few ways that Mercurial can 20.301 - help you to manage these bugfixes without duplicating your 20.302 - work.</para> 20.303 - 20.304 - <para id="x_38e">In the simplest instance, all you need to do is pull changes 20.305 - from your maintenance branch into your local clone of the target 20.306 - branch.</para> 20.307 - 20.308 - &interaction.branch-repo.pull; 20.309 - 20.310 - <para id="x_38f">You'll then need to merge the heads of the two branches, and 20.311 - push back to the main branch.</para> 20.312 - 20.313 - &interaction.branch-repo.merge; 20.314 - </sect1> 20.315 - 20.316 - <sect1> 20.317 - <title>Naming branches within one repository</title> 20.318 - 20.319 - <para id="x_390">In most instances, isolating branches in repositories is the 20.320 - right approach. Its simplicity makes it easy to understand; and 20.321 - so it's hard to make mistakes. There's a one-to-one 20.322 - relationship between branches you're working in and directories 20.323 - on your system. This lets you use normal (non-Mercurial-aware) 20.324 - tools to work on files within a branch/repository.</para> 20.325 - 20.326 - <para id="x_391">If you're more in the <quote>power user</quote> category 20.327 - (<emphasis>and</emphasis> your collaborators are too), there is 20.328 - an alternative way of handling branches that you can consider. 20.329 - I've already mentioned the human-level distinction between 20.330 - <quote>small picture</quote> and <quote>big picture</quote> 20.331 - branches. While Mercurial works with multiple <quote>small 20.332 - picture</quote> branches in a repository all the time (for 20.333 - example after you pull changes in, but before you merge them), 20.334 - it can <emphasis>also</emphasis> work with multiple <quote>big 20.335 - picture</quote> branches.</para> 20.336 - 20.337 - <para id="x_392">The key to working this way is that Mercurial lets you 20.338 - assign a persistent <emphasis>name</emphasis> to a branch. 20.339 - There always exists a branch named <literal>default</literal>. 20.340 - Even before you start naming branches yourself, you can find 20.341 - traces of the <literal>default</literal> branch if you look for 20.342 - them.</para> 20.343 - 20.344 - <para id="x_393">As an example, when you run the <command role="hg-cmd">hg 20.345 - commit</command> command, and it pops up your editor so that 20.346 - you can enter a commit message, look for a line that contains 20.347 - the text <quote><literal>HG: branch default</literal></quote> at 20.348 - the bottom. This is telling you that your commit will occur on 20.349 - the branch named <literal>default</literal>.</para> 20.350 - 20.351 - <para id="x_394">To start working with named branches, use the <command 20.352 - role="hg-cmd">hg branches</command> command. This command 20.353 - lists the named branches already present in your repository, 20.354 - telling you which changeset is the tip of each.</para> 20.355 - 20.356 - &interaction.branch-named.branches; 20.357 - 20.358 - <para id="x_395">Since you haven't created any named branches yet, the only 20.359 - one that exists is <literal>default</literal>.</para> 20.360 - 20.361 - <para id="x_396">To find out what the <quote>current</quote> branch is, run 20.362 - the <command role="hg-cmd">hg branch</command> command, giving 20.363 - it no arguments. This tells you what branch the parent of the 20.364 - current changeset is on.</para> 20.365 - 20.366 - &interaction.branch-named.branch; 20.367 - 20.368 - <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg 20.369 - branch</command> command again. This time, give it one 20.370 - argument: the name of the branch you want to create.</para> 20.371 - 20.372 - &interaction.branch-named.create; 20.373 - 20.374 - <para id="x_398">After you've created a branch, you might wonder what effect 20.375 - the <command role="hg-cmd">hg branch</command> command has had. 20.376 - What do the <command role="hg-cmd">hg status</command> and 20.377 - <command role="hg-cmd">hg tip</command> commands report?</para> 20.378 - 20.379 - &interaction.branch-named.status; 20.380 - 20.381 - <para id="x_399">Nothing has changed in the 20.382 - working directory, and there's been no new history created. As 20.383 - this suggests, running the <command role="hg-cmd">hg 20.384 - branch</command> command has no permanent effect; it only 20.385 - tells Mercurial what branch name to use the 20.386 - <emphasis>next</emphasis> time you commit a changeset.</para> 20.387 - 20.388 - <para id="x_39a">When you commit a change, Mercurial records the name of the 20.389 - branch on which you committed. Once you've switched from the 20.390 - <literal>default</literal> branch to another and committed, 20.391 - you'll see the name of the new branch show up in the output of 20.392 - <command role="hg-cmd">hg log</command>, <command 20.393 - role="hg-cmd">hg tip</command>, and other commands that 20.394 - display the same kind of output.</para> 20.395 - 20.396 - &interaction.branch-named.commit; 20.397 - 20.398 - <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands 20.399 - will print the branch name of every changeset that's not on the 20.400 - <literal>default</literal> branch. As a result, if you never 20.401 - use named branches, you'll never see this information.</para> 20.402 - 20.403 - <para id="x_39c">Once you've named a branch and committed a change with that 20.404 - name, every subsequent commit that descends from that change 20.405 - will inherit the same branch name. You can change the name of a 20.406 - branch at any time, using the <command role="hg-cmd">hg 20.407 - branch</command> command.</para> 20.408 - 20.409 - &interaction.branch-named.rebranch; 20.410 - 20.411 - <para id="x_39d">In practice, this is something you won't do very often, as 20.412 - branch names tend to have fairly long lifetimes. (This isn't a 20.413 - rule, just an observation.)</para> 20.414 - </sect1> 20.415 - 20.416 - <sect1> 20.417 - <title>Dealing with multiple named branches in a 20.418 - repository</title> 20.419 - 20.420 - <para id="x_39e">If you have more than one named branch in a repository, 20.421 - Mercurial will remember the branch that your working directory 20.422 - on when you start a command like <command role="hg-cmd">hg 20.423 - update</command> or <command role="hg-cmd">hg pull 20.424 - -u</command>. It will update the working directory to the tip 20.425 - of this branch, no matter what the <quote>repo-wide</quote> tip 20.426 - is. To update to a revision that's on a different named branch, 20.427 - you may need to use the <option role="hg-opt-update">-C</option> 20.428 - option to <command role="hg-cmd">hg update</command>.</para> 20.429 - 20.430 - <para id="x_39f">This behavior is a little subtle, so let's see it in 20.431 - action. First, let's remind ourselves what branch we're 20.432 - currently on, and what branches are in our repository.</para> 20.433 - 20.434 - &interaction.branch-named.parents; 20.435 - 20.436 - <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also 20.437 - exists an older <command role="hg-cmd">hg foo</command> 20.438 - branch.</para> 20.439 - 20.440 - <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and 20.441 - forth between the tips of the <literal>foo</literal> and 20.442 - <literal>bar</literal> branches without needing to use the 20.443 - <option role="hg-opt-update">-C</option> option, because this 20.444 - only involves going backwards and forwards linearly through our 20.445 - change history.</para> 20.446 - 20.447 - &interaction.branch-named.update-switchy; 20.448 - 20.449 - <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then 20.450 - run <command role="hg-cmd">hg update</command>, it will keep us 20.451 - on <literal>foo</literal>, not move us to the tip of 20.452 - <literal>bar</literal>.</para> 20.453 - 20.454 - &interaction.branch-named.update-nothing; 20.455 - 20.456 - <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch 20.457 - introduces a new head.</para> 20.458 - 20.459 - &interaction.branch-named.foo-commit; 20.460 - </sect1> 20.461 - 20.462 - <sect1> 20.463 - <title>Branch names and merging</title> 20.464 - 20.465 - <para id="x_3a4">As you've probably noticed, merges in Mercurial are not 20.466 - symmetrical. Let's say our repository has two heads, 17 and 23. 20.467 - If I <command role="hg-cmd">hg update</command> to 17 and then 20.468 - <command role="hg-cmd">hg merge</command> with 23, Mercurial 20.469 - records 17 as the first parent of the merge, and 23 as the 20.470 - second. Whereas if I <command role="hg-cmd">hg update</command> 20.471 - to 23 and then <command role="hg-cmd">hg merge</command> with 20.472 - 17, it records 23 as the first parent, and 17 as the 20.473 - second.</para> 20.474 - 20.475 - <para id="x_3a5">This affects Mercurial's choice of branch name when you 20.476 - merge. After a merge, Mercurial will retain the branch name of 20.477 - the first parent when you commit the result of the merge. If 20.478 - your first parent's branch name is <literal>foo</literal>, and 20.479 - you merge with <literal>bar</literal>, the branch name will 20.480 - still be <literal>foo</literal> after you merge.</para> 20.481 - 20.482 - <para id="x_3a6">It's not unusual for a repository to contain multiple heads, 20.483 - each with the same branch name. Let's say I'm working on the 20.484 - <literal>foo</literal> branch, and so are you. We commit 20.485 - different changes; I pull your changes; I now have two heads, 20.486 - each claiming to be on the <literal>foo</literal> branch. The 20.487 - result of a merge will be a single head on the 20.488 - <literal>foo</literal> branch, as you might hope.</para> 20.489 - 20.490 - <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and 20.491 - I merge work from the <literal>foo</literal> branch, the result 20.492 - will remain on the <literal>bar</literal> branch.</para> 20.493 - 20.494 - &interaction.branch-named.merge; 20.495 - 20.496 - <para id="x_3a8">To give a more concrete example, if I'm working on the 20.497 - <literal>bleeding-edge</literal> branch, and I want to bring in 20.498 - the latest fixes from the <literal>stable</literal> branch, 20.499 - Mercurial will choose the <quote>right</quote> 20.500 - (<literal>bleeding-edge</literal>) branch name when I pull and 20.501 - merge from <literal>stable</literal>.</para> 20.502 - </sect1> 20.503 - 20.504 - <sect1> 20.505 - <title>Branch naming is generally useful</title> 20.506 - 20.507 - <para id="x_3a9">You shouldn't think of named branches as applicable only to 20.508 - situations where you have multiple long-lived branches 20.509 - cohabiting in a single repository. They're very useful even in 20.510 - the one-branch-per-repository case.</para> 20.511 - 20.512 - <para id="x_3aa">In the simplest case, giving a name to each branch gives you 20.513 - a permanent record of which branch a changeset originated on. 20.514 - This gives you more context when you're trying to follow the 20.515 - history of a long-lived branchy project.</para> 20.516 - 20.517 - <para id="x_3ab">If you're working with shared repositories, you can set up a 20.518 - <literal role="hook">pretxnchangegroup</literal> hook on each 20.519 - that will block incoming changes that have the 20.520 - <quote>wrong</quote> branch name. This provides a simple, but 20.521 - effective, defence against people accidentally pushing changes 20.522 - from a <quote>bleeding edge</quote> branch to a 20.523 - <quote>stable</quote> branch. Such a hook might look like this 20.524 - inside the shared repo's <filename role="special"> 20.525 - /.hgrc</filename>.</para> 20.526 - <programlisting>[hooks] 20.527 -pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting> 20.528 - </sect1> 20.529 -</chapter> 20.530 - 20.531 -<!-- 20.532 -local variables: 20.533 -sgml-parent-document: ("00book.xml" "book" "chapter") 20.534 -end: 20.535 --->
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/en/ch07-filenames.xml Thu May 21 14:16:17 2009 +0800 21.3 @@ -0,0 +1,451 @@ 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 + </sect1> 21.34 + 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 behaviors when you invoke them without providing any 21.40 + file names or patterns. What kind of behavior 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 behaviors 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 + </sect1> 21.77 + 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>, e.g. 21.92 + because you provided no names, or a directory, or a pattern (see 21.93 + below), it is safest to tell you what files it's operating on.</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 + </sect1> 21.101 + 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 + </sect3> 21.201 + </sect2> 21.202 + 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 + </sect2> 21.234 + </sect1> 21.235 + 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 + </sect1> 21.273 + 21.274 + <sect1> 21.275 + <title>Permanently ignoring unwanted files and directories</title> 21.276 + 21.277 + <para id="x_569">When you create a new repository, the chances are 21.278 + that over time it will grow to contain files that ought to 21.279 + <emphasis>not</emphasis> be managed by Mercurial, but which you 21.280 + don't want to see listed every time you run <command>hg 21.281 + status</command>. For instance, <quote>build products</quote> 21.282 + are files that are created as part of a build but which should 21.283 + not be managed by a revision control system. The most common 21.284 + build products are output files produced by software tools such 21.285 + as compilers. As another example, many text editors litter a 21.286 + directory with lock files, temporary working files, and backup 21.287 + files, which it also makes no sense to manage.</para> 21.288 + 21.289 + <para id="x_6b4">To have Mercurial permanently ignore such files, create a 21.290 + file named <filename>.hgignore</filename> in the root of your 21.291 + repository. You <emphasis>should</emphasis> <command>hg 21.292 + add</command> this file so that it gets tracked with the rest of 21.293 + your repository contents, since your collaborators will probably 21.294 + find it useful too.</para> 21.295 + 21.296 + <para id="x_6b5">By default, the <filename>.hgignore</filename> file should 21.297 + contain a list of regular expressions, one per line. Empty 21.298 + lines are skipped. Most people prefer to describe the files they 21.299 + want to ignore using the <quote>glob</quote> syntax that we 21.300 + described above, so a typical <filename>.hgignore</filename> 21.301 + file will start with this directive:</para> 21.302 + 21.303 + <programlisting>syntax: glob</programlisting> 21.304 + 21.305 + <para id="x_6b6">This tells Mercurial to interpret the lines that follow as 21.306 + glob patterns, not regular expressions.</para> 21.307 + 21.308 + <para id="x_6b7">Here is a typical-looking <filename>.hgignore</filename> 21.309 + file.</para> 21.310 + 21.311 + <programlisting>syntax: glob 21.312 +# This line is a comment, and will be skipped. 21.313 +# Empty lines are skipped too. 21.314 + 21.315 +# Backup files left behind by the Emacs editor. 21.316 +*~ 21.317 + 21.318 +# Lock files used by the Emacs editor. 21.319 +# Notice that the "#" character is quoted with a backslash. 21.320 +# This prevents it from being interpreted as starting a comment. 21.321 +.\#* 21.322 + 21.323 +# Temporary files used by the vim editor. 21.324 +.*.swp 21.325 + 21.326 +# A hidden file created by the Mac OS X Finder. 21.327 +.DS_Store 21.328 +</programlisting> 21.329 + </sect1> 21.330 + 21.331 + <sect1 id="sec:names:case"> 21.332 + <title>Case sensitivity</title> 21.333 + 21.334 + <para id="x_56a">If you're working in a mixed development environment that 21.335 + contains both Linux (or other Unix) systems and Macs or Windows 21.336 + systems, you should keep in the back of your mind the knowledge 21.337 + that they treat the case (<quote>N</quote> versus 21.338 + <quote>n</quote>) of file names in incompatible ways. This is 21.339 + not very likely to affect you, and it's easy to deal with if it 21.340 + does, but it could surprise you if you don't know about 21.341 + it.</para> 21.342 + 21.343 + <para id="x_56b">Operating systems and filesystems differ in the way they 21.344 + handle the <emphasis>case</emphasis> of characters in file and 21.345 + directory names. There are three common ways to handle case in 21.346 + names.</para> 21.347 + <itemizedlist> 21.348 + <listitem><para id="x_56c">Completely case insensitive. Uppercase and 21.349 + lowercase versions of a letter are treated as identical, 21.350 + both when creating a file and during subsequent accesses. 21.351 + This is common on older DOS-based systems.</para> 21.352 + </listitem> 21.353 + <listitem><para id="x_56d">Case preserving, but insensitive. When a file 21.354 + or directory is created, the case of its name is stored, and 21.355 + can be retrieved and displayed by the operating system. 21.356 + When an existing file is being looked up, its case is 21.357 + ignored. This is the standard arrangement on Windows and 21.358 + MacOS. The names <filename>foo</filename> and 21.359 + <filename>FoO</filename> identify the same file. This 21.360 + treatment of uppercase and lowercase letters as 21.361 + interchangeable is also referred to as <emphasis>case 21.362 + folding</emphasis>.</para> 21.363 + </listitem> 21.364 + <listitem><para id="x_56e">Case sensitive. The case of a name 21.365 + is significant at all times. The names 21.366 + <filename>foo</filename> and <filename>FoO</filename> 21.367 + identify different files. This is the way Linux and Unix 21.368 + systems normally work.</para> 21.369 + </listitem></itemizedlist> 21.370 + 21.371 + <para id="x_56f">On Unix-like systems, it is possible to have any or all of 21.372 + the above ways of handling case in action at once. For example, 21.373 + if you use a USB thumb drive formatted with a FAT32 filesystem 21.374 + on a Linux system, Linux will handle names on that filesystem in 21.375 + a case preserving, but insensitive, way.</para> 21.376 + 21.377 + <sect2> 21.378 + <title>Safe, portable repository storage</title> 21.379 + 21.380 + <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case 21.381 + safe</emphasis>. It translates file names so that they can 21.382 + be safely stored on both case sensitive and case insensitive 21.383 + filesystems. This means that you can use normal file copying 21.384 + tools to transfer a Mercurial repository onto, for example, a 21.385 + USB thumb drive, and safely move that drive and repository 21.386 + back and forth between a Mac, a PC running Windows, and a 21.387 + Linux box.</para> 21.388 + 21.389 + </sect2> 21.390 + <sect2> 21.391 + <title>Detecting case conflicts</title> 21.392 + 21.393 + <para id="x_571">When operating in the working directory, Mercurial honours 21.394 + the naming policy of the filesystem where the working 21.395 + directory is located. If the filesystem is case preserving, 21.396 + but insensitive, Mercurial will treat names that differ only 21.397 + in case as the same.</para> 21.398 + 21.399 + <para id="x_572">An important aspect of this approach is that it is 21.400 + possible to commit a changeset on a case sensitive (typically 21.401 + Linux or Unix) filesystem that will cause trouble for users on 21.402 + case insensitive (usually Windows and MacOS) users. If a 21.403 + Linux user commits changes to two files, one named 21.404 + <filename>myfile.c</filename> and the other named 21.405 + <filename>MyFile.C</filename>, they will be stored correctly 21.406 + in the repository. And in the working directories of other 21.407 + Linux users, they will be correctly represented as separate 21.408 + files.</para> 21.409 + 21.410 + <para id="x_573">If a Windows or Mac user pulls this change, they will not 21.411 + initially have a problem, because Mercurial's repository 21.412 + storage mechanism is case safe. However, once they try to 21.413 + <command role="hg-cmd">hg update</command> the working 21.414 + directory to that changeset, or <command role="hg-cmd">hg 21.415 + merge</command> with that changeset, Mercurial will spot the 21.416 + conflict between the two file names that the filesystem would 21.417 + treat as the same, and forbid the update or merge from 21.418 + occurring.</para> 21.419 + </sect2> 21.420 + 21.421 + <sect2> 21.422 + <title>Fixing a case conflict</title> 21.423 + 21.424 + <para id="x_574">If you are using Windows or a Mac in a mixed environment 21.425 + where some of your collaborators are using Linux or Unix, and 21.426 + Mercurial reports a case folding conflict when you try to 21.427 + <command role="hg-cmd">hg update</command> or <command 21.428 + role="hg-cmd">hg merge</command>, the procedure to fix the 21.429 + problem is simple.</para> 21.430 + 21.431 + <para id="x_575">Just find a nearby Linux or Unix box, clone the problem 21.432 + repository onto it, and use Mercurial's <command 21.433 + role="hg-cmd">hg rename</command> command to change the 21.434 + names of any offending files or directories so that they will 21.435 + no longer cause case folding conflicts. Commit this change, 21.436 + <command role="hg-cmd">hg pull</command> or <command 21.437 + role="hg-cmd">hg push</command> it across to your Windows or 21.438 + MacOS system, and <command role="hg-cmd">hg update</command> 21.439 + to the revision with the non-conflicting names.</para> 21.440 + 21.441 + <para id="x_576">The changeset with case-conflicting names will remain in 21.442 + your project's history, and you still won't be able to 21.443 + <command role="hg-cmd">hg update</command> your working 21.444 + directory to that changeset on a Windows or MacOS system, but 21.445 + you can continue development unimpeded.</para> 21.446 + </sect2> 21.447 + </sect1> 21.448 +</chapter> 21.449 + 21.450 +<!-- 21.451 +local variables: 21.452 +sgml-parent-document: ("00book.xml" "book" "chapter") 21.453 +end: 21.454 +-->
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/en/ch08-branch.xml Thu May 21 14:16:17 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 in the root of your repository 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 + </sect2> 22.177 + 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 22.190 + the <filename role="special">.hgtags</filename> file. When you 22.191 + create a tag, the changeset in which its recorded refers to an 22.192 + older changeset. When you run <command role="hg-cmd">hg clone 22.193 + -r foo</command> to clone a repository as of tag 22.194 + <literal>foo</literal>, the new clone <emphasis>will not 22.195 + contain any revision newer than the one the tag refers to, 22.196 + including the revision where the tag was created</emphasis>. 22.197 + The 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 + </sect2> 22.202 + 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 + </sect2> 22.228 + </sect1> 22.229 + 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 22.234 + beginning of the chapter, let's think about a project that has 22.235 + multiple concurrent pieces of work under development at 22.236 + once.</para> 22.237 + 22.238 + <para id="x_385">There might be a push for a new <quote>main</quote> release; 22.239 + a new minor bugfix release to the last main release; and an 22.240 + unexpected <quote>hot fix</quote> to an old release that is now 22.241 + in maintenance mode.</para> 22.242 + 22.243 + <para id="x_386">The usual way people refer to these different concurrent 22.244 + directions of development is as <quote>branches</quote>. 22.245 + However, we've already seen numerous times that Mercurial treats 22.246 + <emphasis>all of history</emphasis> as a series of branches and 22.247 + merges. Really, what we have here is two ideas that are 22.248 + peripherally related, but which happen to share a name.</para> 22.249 + <itemizedlist> 22.250 + <listitem><para id="x_387"><quote>Big picture</quote> branches represent 22.251 + the sweep of a project's evolution; people give them names, 22.252 + and talk about them in conversation.</para> 22.253 + </listitem> 22.254 + <listitem><para id="x_388"><quote>Little picture</quote> branches are 22.255 + artefacts of the day-to-day activity of developing and 22.256 + merging changes. They expose the narrative of how the code 22.257 + was developed.</para> 22.258 + </listitem></itemizedlist> 22.259 + </sect1> 22.260 + 22.261 + <sect1> 22.262 + <title>Managing big-picture branches in repositories</title> 22.263 + 22.264 + <para id="x_389">The easiest way to isolate a <quote>big picture</quote> 22.265 + branch in Mercurial is in a dedicated repository. If you have 22.266 + an existing shared repository&emdash;let's call it 22.267 + <literal>myproject</literal>&emdash;that reaches a 22.268 + <quote>1.0</quote> milestone, you can start to prepare for 22.269 + future maintenance releases on top of version 1.0 by tagging the 22.270 + revision from which you prepared the 1.0 release.</para> 22.271 + 22.272 + &interaction.branch-repo.tag; 22.273 + 22.274 + <para id="x_38a">You can then clone a new shared 22.275 + <literal>myproject-1.0.1</literal> repository as of that 22.276 + tag.</para> 22.277 + 22.278 + &interaction.branch-repo.clone; 22.279 + 22.280 + <para id="x_38b">Afterwards, if someone needs to work on a bug fix that ought 22.281 + to go into an upcoming 1.0.1 minor release, they clone the 22.282 + <literal>myproject-1.0.1</literal> repository, make their 22.283 + changes, and push them back.</para> 22.284 + 22.285 + &interaction.branch-repo.bugfix; 22.286 + 22.287 + <para id="x_38c">Meanwhile, development for 22.288 + the next major release can continue, isolated and unabated, in 22.289 + the <literal>myproject</literal> repository.</para> 22.290 + 22.291 + &interaction.branch-repo.new; 22.292 + </sect1> 22.293 + 22.294 + <sect1> 22.295 + <title>Don't repeat yourself: merging across branches</title> 22.296 + 22.297 + <para id="x_38d">In many cases, if you have a bug to fix on a maintenance 22.298 + branch, the chances are good that the bug exists on your 22.299 + project's main branch (and possibly other maintenance branches, 22.300 + too). It's a rare developer who wants to fix the same bug 22.301 + multiple times, so let's look at a few ways that Mercurial can 22.302 + help you to manage these bugfixes without duplicating your 22.303 + work.</para> 22.304 + 22.305 + <para id="x_38e">In the simplest instance, all you need to do is pull changes 22.306 + from your maintenance branch into your local clone of the target 22.307 + branch.</para> 22.308 + 22.309 + &interaction.branch-repo.pull; 22.310 + 22.311 + <para id="x_38f">You'll then need to merge the heads of the two branches, and 22.312 + push back to the main branch.</para> 22.313 + 22.314 + &interaction.branch-repo.merge; 22.315 + </sect1> 22.316 + 22.317 + <sect1> 22.318 + <title>Naming branches within one repository</title> 22.319 + 22.320 + <para id="x_390">In most instances, isolating branches in repositories is the 22.321 + right approach. Its simplicity makes it easy to understand; and 22.322 + so it's hard to make mistakes. There's a one-to-one 22.323 + relationship between branches you're working in and directories 22.324 + on your system. This lets you use normal (non-Mercurial-aware) 22.325 + tools to work on files within a branch/repository.</para> 22.326 + 22.327 + <para id="x_391">If you're more in the <quote>power user</quote> category 22.328 + (<emphasis>and</emphasis> your collaborators are too), there is 22.329 + an alternative way of handling branches that you can consider. 22.330 + I've already mentioned the human-level distinction between 22.331 + <quote>small picture</quote> and <quote>big picture</quote> 22.332 + branches. While Mercurial works with multiple <quote>small 22.333 + picture</quote> branches in a repository all the time (for 22.334 + example after you pull changes in, but before you merge them), 22.335 + it can <emphasis>also</emphasis> work with multiple <quote>big 22.336 + picture</quote> branches.</para> 22.337 + 22.338 + <para id="x_392">The key to working this way is that Mercurial lets you 22.339 + assign a persistent <emphasis>name</emphasis> to a branch. 22.340 + There always exists a branch named <literal>default</literal>. 22.341 + Even before you start naming branches yourself, you can find 22.342 + traces of the <literal>default</literal> branch if you look for 22.343 + them.</para> 22.344 + 22.345 + <para id="x_393">As an example, when you run the <command role="hg-cmd">hg 22.346 + commit</command> command, and it pops up your editor so that 22.347 + you can enter a commit message, look for a line that contains 22.348 + the text <quote><literal>HG: branch default</literal></quote> at 22.349 + the bottom. This is telling you that your commit will occur on 22.350 + the branch named <literal>default</literal>.</para> 22.351 + 22.352 + <para id="x_394">To start working with named branches, use the <command 22.353 + role="hg-cmd">hg branches</command> command. This command 22.354 + lists the named branches already present in your repository, 22.355 + telling you which changeset is the tip of each.</para> 22.356 + 22.357 + &interaction.branch-named.branches; 22.358 + 22.359 + <para id="x_395">Since you haven't created any named branches yet, the only 22.360 + one that exists is <literal>default</literal>.</para> 22.361 + 22.362 + <para id="x_396">To find out what the <quote>current</quote> branch is, run 22.363 + the <command role="hg-cmd">hg branch</command> command, giving 22.364 + it no arguments. This tells you what branch the parent of the 22.365 + current changeset is on.</para> 22.366 + 22.367 + &interaction.branch-named.branch; 22.368 + 22.369 + <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg 22.370 + branch</command> command again. This time, give it one 22.371 + argument: the name of the branch you want to create.</para> 22.372 + 22.373 + &interaction.branch-named.create; 22.374 + 22.375 + <para id="x_398">After you've created a branch, you might wonder what effect 22.376 + the <command role="hg-cmd">hg branch</command> command has had. 22.377 + What do the <command role="hg-cmd">hg status</command> and 22.378 + <command role="hg-cmd">hg tip</command> commands report?</para> 22.379 + 22.380 + &interaction.branch-named.status; 22.381 + 22.382 + <para id="x_399">Nothing has changed in the 22.383 + working directory, and there's been no new history created. As 22.384 + this suggests, running the <command role="hg-cmd">hg 22.385 + branch</command> command has no permanent effect; it only 22.386 + tells Mercurial what branch name to use the 22.387 + <emphasis>next</emphasis> time you commit a changeset.</para> 22.388 + 22.389 + <para id="x_39a">When you commit a change, Mercurial records the name of the 22.390 + branch on which you committed. Once you've switched from the 22.391 + <literal>default</literal> branch to another and committed, 22.392 + you'll see the name of the new branch show up in the output of 22.393 + <command role="hg-cmd">hg log</command>, <command 22.394 + role="hg-cmd">hg tip</command>, and other commands that 22.395 + display the same kind of output.</para> 22.396 + 22.397 + &interaction.branch-named.commit; 22.398 + 22.399 + <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands 22.400 + will print the branch name of every changeset that's not on the 22.401 + <literal>default</literal> branch. As a result, if you never 22.402 + use named branches, you'll never see this information.</para> 22.403 + 22.404 + <para id="x_39c">Once you've named a branch and committed a change with that 22.405 + name, every subsequent commit that descends from that change 22.406 + will inherit the same branch name. You can change the name of a 22.407 + branch at any time, using the <command role="hg-cmd">hg 22.408 + branch</command> command.</para> 22.409 + 22.410 + &interaction.branch-named.rebranch; 22.411 + 22.412 + <para id="x_39d">In practice, this is something you won't do very often, as 22.413 + branch names tend to have fairly long lifetimes. (This isn't a 22.414 + rule, just an observation.)</para> 22.415 + </sect1> 22.416 + 22.417 + <sect1> 22.418 + <title>Dealing with multiple named branches in a 22.419 + repository</title> 22.420 + 22.421 + <para id="x_39e">If you have more than one named branch in a repository, 22.422 + Mercurial will remember the branch that your working directory 22.423 + is on when you start a command like <command role="hg-cmd">hg 22.424 + update</command> or <command role="hg-cmd">hg pull 22.425 + -u</command>. It will update the working directory to the tip 22.426 + of this branch, no matter what the <quote>repo-wide</quote> tip 22.427 + is. To update to a revision that's on a different named branch, 22.428 + you may need to use the <option role="hg-opt-update">-C</option> 22.429 + option to <command role="hg-cmd">hg update</command>.</para> 22.430 + 22.431 + <para id="x_39f">This behavior is a little subtle, so let's see it in 22.432 + action. First, let's remind ourselves what branch we're 22.433 + currently on, and what branches are in our repository.</para> 22.434 + 22.435 + &interaction.branch-named.parents; 22.436 + 22.437 + <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also 22.438 + exists an older <command role="hg-cmd">hg foo</command> 22.439 + branch.</para> 22.440 + 22.441 + <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and 22.442 + forth between the tips of the <literal>foo</literal> and 22.443 + <literal>bar</literal> branches without needing to use the 22.444 + <option role="hg-opt-update">-C</option> option, because this 22.445 + only involves going backwards and forwards linearly through our 22.446 + change history.</para> 22.447 + 22.448 + &interaction.branch-named.update-switchy; 22.449 + 22.450 + <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then 22.451 + run <command role="hg-cmd">hg update</command>, it will keep us 22.452 + on <literal>foo</literal>, not move us to the tip of 22.453 + <literal>bar</literal>.</para> 22.454 + 22.455 + &interaction.branch-named.update-nothing; 22.456 + 22.457 + <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch 22.458 + introduces a new head.</para> 22.459 + 22.460 + &interaction.branch-named.foo-commit; 22.461 + </sect1> 22.462 + 22.463 + <sect1> 22.464 + <title>Branch names and merging</title> 22.465 + 22.466 + <para id="x_3a4">As you've probably noticed, merges in Mercurial are not 22.467 + symmetrical. Let's say our repository has two heads, 17 and 23. 22.468 + If I <command role="hg-cmd">hg update</command> to 17 and then 22.469 + <command role="hg-cmd">hg merge</command> with 23, Mercurial 22.470 + records 17 as the first parent of the merge, and 23 as the 22.471 + second. Whereas if I <command role="hg-cmd">hg update</command> 22.472 + to 23 and then <command role="hg-cmd">hg merge</command> with 22.473 + 17, it records 23 as the first parent, and 17 as the 22.474 + second.</para> 22.475 + 22.476 + <para id="x_3a5">This affects Mercurial's choice of branch name when you 22.477 + merge. After a merge, Mercurial will retain the branch name of 22.478 + the first parent when you commit the result of the merge. If 22.479 + your first parent's branch name is <literal>foo</literal>, and 22.480 + you merge with <literal>bar</literal>, the branch name will 22.481 + still be <literal>foo</literal> after you merge.</para> 22.482 + 22.483 + <para id="x_3a6">It's not unusual for a repository to contain multiple heads, 22.484 + each with the same branch name. Let's say I'm working on the 22.485 + <literal>foo</literal> branch, and so are you. We commit 22.486 + different changes; I pull your changes; I now have two heads, 22.487 + each claiming to be on the <literal>foo</literal> branch. The 22.488 + result of a merge will be a single head on the 22.489 + <literal>foo</literal> branch, as you might hope.</para> 22.490 + 22.491 + <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and 22.492 + I merge work from the <literal>foo</literal> branch, the result 22.493 + will remain on the <literal>bar</literal> branch.</para> 22.494 + 22.495 + &interaction.branch-named.merge; 22.496 + 22.497 + <para id="x_3a8">To give a more concrete example, if I'm working on the 22.498 + <literal>bleeding-edge</literal> branch, and I want to bring in 22.499 + the latest fixes from the <literal>stable</literal> branch, 22.500 + Mercurial will choose the <quote>right</quote> 22.501 + (<literal>bleeding-edge</literal>) branch name when I pull and 22.502 + merge from <literal>stable</literal>.</para> 22.503 + </sect1> 22.504 + 22.505 + <sect1> 22.506 + <title>Branch naming is generally useful</title> 22.507 + 22.508 + <para id="x_3a9">You shouldn't think of named branches as applicable only to 22.509 + situations where you have multiple long-lived branches 22.510 + cohabiting in a single repository. They're very useful even in 22.511 + the one-branch-per-repository case.</para> 22.512 + 22.513 + <para id="x_3aa">In the simplest case, giving a name to each branch gives you 22.514 + a permanent record of which branch a changeset originated on. 22.515 + This gives you more context when you're trying to follow the 22.516 + history of a long-lived branchy project.</para> 22.517 + 22.518 + <para id="x_3ab">If you're working with shared repositories, you can set up a 22.519 + <literal role="hook">pretxnchangegroup</literal> hook on each 22.520 + that will block incoming changes that have the 22.521 + <quote>wrong</quote> branch name. This provides a simple, but 22.522 + effective, defence against people accidentally pushing changes 22.523 + from a <quote>bleeding edge</quote> branch to a 22.524 + <quote>stable</quote> branch. Such a hook might look like this 22.525 + inside the shared repo's <filename role="special"> 22.526 + /.hgrc</filename>.</para> 22.527 + <programlisting>[hooks] 22.528 +pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting> 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/ch08-undo.xml Sat Apr 18 11:52:33 2009 +0800 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,1069 +0,0 @@ 23.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 23.5 - 23.6 -<chapter id="chap:undo"> 23.7 - <?dbhtml filename="finding-and-fixing-mistakes.html"?> 23.8 - <title>Finding and fixing mistakes</title> 23.9 - 23.10 - <para id="x_d2">To err might be human, but to really handle the consequences 23.11 - well takes a top-notch revision control system. In this chapter, 23.12 - we'll discuss some of the techniques you can use when you find 23.13 - that a problem has crept into your project. Mercurial has some 23.14 - highly capable features that will help you to isolate the sources 23.15 - of problems, and to handle them appropriately.</para> 23.16 - 23.17 - <sect1> 23.18 - <title>Erasing local history</title> 23.19 - 23.20 - <sect2> 23.21 - <title>The accidental commit</title> 23.22 - 23.23 - <para id="x_d3">I have the occasional but persistent problem of typing 23.24 - rather more quickly than I can think, which sometimes results 23.25 - in me committing a changeset that is either incomplete or 23.26 - plain wrong. In my case, the usual kind of incomplete 23.27 - changeset is one in which I've created a new source file, but 23.28 - forgotten to <command role="hg-cmd">hg add</command> it. A 23.29 - <quote>plain wrong</quote> changeset is not as common, but no 23.30 - less annoying.</para> 23.31 - 23.32 - </sect2> 23.33 - <sect2 id="sec:undo:rollback"> 23.34 - <title>Rolling back a transaction</title> 23.35 - 23.36 - <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I 23.37 - mentioned that Mercurial treats each modification of a 23.38 - repository as a <emphasis>transaction</emphasis>. Every time 23.39 - you commit a changeset or pull changes from another 23.40 - repository, Mercurial remembers what you did. You can undo, 23.41 - or <emphasis>roll back</emphasis>, exactly one of these 23.42 - actions using the <command role="hg-cmd">hg rollback</command> 23.43 - command. (See <xref linkend="sec:undo:rollback-after-push"/> 23.44 - for an important caveat about the use of this command.)</para> 23.45 - 23.46 - <para id="x_d5">Here's a mistake that I often find myself making: 23.47 - committing a change in which I've created a new file, but 23.48 - forgotten to <command role="hg-cmd">hg add</command> 23.49 - it.</para> 23.50 - 23.51 - &interaction.rollback.commit; 23.52 - 23.53 - <para id="x_d6">Looking at the output of <command role="hg-cmd">hg 23.54 - status</command> after the commit immediately confirms the 23.55 - error.</para> 23.56 - 23.57 - &interaction.rollback.status; 23.58 - 23.59 - <para id="x_d7">The commit captured the changes to the file 23.60 - <filename>a</filename>, but not the new file 23.61 - <filename>b</filename>. If I were to push this changeset to a 23.62 - repository that I shared with a colleague, the chances are 23.63 - high that something in <filename>a</filename> would refer to 23.64 - <filename>b</filename>, which would not be present in their 23.65 - repository when they pulled my changes. I would thus become 23.66 - the object of some indignation.</para> 23.67 - 23.68 - <para id="x_d8">However, luck is with me&emdash;I've caught my error 23.69 - before I pushed the changeset. I use the <command 23.70 - role="hg-cmd">hg rollback</command> command, and Mercurial 23.71 - makes that last changeset vanish.</para> 23.72 - 23.73 - &interaction.rollback.rollback; 23.74 - 23.75 - <para id="x_d9">Notice that the changeset is no longer present in the 23.76 - repository's history, and the working directory once again 23.77 - thinks that the file <filename>a</filename> is modified. The 23.78 - commit and rollback have left the working directory exactly as 23.79 - it was prior to the commit; the changeset has been completely 23.80 - erased. I can now safely <command role="hg-cmd">hg 23.81 - add</command> the file <filename>b</filename>, and rerun my 23.82 - commit.</para> 23.83 - 23.84 - &interaction.rollback.add; 23.85 - 23.86 - </sect2> 23.87 - <sect2> 23.88 - <title>The erroneous pull</title> 23.89 - 23.90 - <para id="x_da">It's common practice with Mercurial to maintain separate 23.91 - development branches of a project in different repositories. 23.92 - Your development team might have one shared repository for 23.93 - your project's <quote>0.9</quote> release, and another, 23.94 - containing different changes, for the <quote>1.0</quote> 23.95 - release.</para> 23.96 - 23.97 - <para id="x_db">Given this, you can imagine that the consequences could be 23.98 - messy if you had a local <quote>0.9</quote> repository, and 23.99 - accidentally pulled changes from the shared <quote>1.0</quote> 23.100 - repository into it. At worst, you could be paying 23.101 - insufficient attention, and push those changes into the shared 23.102 - <quote>0.9</quote> tree, confusing your entire team (but don't 23.103 - worry, we'll return to this horror scenario later). However, 23.104 - it's more likely that you'll notice immediately, because 23.105 - Mercurial will display the URL it's pulling from, or you will 23.106 - see it pull a suspiciously large number of changes into the 23.107 - repository.</para> 23.108 - 23.109 - <para id="x_dc">The <command role="hg-cmd">hg rollback</command> command 23.110 - will work nicely to expunge all of the changesets that you 23.111 - just pulled. Mercurial groups all changes from one <command 23.112 - role="hg-cmd">hg pull</command> into a single transaction, 23.113 - so one <command role="hg-cmd">hg rollback</command> is all you 23.114 - need to undo this mistake.</para> 23.115 - 23.116 - </sect2> 23.117 - <sect2 id="sec:undo:rollback-after-push"> 23.118 - <title>Rolling back is useless once you've pushed</title> 23.119 - 23.120 - <para id="x_dd">The value of the <command role="hg-cmd">hg 23.121 - rollback</command> command drops to zero once you've pushed 23.122 - your changes to another repository. Rolling back a change 23.123 - makes it disappear entirely, but <emphasis>only</emphasis> in 23.124 - the repository in which you perform the <command 23.125 - role="hg-cmd">hg rollback</command>. Because a rollback 23.126 - eliminates history, there's no way for the disappearance of a 23.127 - change to propagate between repositories.</para> 23.128 - 23.129 - <para id="x_de">If you've pushed a change to another 23.130 - repository&emdash;particularly if it's a shared 23.131 - repository&emdash;it has essentially <quote>escaped into the 23.132 - wild,</quote> and you'll have to recover from your mistake 23.133 - in a different way. What will happen if you push a changeset 23.134 - somewhere, then roll it back, then pull from the repository 23.135 - you pushed to, is that the changeset will reappear in your 23.136 - repository.</para> 23.137 - 23.138 - <para id="x_df">(If you absolutely know for sure that the change you want 23.139 - to roll back is the most recent change in the repository that 23.140 - you pushed to, <emphasis>and</emphasis> you know that nobody 23.141 - else could have pulled it from that repository, you can roll 23.142 - back the changeset there, too, but you really should really 23.143 - not rely on this working reliably. If you do this, sooner or 23.144 - later a change really will make it into a repository that you 23.145 - don't directly control (or have forgotten about), and come 23.146 - back to bite you.)</para> 23.147 - 23.148 - </sect2> 23.149 - <sect2> 23.150 - <title>You can only roll back once</title> 23.151 - 23.152 - <para id="x_e0">Mercurial stores exactly one transaction in its 23.153 - transaction log; that transaction is the most recent one that 23.154 - occurred in the repository. This means that you can only roll 23.155 - back one transaction. If you expect to be able to roll back 23.156 - one transaction, then its predecessor, this is not the 23.157 - behavior you will get.</para> 23.158 - 23.159 - &interaction.rollback.twice; 23.160 - 23.161 - <para id="x_e1">Once you've rolled back one transaction in a repository, 23.162 - you can't roll back again in that repository until you perform 23.163 - another commit or pull.</para> 23.164 - 23.165 - </sect2> 23.166 - </sect1> 23.167 - <sect1> 23.168 - <title>Reverting the mistaken change</title> 23.169 - 23.170 - <para id="x_e2">If you make a modification to a file, and decide that you 23.171 - really didn't want to change the file at all, and you haven't 23.172 - yet committed your changes, the <command role="hg-cmd">hg 23.173 - revert</command> command is the one you'll need. It looks at 23.174 - the changeset that's the parent of the working directory, and 23.175 - restores the contents of the file to their state as of that 23.176 - changeset. (That's a long-winded way of saying that, in the 23.177 - normal case, it undoes your modifications.)</para> 23.178 - 23.179 - <para id="x_e3">Let's illustrate how the <command role="hg-cmd">hg 23.180 - revert</command> command works with yet another small example. 23.181 - We'll begin by modifying a file that Mercurial is already 23.182 - tracking.</para> 23.183 - 23.184 - &interaction.daily.revert.modify; 23.185 - 23.186 - <para id="x_e4">If we don't 23.187 - want that change, we can simply <command role="hg-cmd">hg 23.188 - revert</command> the file.</para> 23.189 - 23.190 - &interaction.daily.revert.unmodify; 23.191 - 23.192 - <para id="x_e5">The <command role="hg-cmd">hg revert</command> command 23.193 - provides us with an extra degree of safety by saving our 23.194 - modified file with a <filename>.orig</filename> 23.195 - extension.</para> 23.196 - 23.197 - &interaction.daily.revert.status; 23.198 - 23.199 - <para id="x_e6">Here is a summary of the cases that the <command 23.200 - role="hg-cmd">hg revert</command> command can deal with. We 23.201 - will describe each of these in more detail in the section that 23.202 - follows.</para> 23.203 - <itemizedlist> 23.204 - <listitem><para id="x_e7">If you modify a file, it will restore the file 23.205 - to its unmodified state.</para> 23.206 - </listitem> 23.207 - <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a 23.208 - file, it will undo the <quote>added</quote> state of the 23.209 - file, but leave the file itself untouched.</para> 23.210 - </listitem> 23.211 - <listitem><para id="x_e9">If you delete a file without telling Mercurial, 23.212 - it will restore the file to its unmodified contents.</para> 23.213 - </listitem> 23.214 - <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg 23.215 - remove</command> command to remove a file, it will undo 23.216 - the <quote>removed</quote> state of the file, and restore 23.217 - the file to its unmodified contents.</para> 23.218 - </listitem></itemizedlist> 23.219 - 23.220 - <sect2 id="sec:undo:mgmt"> 23.221 - <title>File management errors</title> 23.222 - 23.223 - <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is 23.224 - useful for more than just modified files. It lets you reverse 23.225 - the results of all of Mercurial's file management 23.226 - commands&emdash;<command role="hg-cmd">hg add</command>, 23.227 - <command role="hg-cmd">hg remove</command>, and so on.</para> 23.228 - 23.229 - <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file, 23.230 - then decide that in fact you don't want Mercurial to track it, 23.231 - use <command role="hg-cmd">hg revert</command> to undo the 23.232 - add. Don't worry; Mercurial will not modify the file in any 23.233 - way. It will just <quote>unmark</quote> the file.</para> 23.234 - 23.235 - &interaction.daily.revert.add; 23.236 - 23.237 - <para id="x_ed">Similarly, if you ask Mercurial to <command 23.238 - role="hg-cmd">hg remove</command> a file, you can use 23.239 - <command role="hg-cmd">hg revert</command> to restore it to 23.240 - the contents it had as of the parent of the working directory. 23.241 - &interaction.daily.revert.remove; This works just as 23.242 - well for a file that you deleted by hand, without telling 23.243 - Mercurial (recall that in Mercurial terminology, this kind of 23.244 - file is called <quote>missing</quote>).</para> 23.245 - 23.246 - &interaction.daily.revert.missing; 23.247 - 23.248 - <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>, 23.249 - the copied-to file remains in your working directory 23.250 - afterwards, untracked. Since a copy doesn't affect the 23.251 - copied-from file in any way, Mercurial doesn't do anything 23.252 - with the copied-from file.</para> 23.253 - 23.254 - &interaction.daily.revert.copy; 23.255 - 23.256 - <sect3> 23.257 - <title>A slightly special case: reverting a rename</title> 23.258 - 23.259 - <para id="x_ef">If you <command role="hg-cmd">hg rename</command> a 23.260 - file, there is one small detail that you should remember. 23.261 - When you <command role="hg-cmd">hg revert</command> a 23.262 - rename, it's not enough to provide the name of the 23.263 - renamed-to file, as you can see here.</para> 23.264 - 23.265 - &interaction.daily.revert.rename; 23.266 - 23.267 - <para id="x_f0">As you can see from the output of <command 23.268 - role="hg-cmd">hg status</command>, the renamed-to file is 23.269 - no longer identified as added, but the 23.270 - renamed-<emphasis>from</emphasis> file is still removed! 23.271 - This is counter-intuitive (at least to me), but at least 23.272 - it's easy to deal with.</para> 23.273 - 23.274 - &interaction.daily.revert.rename-orig; 23.275 - 23.276 - <para id="x_f1">So remember, to revert a <command role="hg-cmd">hg 23.277 - rename</command>, you must provide 23.278 - <emphasis>both</emphasis> the source and destination 23.279 - names.</para> 23.280 - 23.281 - <para id="x_f2">% TODO: the output doesn't look like it will be 23.282 - removed!</para> 23.283 - 23.284 - <para id="x_f3">(By the way, if you rename a file, then modify the 23.285 - renamed-to file, then revert both components of the rename, 23.286 - when Mercurial restores the file that was removed as part of 23.287 - the rename, it will be unmodified. If you need the 23.288 - modifications in the renamed-to file to show up in the 23.289 - renamed-from file, don't forget to copy them over.)</para> 23.290 - 23.291 - <para id="x_f4">These fiddly aspects of reverting a rename arguably 23.292 - constitute a small bug in Mercurial.</para> 23.293 - 23.294 - </sect3> 23.295 - </sect2> 23.296 - </sect1> 23.297 - <sect1> 23.298 - <title>Dealing with committed changes</title> 23.299 - 23.300 - <para id="x_f5">Consider a case where you have committed a change $a$, and 23.301 - another change $b$ on top of it; you then realise that change 23.302 - $a$ was incorrect. Mercurial lets you <quote>back out</quote> 23.303 - an entire changeset automatically, and building blocks that let 23.304 - you reverse part of a changeset by hand.</para> 23.305 - 23.306 - <para id="x_f6">Before you read this section, here's something to 23.307 - keep in mind: the <command role="hg-cmd">hg backout</command> 23.308 - command undoes changes by <emphasis>adding</emphasis> history, 23.309 - not by modifying or erasing it. It's the right tool to use if 23.310 - you're fixing bugs, but not if you're trying to undo some change 23.311 - that has catastrophic consequences. To deal with those, see 23.312 - <xref linkend="sec:undo:aaaiiieee"/>.</para> 23.313 - 23.314 - <sect2> 23.315 - <title>Backing out a changeset</title> 23.316 - 23.317 - <para id="x_f7">The <command role="hg-cmd">hg backout</command> command 23.318 - lets you <quote>undo</quote> the effects of an entire 23.319 - changeset in an automated fashion. Because Mercurial's 23.320 - history is immutable, this command <emphasis>does 23.321 - not</emphasis> get rid of the changeset you want to undo. 23.322 - Instead, it creates a new changeset that 23.323 - <emphasis>reverses</emphasis> the effect of the to-be-undone 23.324 - changeset.</para> 23.325 - 23.326 - <para id="x_f8">The operation of the <command role="hg-cmd">hg 23.327 - backout</command> command is a little intricate, so let's 23.328 - illustrate it with some examples. First, we'll create a 23.329 - repository with some simple changes.</para> 23.330 - 23.331 - &interaction.backout.init; 23.332 - 23.333 - <para id="x_f9">The <command role="hg-cmd">hg backout</command> command 23.334 - takes a single changeset ID as its argument; this is the 23.335 - changeset to back out. Normally, <command role="hg-cmd">hg 23.336 - backout</command> will drop you into a text editor to write 23.337 - a commit message, so you can record why you're backing the 23.338 - change out. In this example, we provide a commit message on 23.339 - the command line using the <option 23.340 - role="hg-opt-backout">-m</option> option.</para> 23.341 - 23.342 - </sect2> 23.343 - <sect2> 23.344 - <title>Backing out the tip changeset</title> 23.345 - 23.346 - <para id="x_fa">We're going to start by backing out the last changeset we 23.347 - committed.</para> 23.348 - 23.349 - &interaction.backout.simple; 23.350 - 23.351 - <para id="x_fb">You can see that the second line from 23.352 - <filename>myfile</filename> is no longer present. Taking a 23.353 - look at the output of <command role="hg-cmd">hg log</command> 23.354 - gives us an idea of what the <command role="hg-cmd">hg 23.355 - backout</command> command has done. 23.356 - &interaction.backout.simple.log; Notice that the new changeset 23.357 - that <command role="hg-cmd">hg backout</command> has created 23.358 - is a child of the changeset we backed out. It's easier to see 23.359 - this in <xref linkend="fig:undo:backout"/>, which presents a 23.360 - graphical view of the change history. As you can see, the 23.361 - history is nice and linear.</para> 23.362 - 23.363 - <figure id="fig:undo:backout"> 23.364 - <title>Backing out a change using the <command 23.365 - role="hg-cmd">hg backout</command> command</title> 23.366 - <mediaobject> 23.367 - <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject> 23.368 - <textobject><phrase>XXX add text</phrase></textobject> 23.369 - </mediaobject> 23.370 - </figure> 23.371 - 23.372 - </sect2> 23.373 - <sect2> 23.374 - <title>Backing out a non-tip change</title> 23.375 - 23.376 - <para id="x_fd">If you want to back out a change other than the last one 23.377 - you committed, pass the <option 23.378 - role="hg-opt-backout">--merge</option> option to the 23.379 - <command role="hg-cmd">hg backout</command> command.</para> 23.380 - 23.381 - &interaction.backout.non-tip.clone; 23.382 - 23.383 - <para id="x_fe">This makes backing out any changeset a 23.384 - <quote>one-shot</quote> operation that's usually simple and 23.385 - fast.</para> 23.386 - 23.387 - &interaction.backout.non-tip.backout; 23.388 - 23.389 - <para id="x_ff">If you take a look at the contents of 23.390 - <filename>myfile</filename> after the backout finishes, you'll 23.391 - see that the first and third changes are present, but not the 23.392 - second.</para> 23.393 - 23.394 - &interaction.backout.non-tip.cat; 23.395 - 23.396 - <para id="x_100">As the graphical history in <xref 23.397 - linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial 23.398 - actually commits <emphasis>two</emphasis> changes in this kind 23.399 - of situation (the box-shaped nodes are the ones that Mercurial 23.400 - commits automatically). Before Mercurial begins the backout 23.401 - process, it first remembers what the current parent of the 23.402 - working directory is. It then backs out the target changeset, 23.403 - and commits that as a changeset. Finally, it merges back to 23.404 - the previous parent of the working directory, and commits the 23.405 - result of the merge.</para> 23.406 - 23.407 - <para id="x_101">% TODO: to me it looks like mercurial doesn't commit the 23.408 - second merge automatically!</para> 23.409 - 23.410 - <figure id="fig:undo:backout-non-tip"> 23.411 - <title>Automated backout of a non-tip change using the 23.412 - <command role="hg-cmd">hg backout</command> command</title> 23.413 - <mediaobject> 23.414 - <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject> 23.415 - <textobject><phrase>XXX add text</phrase></textobject> 23.416 - </mediaobject> 23.417 - </figure> 23.418 - 23.419 - <para id="x_103">The result is that you end up <quote>back where you 23.420 - were</quote>, only with some extra history that undoes the 23.421 - effect of the changeset you wanted to back out.</para> 23.422 - 23.423 - <sect3> 23.424 - <title>Always use the <option 23.425 - role="hg-opt-backout">--merge</option> option</title> 23.426 - 23.427 - <para id="x_104">In fact, since the <option 23.428 - role="hg-opt-backout">--merge</option> option will do the 23.429 - <quote>right thing</quote> whether or not the changeset 23.430 - you're backing out is the tip (i.e. it won't try to merge if 23.431 - it's backing out the tip, since there's no need), you should 23.432 - <emphasis>always</emphasis> use this option when you run the 23.433 - <command role="hg-cmd">hg backout</command> command.</para> 23.434 - 23.435 - </sect3> 23.436 - </sect2> 23.437 - <sect2> 23.438 - <title>Gaining more control of the backout process</title> 23.439 - 23.440 - <para id="x_105">While I've recommended that you always use the <option 23.441 - role="hg-opt-backout">--merge</option> option when backing 23.442 - out a change, the <command role="hg-cmd">hg backout</command> 23.443 - command lets you decide how to merge a backout changeset. 23.444 - Taking control of the backout process by hand is something you 23.445 - will rarely need to do, but it can be useful to understand 23.446 - what the <command role="hg-cmd">hg backout</command> command 23.447 - is doing for you automatically. To illustrate this, let's 23.448 - clone our first repository, but omit the backout change that 23.449 - it contains.</para> 23.450 - 23.451 - &interaction.backout.manual.clone; 23.452 - 23.453 - <para id="x_106">As with our 23.454 - earlier example, We'll commit a third changeset, then back out 23.455 - its parent, and see what happens.</para> 23.456 - 23.457 - &interaction.backout.manual.backout; 23.458 - 23.459 - <para id="x_107">Our new changeset is again a descendant of the changeset 23.460 - we backout out; it's thus a new head, <emphasis>not</emphasis> 23.461 - a descendant of the changeset that was the tip. The <command 23.462 - role="hg-cmd">hg backout</command> command was quite 23.463 - explicit in telling us this.</para> 23.464 - 23.465 - &interaction.backout.manual.log; 23.466 - 23.467 - <para id="x_108">Again, it's easier to see what has happened by looking at 23.468 - a graph of the revision history, in <xref 23.469 - linkend="fig:undo:backout-manual"/>. This makes it clear 23.470 - that when we use <command role="hg-cmd">hg backout</command> 23.471 - to back out a change other than the tip, Mercurial adds a new 23.472 - head to the repository (the change it committed is 23.473 - box-shaped).</para> 23.474 - 23.475 - <figure id="fig:undo:backout-manual"> 23.476 - <title>Backing out a change using the <command 23.477 - role="hg-cmd">hg backout</command> command</title> 23.478 - <mediaobject> 23.479 - <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject> 23.480 - <textobject><phrase>XXX add text</phrase></textobject> 23.481 - </mediaobject> 23.482 - </figure> 23.483 - 23.484 - <para id="x_10a">After the <command role="hg-cmd">hg backout</command> 23.485 - command has completed, it leaves the new 23.486 - <quote>backout</quote> changeset as the parent of the working 23.487 - directory.</para> 23.488 - 23.489 - &interaction.backout.manual.parents; 23.490 - 23.491 - <para id="x_10b">Now we have two isolated sets of changes.</para> 23.492 - 23.493 - &interaction.backout.manual.heads; 23.494 - 23.495 - <para id="x_10c">Let's think about what we expect to see as the contents of 23.496 - <filename>myfile</filename> now. The first change should be 23.497 - present, because we've never backed it out. The second change 23.498 - should be missing, as that's the change we backed out. Since 23.499 - the history graph shows the third change as a separate head, 23.500 - we <emphasis>don't</emphasis> expect to see the third change 23.501 - present in <filename>myfile</filename>.</para> 23.502 - 23.503 - &interaction.backout.manual.cat; 23.504 - 23.505 - <para id="x_10d">To get the third change back into the file, we just do a 23.506 - normal merge of our two heads.</para> 23.507 - 23.508 - &interaction.backout.manual.merge; 23.509 - 23.510 - <para id="x_10e">Afterwards, the graphical history of our 23.511 - repository looks like 23.512 - <xref linkend="fig:undo:backout-manual-merge"/>.</para> 23.513 - 23.514 - <figure id="fig:undo:backout-manual-merge"> 23.515 - <title>Manually merging a backout change</title> 23.516 - <mediaobject> 23.517 - <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject> 23.518 - <textobject><phrase>XXX add text</phrase></textobject> 23.519 - </mediaobject> 23.520 - </figure> 23.521 - 23.522 - </sect2> 23.523 - <sect2> 23.524 - <title>Why <command role="hg-cmd">hg backout</command> works as 23.525 - it does</title> 23.526 - 23.527 - <para id="x_110">Here's a brief description of how the <command 23.528 - role="hg-cmd">hg backout</command> command works.</para> 23.529 - <orderedlist> 23.530 - <listitem><para id="x_111">It ensures that the working directory is 23.531 - <quote>clean</quote>, i.e. that the output of <command 23.532 - role="hg-cmd">hg status</command> would be empty.</para> 23.533 - </listitem> 23.534 - <listitem><para id="x_112">It remembers the current parent of the working 23.535 - directory. Let's call this changeset 23.536 - <literal>orig</literal></para> 23.537 - </listitem> 23.538 - <listitem><para id="x_113">It does the equivalent of a <command 23.539 - role="hg-cmd">hg update</command> to sync the working 23.540 - directory to the changeset you want to back out. Let's 23.541 - call this changeset <literal>backout</literal></para> 23.542 - </listitem> 23.543 - <listitem><para id="x_114">It finds the parent of that changeset. Let's 23.544 - call that changeset <literal>parent</literal>.</para> 23.545 - </listitem> 23.546 - <listitem><para id="x_115">For each file that the 23.547 - <literal>backout</literal> changeset affected, it does the 23.548 - equivalent of a <command role="hg-cmd">hg revert -r 23.549 - parent</command> on that file, to restore it to the 23.550 - contents it had before that changeset was 23.551 - committed.</para> 23.552 - </listitem> 23.553 - <listitem><para id="x_116">It commits the result as a new changeset. 23.554 - This changeset has <literal>backout</literal> as its 23.555 - parent.</para> 23.556 - </listitem> 23.557 - <listitem><para id="x_117">If you specify <option 23.558 - role="hg-opt-backout">--merge</option> on the command 23.559 - line, it merges with <literal>orig</literal>, and commits 23.560 - the result of the merge.</para> 23.561 - </listitem></orderedlist> 23.562 - 23.563 - <para id="x_118">An alternative way to implement the <command 23.564 - role="hg-cmd">hg backout</command> command would be to 23.565 - <command role="hg-cmd">hg export</command> the 23.566 - to-be-backed-out changeset as a diff, then use the <option 23.567 - role="cmd-opt-patch">--reverse</option> option to the 23.568 - <command>patch</command> command to reverse the effect of the 23.569 - change without fiddling with the working directory. This 23.570 - sounds much simpler, but it would not work nearly as 23.571 - well.</para> 23.572 - 23.573 - <para id="x_119">The reason that <command role="hg-cmd">hg 23.574 - backout</command> does an update, a commit, a merge, and 23.575 - another commit is to give the merge machinery the best chance 23.576 - to do a good job when dealing with all the changes 23.577 - <emphasis>between</emphasis> the change you're backing out and 23.578 - the current tip.</para> 23.579 - 23.580 - <para id="x_11a">If you're backing out a changeset that's 100 revisions 23.581 - back in your project's history, the chances that the 23.582 - <command>patch</command> command will be able to apply a 23.583 - reverse diff cleanly are not good, because intervening changes 23.584 - are likely to have <quote>broken the context</quote> that 23.585 - <command>patch</command> uses to determine whether it can 23.586 - apply a patch (if this sounds like gibberish, see <xref 23.587 - linkend="sec:mq:patch"/> for a 23.588 - discussion of the <command>patch</command> command). Also, 23.589 - Mercurial's merge machinery will handle files and directories 23.590 - being renamed, permission changes, and modifications to binary 23.591 - files, none of which <command>patch</command> can deal 23.592 - with.</para> 23.593 - 23.594 - </sect2> 23.595 - </sect1> 23.596 - <sect1 id="sec:undo:aaaiiieee"> 23.597 - <title>Changes that should never have been</title> 23.598 - 23.599 - <para id="x_11b">Most of the time, the <command role="hg-cmd">hg 23.600 - backout</command> command is exactly what you need if you want 23.601 - to undo the effects of a change. It leaves a permanent record 23.602 - of exactly what you did, both when committing the original 23.603 - changeset and when you cleaned up after it.</para> 23.604 - 23.605 - <para id="x_11c">On rare occasions, though, you may find that you've 23.606 - committed a change that really should not be present in the 23.607 - repository at all. For example, it would be very unusual, and 23.608 - usually considered a mistake, to commit a software project's 23.609 - object files as well as its source files. Object files have 23.610 - almost no intrinsic value, and they're <emphasis>big</emphasis>, 23.611 - so they increase the size of the repository and the amount of 23.612 - time it takes to clone or pull changes.</para> 23.613 - 23.614 - <para id="x_11d">Before I discuss the options that you have if you commit a 23.615 - <quote>brown paper bag</quote> change (the kind that's so bad 23.616 - that you want to pull a brown paper bag over your head), let me 23.617 - first discuss some approaches that probably won't work.</para> 23.618 - 23.619 - <para id="x_11e">Since Mercurial treats history as 23.620 - accumulative&emdash;every change builds on top of all changes 23.621 - that preceded it&emdash;you generally can't just make disastrous 23.622 - changes disappear. The one exception is when you've just 23.623 - committed a change, and it hasn't been pushed or pulled into 23.624 - another repository. That's when you can safely use the <command 23.625 - role="hg-cmd">hg rollback</command> command, as I detailed in 23.626 - <xref linkend="sec:undo:rollback"/>.</para> 23.627 - 23.628 - <para id="x_11f">After you've pushed a bad change to another repository, you 23.629 - <emphasis>could</emphasis> still use <command role="hg-cmd">hg 23.630 - rollback</command> to make your local copy of the change 23.631 - disappear, but it won't have the consequences you want. The 23.632 - change will still be present in the remote repository, so it 23.633 - will reappear in your local repository the next time you 23.634 - pull.</para> 23.635 - 23.636 - <para id="x_120">If a situation like this arises, and you know which 23.637 - repositories your bad change has propagated into, you can 23.638 - <emphasis>try</emphasis> to get rid of the changeefrom 23.639 - <emphasis>every</emphasis> one of those repositories. This is, 23.640 - of course, not a satisfactory solution: if you miss even a 23.641 - single repository while you're expunging, the change is still 23.642 - <quote>in the wild</quote>, and could propagate further.</para> 23.643 - 23.644 - <para id="x_121">If you've committed one or more changes 23.645 - <emphasis>after</emphasis> the change that you'd like to see 23.646 - disappear, your options are further reduced. Mercurial doesn't 23.647 - provide a way to <quote>punch a hole</quote> in history, leaving 23.648 - changesets intact.</para> 23.649 - 23.650 - <para id="x_122">XXX This needs filling out. The 23.651 - <literal>hg-replay</literal> script in the 23.652 - <literal>examples</literal> directory works, but doesn't handle 23.653 - merge changesets. Kind of an important omission.</para> 23.654 - 23.655 - <sect2> 23.656 - <title>Protect yourself from <quote>escaped</quote> 23.657 - changes</title> 23.658 - 23.659 - <para id="x_123">If you've committed some changes to your local repository 23.660 - and they've been pushed or pulled somewhere else, this isn't 23.661 - necessarily a disaster. You can protect yourself ahead of 23.662 - time against some classes of bad changeset. This is 23.663 - particularly easy if your team usually pulls changes from a 23.664 - central repository.</para> 23.665 - 23.666 - <para id="x_124">By configuring some hooks on that repository to validate 23.667 - incoming changesets (see chapter <xref linkend="chap:hook"/>), 23.668 - you can 23.669 - automatically prevent some kinds of bad changeset from being 23.670 - pushed to the central repository at all. With such a 23.671 - configuration in place, some kinds of bad changeset will 23.672 - naturally tend to <quote>die out</quote> because they can't 23.673 - propagate into the central repository. Better yet, this 23.674 - happens without any need for explicit intervention.</para> 23.675 - 23.676 - <para id="x_125">For instance, an incoming change hook that verifies that a 23.677 - changeset will actually compile can prevent people from 23.678 - inadvertantly <quote>breaking the build</quote>.</para> 23.679 - 23.680 - </sect2> 23.681 - </sect1> 23.682 - <sect1 id="sec:undo:bisect"> 23.683 - <title>Finding the source of a bug</title> 23.684 - 23.685 - <para id="x_126">While it's all very well to be able to back out a changeset 23.686 - that introduced a bug, this requires that you know which 23.687 - changeset to back out. Mercurial provides an invaluable 23.688 - command, called <command role="hg-cmd">hg bisect</command>, that 23.689 - helps you to automate this process and accomplish it very 23.690 - efficiently.</para> 23.691 - 23.692 - <para id="x_127">The idea behind the <command role="hg-cmd">hg 23.693 - bisect</command> command is that a changeset has introduced 23.694 - some change of behavior that you can identify with a simple 23.695 - binary test. You don't know which piece of code introduced the 23.696 - change, but you know how to test for the presence of the bug. 23.697 - The <command role="hg-cmd">hg bisect</command> command uses your 23.698 - test to direct its search for the changeset that introduced the 23.699 - code that caused the bug.</para> 23.700 - 23.701 - <para id="x_128">Here are a few scenarios to help you understand how you 23.702 - might apply this command.</para> 23.703 - <itemizedlist> 23.704 - <listitem><para id="x_129">The most recent version of your software has a 23.705 - bug that you remember wasn't present a few weeks ago, but 23.706 - you don't know when it was introduced. Here, your binary 23.707 - test checks for the presence of that bug.</para> 23.708 - </listitem> 23.709 - <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to 23.710 - close the entry in your team's bug database. The bug 23.711 - database requires a changeset ID when you close an entry, 23.712 - but you don't remember which changeset you fixed the bug in. 23.713 - Once again, your binary test checks for the presence of the 23.714 - bug.</para> 23.715 - </listitem> 23.716 - <listitem><para id="x_12b">Your software works correctly, but runs 15% 23.717 - slower than the last time you measured it. You want to know 23.718 - which changeset introduced the performance regression. In 23.719 - this case, your binary test measures the performance of your 23.720 - software, to see whether it's <quote>fast</quote> or 23.721 - <quote>slow</quote>.</para> 23.722 - </listitem> 23.723 - <listitem><para id="x_12c">The sizes of the components of your project that 23.724 - you ship exploded recently, and you suspect that something 23.725 - changed in the way you build your project.</para> 23.726 - </listitem></itemizedlist> 23.727 - 23.728 - <para id="x_12d">From these examples, it should be clear that the <command 23.729 - role="hg-cmd">hg bisect</command> command is not useful only 23.730 - for finding the sources of bugs. You can use it to find any 23.731 - <quote>emergent property</quote> of a repository (anything that 23.732 - you can't find from a simple text search of the files in the 23.733 - tree) for which you can write a binary test.</para> 23.734 - 23.735 - <para id="x_12e">We'll introduce a little bit of terminology here, just to 23.736 - make it clear which parts of the search process are your 23.737 - responsibility, and which are Mercurial's. A 23.738 - <emphasis>test</emphasis> is something that 23.739 - <emphasis>you</emphasis> run when <command role="hg-cmd">hg 23.740 - bisect</command> chooses a changeset. A 23.741 - <emphasis>probe</emphasis> is what <command role="hg-cmd">hg 23.742 - bisect</command> runs to tell whether a revision is good. 23.743 - Finally, we'll use the word <quote>bisect</quote>, as both a 23.744 - noun and a verb, to stand in for the phrase <quote>search using 23.745 - the <command role="hg-cmd">hg bisect</command> 23.746 - command</quote>.</para> 23.747 - 23.748 - <para id="x_12f">One simple way to automate the searching process would be 23.749 - simply to probe every changeset. However, this scales poorly. 23.750 - If it took ten minutes to test a single changeset, and you had 23.751 - 10,000 changesets in your repository, the exhaustive approach 23.752 - would take on average 35 <emphasis>days</emphasis> to find the 23.753 - changeset that introduced a bug. Even if you knew that the bug 23.754 - was introduced by one of the last 500 changesets, and limited 23.755 - your search to those, you'd still be looking at over 40 hours to 23.756 - find the changeset that introduced your bug.</para> 23.757 - 23.758 - <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command 23.759 - does is use its knowledge of the <quote>shape</quote> of your 23.760 - project's revision history to perform a search in time 23.761 - proportional to the <emphasis>logarithm</emphasis> of the number 23.762 - of changesets to check (the kind of search it performs is called 23.763 - a dichotomic search). With this approach, searching through 23.764 - 10,000 changesets will take less than three hours, even at ten 23.765 - minutes per test (the search will require about 14 tests). 23.766 - Limit your search to the last hundred changesets, and it will 23.767 - take only about an hour (roughly seven tests).</para> 23.768 - 23.769 - <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is 23.770 - aware of the <quote>branchy</quote> nature of a Mercurial 23.771 - project's revision history, so it has no problems dealing with 23.772 - branches, merges, or multiple heads in a repository. It can 23.773 - prune entire branches of history with a single probe, which is 23.774 - how it operates so efficiently.</para> 23.775 - 23.776 - <sect2> 23.777 - <title>Using the <command role="hg-cmd">hg bisect</command> 23.778 - command</title> 23.779 - 23.780 - <para id="x_132">Here's an example of <command role="hg-cmd">hg 23.781 - bisect</command> in action.</para> 23.782 - 23.783 - <note> 23.784 - <para id="x_133"> In versions 0.9.5 and earlier of Mercurial, <command 23.785 - role="hg-cmd">hg bisect</command> was not a core command: 23.786 - it was distributed with Mercurial as an extension. This 23.787 - section describes the built-in command, not the old 23.788 - extension.</para> 23.789 - </note> 23.790 - 23.791 - <para id="x_134">Now let's create a repository, so that we can try out the 23.792 - <command role="hg-cmd">hg bisect</command> command in 23.793 - isolation.</para> 23.794 - 23.795 - &interaction.bisect.init; 23.796 - 23.797 - <para id="x_135">We'll simulate a project that has a bug in it in a 23.798 - simple-minded way: create trivial changes in a loop, and 23.799 - nominate one specific change that will have the 23.800 - <quote>bug</quote>. This loop creates 35 changesets, each 23.801 - adding a single file to the repository. We'll represent our 23.802 - <quote>bug</quote> with a file that contains the text <quote>i 23.803 - have a gub</quote>.</para> 23.804 - 23.805 - &interaction.bisect.commits; 23.806 - 23.807 - <para id="x_136">The next thing that we'd like to do is figure out how to 23.808 - use the <command role="hg-cmd">hg bisect</command> command. 23.809 - We can use Mercurial's normal built-in help mechanism for 23.810 - this.</para> 23.811 - 23.812 - &interaction.bisect.help; 23.813 - 23.814 - <para id="x_137">The <command role="hg-cmd">hg bisect</command> command 23.815 - works in steps. Each step proceeds as follows.</para> 23.816 - <orderedlist> 23.817 - <listitem><para id="x_138">You run your binary test.</para> 23.818 - <itemizedlist> 23.819 - <listitem><para id="x_139">If the test succeeded, you tell <command 23.820 - role="hg-cmd">hg bisect</command> by running the 23.821 - <command role="hg-cmd">hg bisect good</command> 23.822 - command.</para> 23.823 - </listitem> 23.824 - <listitem><para id="x_13a">If it failed, run the <command 23.825 - role="hg-cmd">hg bisect bad</command> 23.826 - command.</para></listitem></itemizedlist> 23.827 - </listitem> 23.828 - <listitem><para id="x_13b">The command uses your information to decide 23.829 - which changeset to test next.</para> 23.830 - </listitem> 23.831 - <listitem><para id="x_13c">It updates the working directory to that 23.832 - changeset, and the process begins again.</para> 23.833 - </listitem></orderedlist> 23.834 - <para id="x_13d">The process ends when <command role="hg-cmd">hg 23.835 - bisect</command> identifies a unique changeset that marks 23.836 - the point where your test transitioned from 23.837 - <quote>succeeding</quote> to <quote>failing</quote>.</para> 23.838 - 23.839 - <para id="x_13e">To start the search, we must run the <command 23.840 - role="hg-cmd">hg bisect --reset</command> command.</para> 23.841 - 23.842 - &interaction.bisect.search.init; 23.843 - 23.844 - <para id="x_13f">In our case, the binary test we use is simple: we check to 23.845 - see if any file in the repository contains the string <quote>i 23.846 - have a gub</quote>. If it does, this changeset contains the 23.847 - change that <quote>caused the bug</quote>. By convention, a 23.848 - changeset that has the property we're searching for is 23.849 - <quote>bad</quote>, while one that doesn't is 23.850 - <quote>good</quote>.</para> 23.851 - 23.852 - <para id="x_140">Most of the time, the revision to which the working 23.853 - directory is synced (usually the tip) already exhibits the 23.854 - problem introduced by the buggy change, so we'll mark it as 23.855 - <quote>bad</quote>.</para> 23.856 - 23.857 - &interaction.bisect.search.bad-init; 23.858 - 23.859 - <para id="x_141">Our next task is to nominate a changeset that we know 23.860 - <emphasis>doesn't</emphasis> have the bug; the <command 23.861 - role="hg-cmd">hg bisect</command> command will 23.862 - <quote>bracket</quote> its search between the first pair of 23.863 - good and bad changesets. In our case, we know that revision 23.864 - 10 didn't have the bug. (I'll have more words about choosing 23.865 - the first <quote>good</quote> changeset later.)</para> 23.866 - 23.867 - &interaction.bisect.search.good-init; 23.868 - 23.869 - <para id="x_142">Notice that this command printed some output.</para> 23.870 - <itemizedlist> 23.871 - <listitem><para id="x_143">It told us how many changesets it must 23.872 - consider before it can identify the one that introduced 23.873 - the bug, and how many tests that will require.</para> 23.874 - </listitem> 23.875 - <listitem><para id="x_144">It updated the working directory to the next 23.876 - changeset to test, and told us which changeset it's 23.877 - testing.</para> 23.878 - </listitem></itemizedlist> 23.879 - 23.880 - <para id="x_145">We now run our test in the working directory. We use the 23.881 - <command>grep</command> command to see if our 23.882 - <quote>bad</quote> file is present in the working directory. 23.883 - If it is, this revision is bad; if not, this revision is good. 23.884 - &interaction.bisect.search.step1;</para> 23.885 - 23.886 - <para id="x_146">This test looks like a perfect candidate for automation, 23.887 - so let's turn it into a shell function.</para> 23.888 - &interaction.bisect.search.mytest; 23.889 - 23.890 - <para id="x_147">We can now run an entire test step with a single command, 23.891 - <literal>mytest</literal>.</para> 23.892 - 23.893 - &interaction.bisect.search.step2; 23.894 - 23.895 - <para id="x_148">A few more invocations of our canned test step command, 23.896 - and we're done.</para> 23.897 - 23.898 - &interaction.bisect.search.rest; 23.899 - 23.900 - <para id="x_149">Even though we had 40 changesets to search through, the 23.901 - <command role="hg-cmd">hg bisect</command> command let us find 23.902 - the changeset that introduced our <quote>bug</quote> with only 23.903 - five tests. Because the number of tests that the <command 23.904 - role="hg-cmd">hg bisect</command> command performs grows 23.905 - logarithmically with the number of changesets to search, the 23.906 - advantage that it has over the <quote>brute force</quote> 23.907 - search approach increases with every changeset you add.</para> 23.908 - 23.909 - </sect2> 23.910 - <sect2> 23.911 - <title>Cleaning up after your search</title> 23.912 - 23.913 - <para id="x_14a">When you're finished using the <command role="hg-cmd">hg 23.914 - bisect</command> command in a repository, you can use the 23.915 - <command role="hg-cmd">hg bisect reset</command> command to 23.916 - drop the information it was using to drive your search. The 23.917 - command doesn't use much space, so it doesn't matter if you 23.918 - forget to run this command. However, <command 23.919 - role="hg-cmd">hg bisect</command> won't let you start a new 23.920 - search in that repository until you do a <command 23.921 - role="hg-cmd">hg bisect reset</command>.</para> 23.922 - 23.923 - &interaction.bisect.search.reset; 23.924 - 23.925 - </sect2> 23.926 - </sect1> 23.927 - <sect1> 23.928 - <title>Tips for finding bugs effectively</title> 23.929 - 23.930 - <sect2> 23.931 - <title>Give consistent input</title> 23.932 - 23.933 - <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command 23.934 - requires that you correctly report the result of every test 23.935 - you perform. If you tell it that a test failed when it really 23.936 - succeeded, it <emphasis>might</emphasis> be able to detect the 23.937 - inconsistency. If it can identify an inconsistency in your 23.938 - reports, it will tell you that a particular changeset is both 23.939 - good and bad. However, it can't do this perfectly; it's about 23.940 - as likely to report the wrong changeset as the source of the 23.941 - bug.</para> 23.942 - 23.943 - </sect2> 23.944 - <sect2> 23.945 - <title>Automate as much as possible</title> 23.946 - 23.947 - <para id="x_14c">When I started using the <command role="hg-cmd">hg 23.948 - bisect</command> command, I tried a few times to run my 23.949 - tests by hand, on the command line. This is an approach that 23.950 - I, at least, am not suited to. After a few tries, I found 23.951 - that I was making enough mistakes that I was having to restart 23.952 - my searches several times before finally getting correct 23.953 - results.</para> 23.954 - 23.955 - <para id="x_14d">My initial problems with driving the <command 23.956 - role="hg-cmd">hg bisect</command> command by hand occurred 23.957 - even with simple searches on small repositories; if the 23.958 - problem you're looking for is more subtle, or the number of 23.959 - tests that <command role="hg-cmd">hg bisect</command> must 23.960 - perform increases, the likelihood of operator error ruining 23.961 - the search is much higher. Once I started automating my 23.962 - tests, I had much better results.</para> 23.963 - 23.964 - <para id="x_14e">The key to automated testing is twofold:</para> 23.965 - <itemizedlist> 23.966 - <listitem><para id="x_14f">always test for the same symptom, and</para> 23.967 - </listitem> 23.968 - <listitem><para id="x_150">always feed consistent input to the <command 23.969 - role="hg-cmd">hg bisect</command> command.</para> 23.970 - </listitem></itemizedlist> 23.971 - <para id="x_151">In my tutorial example above, the <command>grep</command> 23.972 - command tests for the symptom, and the <literal>if</literal> 23.973 - statement takes the result of this check and ensures that we 23.974 - always feed the same input to the <command role="hg-cmd">hg 23.975 - bisect</command> command. The <literal>mytest</literal> 23.976 - function marries these together in a reproducible way, so that 23.977 - every test is uniform and consistent.</para> 23.978 - 23.979 - </sect2> 23.980 - <sect2> 23.981 - <title>Check your results</title> 23.982 - 23.983 - <para id="x_152">Because the output of a <command role="hg-cmd">hg 23.984 - bisect</command> search is only as good as the input you 23.985 - give it, don't take the changeset it reports as the absolute 23.986 - truth. A simple way to cross-check its report is to manually 23.987 - run your test at each of the following changesets:</para> 23.988 - <itemizedlist> 23.989 - <listitem><para id="x_153">The changeset that it reports as the first bad 23.990 - revision. Your test should still report this as 23.991 - bad.</para> 23.992 - </listitem> 23.993 - <listitem><para id="x_154">The parent of that changeset (either parent, 23.994 - if it's a merge). Your test should report this changeset 23.995 - as good.</para> 23.996 - </listitem> 23.997 - <listitem><para id="x_155">A child of that changeset. Your test should 23.998 - report this changeset as bad.</para> 23.999 - </listitem></itemizedlist> 23.1000 - 23.1001 - </sect2> 23.1002 - <sect2> 23.1003 - <title>Beware interference between bugs</title> 23.1004 - 23.1005 - <para id="x_156">It's possible that your search for one bug could be 23.1006 - disrupted by the presence of another. For example, let's say 23.1007 - your software crashes at revision 100, and worked correctly at 23.1008 - revision 50. Unknown to you, someone else introduced a 23.1009 - different crashing bug at revision 60, and fixed it at 23.1010 - revision 80. This could distort your results in one of 23.1011 - several ways.</para> 23.1012 - 23.1013 - <para id="x_157">It is possible that this other bug completely 23.1014 - <quote>masks</quote> yours, which is to say that it occurs 23.1015 - before your bug has a chance to manifest itself. If you can't 23.1016 - avoid that other bug (for example, it prevents your project 23.1017 - from building), and so can't tell whether your bug is present 23.1018 - in a particular changeset, the <command role="hg-cmd">hg 23.1019 - bisect</command> command cannot help you directly. Instead, 23.1020 - you can mark a changeset as untested by running <command 23.1021 - role="hg-cmd">hg bisect --skip</command>.</para> 23.1022 - 23.1023 - <para id="x_158">A different problem could arise if your test for a bug's 23.1024 - presence is not specific enough. If you check for <quote>my 23.1025 - program crashes</quote>, then both your crashing bug and an 23.1026 - unrelated crashing bug that masks it will look like the same 23.1027 - thing, and mislead <command role="hg-cmd">hg 23.1028 - bisect</command>.</para> 23.1029 - 23.1030 - <para id="x_159">Another useful situation in which to use <command 23.1031 - role="hg-cmd">hg bisect --skip</command> is if you can't 23.1032 - test a revision because your project was in a broken and hence 23.1033 - untestable state at that revision, perhaps because someone 23.1034 - checked in a change that prevented the project from 23.1035 - building.</para> 23.1036 - 23.1037 - </sect2> 23.1038 - <sect2> 23.1039 - <title>Bracket your search lazily</title> 23.1040 - 23.1041 - <para id="x_15a">Choosing the first <quote>good</quote> and 23.1042 - <quote>bad</quote> changesets that will mark the end points of 23.1043 - your search is often easy, but it bears a little discussion 23.1044 - nevertheless. From the perspective of <command 23.1045 - role="hg-cmd">hg bisect</command>, the <quote>newest</quote> 23.1046 - changeset is conventionally <quote>bad</quote>, and the older 23.1047 - changeset is <quote>good</quote>.</para> 23.1048 - 23.1049 - <para id="x_15b">If you're having trouble remembering when a suitable 23.1050 - <quote>good</quote> change was, so that you can tell <command 23.1051 - role="hg-cmd">hg bisect</command>, you could do worse than 23.1052 - testing changesets at random. Just remember to eliminate 23.1053 - contenders that can't possibly exhibit the bug (perhaps 23.1054 - because the feature with the bug isn't present yet) and those 23.1055 - where another problem masks the bug (as I discussed 23.1056 - above).</para> 23.1057 - 23.1058 - <para id="x_15c">Even if you end up <quote>early</quote> by thousands of 23.1059 - changesets or months of history, you will only add a handful 23.1060 - of tests to the total number that <command role="hg-cmd">hg 23.1061 - bisect</command> must perform, thanks to its logarithmic 23.1062 - behavior.</para> 23.1063 - 23.1064 - </sect2> 23.1065 - </sect1> 23.1066 -</chapter> 23.1067 - 23.1068 -<!-- 23.1069 -local variables: 23.1070 -sgml-parent-document: ("00book.xml" "book" "chapter") 23.1071 -end: 23.1072 --->
24.1 --- a/en/ch09-hook.xml Sat Apr 18 11:52:33 2009 +0800 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,2038 +0,0 @@ 24.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 24.5 - 24.6 -<chapter id="chap:hook"> 24.7 - <?dbhtml filename="handling-repository-events-with-hooks.html"?> 24.8 - <title>Handling repository events with hooks</title> 24.9 - 24.10 - <para id="x_1e6">Mercurial offers a powerful mechanism to let you perform 24.11 - automated actions in response to events that occur in a 24.12 - repository. In some cases, you can even control Mercurial's 24.13 - response to those events.</para> 24.14 - 24.15 - <para id="x_1e7">The name Mercurial uses for one of these actions is a 24.16 - <emphasis>hook</emphasis>. Hooks are called 24.17 - <quote>triggers</quote> in some revision control systems, but the 24.18 - two names refer to the same idea.</para> 24.19 - 24.20 - <sect1> 24.21 - <title>An overview of hooks in Mercurial</title> 24.22 - 24.23 - <para id="x_1e8">Here is a brief list of the hooks that Mercurial 24.24 - supports. We will revisit each of these hooks in more detail 24.25 - later, in <xref linkend="sec:hook:ref"/>.</para> 24.26 - 24.27 - <itemizedlist> 24.28 - <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: This 24.29 - is run after a group of changesets has been brought into the 24.30 - repository from elsewhere.</para> 24.31 - </listitem> 24.32 - <listitem><para id="x_1ea"><literal role="hook">commit</literal>: This is 24.33 - run after a new changeset has been created in the local 24.34 - repository.</para> 24.35 - </listitem> 24.36 - <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: This is 24.37 - run once for each new changeset that is brought into the 24.38 - repository from elsewhere. Notice the difference from 24.39 - <literal role="hook">changegroup</literal>, which is run 24.40 - once per <emphasis>group</emphasis> of changesets brought 24.41 - in.</para> 24.42 - </listitem> 24.43 - <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: This is 24.44 - run after a group of changesets has been transmitted from 24.45 - this repository.</para> 24.46 - </listitem> 24.47 - <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>: 24.48 - This is run before starting to bring a group of changesets 24.49 - into the repository. 24.50 - </para> 24.51 - </listitem> 24.52 - <listitem><para id="x_1ee"><literal role="hook">precommit</literal>: 24.53 - Controlling. This is run before starting a commit. 24.54 - </para> 24.55 - </listitem> 24.56 - <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>: 24.57 - Controlling. This is run before starting to transmit a group 24.58 - of changesets from this repository. 24.59 - </para> 24.60 - </listitem> 24.61 - <listitem><para id="x_1f0"><literal role="hook">pretag</literal>: 24.62 - Controlling. This is run before creating a tag. 24.63 - </para> 24.64 - </listitem> 24.65 - <listitem><para id="x_1f1"><literal 24.66 - role="hook">pretxnchangegroup</literal>: Controlling. This 24.67 - is run after a group of changesets has been brought into the 24.68 - local repository from another, but before the transaction 24.69 - completes that will make the changes permanent in the 24.70 - repository. 24.71 - </para> 24.72 - </listitem> 24.73 - <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>: 24.74 - Controlling. This is run after a new changeset has been 24.75 - created in the local repository, but before the transaction 24.76 - completes that will make it permanent. 24.77 - </para> 24.78 - </listitem> 24.79 - <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>: 24.80 - Controlling. This is run before starting an update or merge 24.81 - of the working directory. 24.82 - </para> 24.83 - </listitem> 24.84 - <listitem><para id="x_1f4"><literal role="hook">tag</literal>: This is run 24.85 - after a tag is created. 24.86 - </para> 24.87 - </listitem> 24.88 - <listitem><para id="x_1f5"><literal role="hook">update</literal>: This is 24.89 - run after an update or merge of the working directory has 24.90 - finished. 24.91 - </para> 24.92 - </listitem></itemizedlist> 24.93 - <para id="x_1f6">Each of the hooks whose description begins with the word 24.94 - <quote>Controlling</quote> has the ability to determine whether 24.95 - an activity can proceed. If the hook succeeds, the activity may 24.96 - proceed; if it fails, the activity is either not permitted or 24.97 - undone, depending on the hook. 24.98 - </para> 24.99 - 24.100 - </sect1> 24.101 - <sect1> 24.102 - <title>Hooks and security</title> 24.103 - 24.104 - <sect2> 24.105 - <title>Hooks are run with your privileges</title> 24.106 - 24.107 - <para id="x_1f7">When you run a Mercurial command in a repository, and the 24.108 - command causes a hook to run, that hook runs on 24.109 - <emphasis>your</emphasis> system, under 24.110 - <emphasis>your</emphasis> user account, with 24.111 - <emphasis>your</emphasis> privilege level. Since hooks are 24.112 - arbitrary pieces of executable code, you should treat them 24.113 - with an appropriate level of suspicion. Do not install a hook 24.114 - unless you are confident that you know who created it and what 24.115 - it does. 24.116 - </para> 24.117 - 24.118 - <para id="x_1f8">In some cases, you may be exposed to hooks that you did 24.119 - not install yourself. If you work with Mercurial on an 24.120 - unfamiliar system, Mercurial will run hooks defined in that 24.121 - system's global <filename role="special">~/.hgrc</filename> 24.122 - file. 24.123 - </para> 24.124 - 24.125 - <para id="x_1f9">If you are working with a repository owned by another 24.126 - user, Mercurial can run hooks defined in that user's 24.127 - repository, but it will still run them as <quote>you</quote>. 24.128 - For example, if you <command role="hg-cmd">hg pull</command> 24.129 - from that repository, and its <filename 24.130 - role="special">.hg/hgrc</filename> defines a local <literal 24.131 - role="hook">outgoing</literal> hook, that hook will run 24.132 - under your user account, even though you don't own that 24.133 - repository. 24.134 - </para> 24.135 - 24.136 - <note> 24.137 - <para id="x_1fa"> This only applies if you are pulling from a repository 24.138 - on a local or network filesystem. If you're pulling over 24.139 - http or ssh, any <literal role="hook">outgoing</literal> 24.140 - hook will run under whatever account is executing the server 24.141 - process, on the server. 24.142 - </para> 24.143 - </note> 24.144 - 24.145 - <para id="x_1fb">XXX To see what hooks are defined in a repository, use the 24.146 - <command role="hg-cmd">hg config hooks</command> command. If 24.147 - you are working in one repository, but talking to another that 24.148 - you do not own (e.g. using <command role="hg-cmd">hg 24.149 - pull</command> or <command role="hg-cmd">hg 24.150 - incoming</command>), remember that it is the other 24.151 - repository's hooks you should be checking, not your own. 24.152 - </para> 24.153 - 24.154 - </sect2> 24.155 - <sect2> 24.156 - <title>Hooks do not propagate</title> 24.157 - 24.158 - <para id="x_1fc">In Mercurial, hooks are not revision controlled, and do 24.159 - not propagate when you clone, or pull from, a repository. The 24.160 - reason for this is simple: a hook is a completely arbitrary 24.161 - piece of executable code. It runs under your user identity, 24.162 - with your privilege level, on your machine. 24.163 - </para> 24.164 - 24.165 - <para id="x_1fd">It would be extremely reckless for any distributed 24.166 - revision control system to implement revision-controlled 24.167 - hooks, as this would offer an easily exploitable way to 24.168 - subvert the accounts of users of the revision control system. 24.169 - </para> 24.170 - 24.171 - <para id="x_1fe">Since Mercurial does not propagate hooks, if you are 24.172 - collaborating with other people on a common project, you 24.173 - should not assume that they are using the same Mercurial hooks 24.174 - as you are, or that theirs are correctly configured. You 24.175 - should document the hooks you expect people to use. 24.176 - </para> 24.177 - 24.178 - <para id="x_1ff">In a corporate intranet, this is somewhat easier to 24.179 - control, as you can for example provide a 24.180 - <quote>standard</quote> installation of Mercurial on an NFS 24.181 - filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will 24.182 - see. However, this too has its limits; see below. 24.183 - </para> 24.184 - 24.185 - </sect2> 24.186 - <sect2> 24.187 - <title>Hooks can be overridden</title> 24.188 - 24.189 - <para id="x_200">Mercurial allows you to override a hook definition by 24.190 - redefining the hook. You can disable it by setting its value 24.191 - to the empty string, or change its behavior as you wish. 24.192 - </para> 24.193 - 24.194 - <para id="x_201">If you deploy a system- or site-wide <filename 24.195 - role="special">~/.hgrc</filename> file that defines some 24.196 - hooks, you should thus understand that your users can disable 24.197 - or override those hooks. 24.198 - </para> 24.199 - 24.200 - </sect2> 24.201 - <sect2> 24.202 - <title>Ensuring that critical hooks are run</title> 24.203 - 24.204 - <para id="x_202">Sometimes you may want to enforce a policy that you do not 24.205 - want others to be able to work around. For example, you may 24.206 - have a requirement that every changeset must pass a rigorous 24.207 - set of tests. Defining this requirement via a hook in a 24.208 - site-wide <filename role="special">~/.hgrc</filename> won't 24.209 - work for remote users on laptops, and of course local users 24.210 - can subvert it at will by overriding the hook. 24.211 - </para> 24.212 - 24.213 - <para id="x_203">Instead, you can set up your policies for use of Mercurial 24.214 - so that people are expected to propagate changes through a 24.215 - well-known <quote>canonical</quote> server that you have 24.216 - locked down and configured appropriately. 24.217 - </para> 24.218 - 24.219 - <para id="x_204">One way to do this is via a combination of social 24.220 - engineering and technology. Set up a restricted-access 24.221 - account; users can push changes over the network to 24.222 - repositories managed by this account, but they cannot log into 24.223 - the account and run normal shell commands. In this scenario, 24.224 - a user can commit a changeset that contains any old garbage 24.225 - they want. 24.226 - </para> 24.227 - 24.228 - <para id="x_205">When someone pushes a changeset to the server that 24.229 - everyone pulls from, the server will test the changeset before 24.230 - it accepts it as permanent, and reject it if it fails to pass 24.231 - the test suite. If people only pull changes from this 24.232 - filtering server, it will serve to ensure that all changes 24.233 - that people pull have been automatically vetted. 24.234 - </para> 24.235 - 24.236 - </sect2> 24.237 - </sect1> 24.238 - <sect1> 24.239 - <title>Care with <literal>pretxn</literal> hooks in a 24.240 - shared-access repository</title> 24.241 - 24.242 - <para id="x_206">If you want to use hooks to do some automated work in a 24.243 - repository that a number of people have shared access to, you 24.244 - need to be careful in how you do this. 24.245 - </para> 24.246 - 24.247 - <para id="x_207">Mercurial only locks a repository when it is writing to the 24.248 - repository, and only the parts of Mercurial that write to the 24.249 - repository pay attention to locks. Write locks are necessary to 24.250 - prevent multiple simultaneous writers from scribbling on each 24.251 - other's work, corrupting the repository. 24.252 - </para> 24.253 - 24.254 - <para id="x_208">Because Mercurial is careful with the order in which it 24.255 - reads and writes data, it does not need to acquire a lock when 24.256 - it wants to read data from the repository. The parts of 24.257 - Mercurial that read from the repository never pay attention to 24.258 - locks. This lockless reading scheme greatly increases 24.259 - performance and concurrency. 24.260 - </para> 24.261 - 24.262 - <para id="x_209">With great performance comes a trade-off, though, one which 24.263 - has the potential to cause you trouble unless you're aware of 24.264 - it. To describe this requires a little detail about how 24.265 - Mercurial adds changesets to a repository and reads those 24.266 - changes. 24.267 - </para> 24.268 - 24.269 - <para id="x_20a">When Mercurial <emphasis>writes</emphasis> metadata, it 24.270 - writes it straight into the destination file. It writes file 24.271 - data first, then manifest data (which contains pointers to the 24.272 - new file data), then changelog data (which contains pointers to 24.273 - the new manifest data). Before the first write to each file, it 24.274 - stores a record of where the end of the file was in its 24.275 - transaction log. If the transaction must be rolled back, 24.276 - Mercurial simply truncates each file back to the size it was 24.277 - before the transaction began. 24.278 - </para> 24.279 - 24.280 - <para id="x_20b">When Mercurial <emphasis>reads</emphasis> metadata, it reads 24.281 - the changelog first, then everything else. Since a reader will 24.282 - only access parts of the manifest or file metadata that it can 24.283 - see in the changelog, it can never see partially written data. 24.284 - </para> 24.285 - 24.286 - <para id="x_20c">Some controlling hooks (<literal 24.287 - role="hook">pretxncommit</literal> and <literal 24.288 - role="hook">pretxnchangegroup</literal>) run when a 24.289 - transaction is almost complete. All of the metadata has been 24.290 - written, but Mercurial can still roll the transaction back and 24.291 - cause the newly-written data to disappear. 24.292 - </para> 24.293 - 24.294 - <para id="x_20d">If one of these hooks runs for long, it opens a window of 24.295 - time during which a reader can see the metadata for changesets 24.296 - that are not yet permanent, and should not be thought of as 24.297 - <quote>really there</quote>. The longer the hook runs, the 24.298 - longer that window is open. 24.299 - </para> 24.300 - 24.301 - <sect2> 24.302 - <title>The problem illustrated</title> 24.303 - 24.304 - <para id="x_20e">In principle, a good use for the <literal 24.305 - role="hook">pretxnchangegroup</literal> hook would be to 24.306 - automatically build and test incoming changes before they are 24.307 - accepted into a central repository. This could let you 24.308 - guarantee that nobody can push changes to this repository that 24.309 - <quote>break the build</quote>. But if a client can pull 24.310 - changes while they're being tested, the usefulness of the test 24.311 - is zero; an unsuspecting someone can pull untested changes, 24.312 - potentially breaking their build. 24.313 - </para> 24.314 - 24.315 - <para id="x_20f">The safest technological answer to this challenge is to 24.316 - set up such a <quote>gatekeeper</quote> repository as 24.317 - <emphasis>unidirectional</emphasis>. Let it take changes 24.318 - pushed in from the outside, but do not allow anyone to pull 24.319 - changes from it (use the <literal 24.320 - role="hook">preoutgoing</literal> hook to lock it down). 24.321 - Configure a <literal role="hook">changegroup</literal> hook so 24.322 - that if a build or test succeeds, the hook will push the new 24.323 - changes out to another repository that people 24.324 - <emphasis>can</emphasis> pull from. 24.325 - </para> 24.326 - 24.327 - <para id="x_210">In practice, putting a centralised bottleneck like this in 24.328 - place is not often a good idea, and transaction visibility has 24.329 - nothing to do with the problem. As the size of a 24.330 - project&emdash;and the time it takes to build and 24.331 - test&emdash;grows, you rapidly run into a wall with this 24.332 - <quote>try before you buy</quote> approach, where you have 24.333 - more changesets to test than time in which to deal with them. 24.334 - The inevitable result is frustration on the part of all 24.335 - involved. 24.336 - </para> 24.337 - 24.338 - <para id="x_211">An approach that scales better is to get people to build 24.339 - and test before they push, then run automated builds and tests 24.340 - centrally <emphasis>after</emphasis> a push, to be sure all is 24.341 - well. The advantage of this approach is that it does not 24.342 - impose a limit on the rate at which the repository can accept 24.343 - changes. 24.344 - </para> 24.345 - 24.346 - </sect2> 24.347 - </sect1> 24.348 - <sect1 id="sec:hook:simple"> 24.349 - <title>A short tutorial on using hooks</title> 24.350 - 24.351 - <para id="x_212">It is easy to write a Mercurial hook. Let's start with a 24.352 - hook that runs when you finish a <command role="hg-cmd">hg 24.353 - commit</command>, and simply prints the hash of the changeset 24.354 - you just created. The hook is called <literal 24.355 - role="hook">commit</literal>. 24.356 - </para> 24.357 - 24.358 - <para id="x_213">All hooks follow the pattern in this example.</para> 24.359 - 24.360 -&interaction.hook.simple.init; 24.361 - 24.362 - <para id="x_214">You add an entry to the <literal 24.363 - role="rc-hooks">hooks</literal> section of your <filename 24.364 - role="special">~/.hgrc</filename>. On the left is the name of 24.365 - the event to trigger on; on the right is the action to take. As 24.366 - you can see, you can run an arbitrary shell command in a hook. 24.367 - Mercurial passes extra information to the hook using environment 24.368 - variables (look for <envar>HG_NODE</envar> in the example). 24.369 - </para> 24.370 - 24.371 - <sect2> 24.372 - <title>Performing multiple actions per event</title> 24.373 - 24.374 - <para id="x_215">Quite often, you will want to define more than one hook 24.375 - for a particular kind of event, as shown below.</para> 24.376 - 24.377 -&interaction.hook.simple.ext; 24.378 - 24.379 - <para id="x_216">Mercurial lets you do this by adding an 24.380 - <emphasis>extension</emphasis> to the end of a hook's name. 24.381 - You extend a hook's name by giving the name of the hook, 24.382 - followed by a full stop (the 24.383 - <quote><literal>.</literal></quote> character), followed by 24.384 - some more text of your choosing. For example, Mercurial will 24.385 - run both <literal>commit.foo</literal> and 24.386 - <literal>commit.bar</literal> when the 24.387 - <literal>commit</literal> event occurs. 24.388 - </para> 24.389 - 24.390 - <para id="x_217">To give a well-defined order of execution when there are 24.391 - multiple hooks defined for an event, Mercurial sorts hooks by 24.392 - extension, and executes the hook commands in this sorted 24.393 - order. In the above example, it will execute 24.394 - <literal>commit.bar</literal> before 24.395 - <literal>commit.foo</literal>, and <literal>commit</literal> 24.396 - before both. 24.397 - </para> 24.398 - 24.399 - <para id="x_218">It is a good idea to use a somewhat descriptive 24.400 - extension when you define a new hook. This will help you to 24.401 - remember what the hook was for. If the hook fails, you'll get 24.402 - an error message that contains the hook name and extension, so 24.403 - using a descriptive extension could give you an immediate hint 24.404 - as to why the hook failed (see <xref 24.405 - linkend="sec:hook:perm"/> for an example). 24.406 - </para> 24.407 - 24.408 - </sect2> 24.409 - <sect2 id="sec:hook:perm"> 24.410 - <title>Controlling whether an activity can proceed</title> 24.411 - 24.412 - <para id="x_219">In our earlier examples, we used the <literal 24.413 - role="hook">commit</literal> hook, which is run after a 24.414 - commit has completed. This is one of several Mercurial hooks 24.415 - that run after an activity finishes. Such hooks have no way 24.416 - of influencing the activity itself. 24.417 - </para> 24.418 - 24.419 - <para id="x_21a">Mercurial defines a number of events that occur before an 24.420 - activity starts; or after it starts, but before it finishes. 24.421 - Hooks that trigger on these events have the added ability to 24.422 - choose whether the activity can continue, or will abort. 24.423 - </para> 24.424 - 24.425 - <para id="x_21b">The <literal role="hook">pretxncommit</literal> hook runs 24.426 - after a commit has all but completed. In other words, the 24.427 - metadata representing the changeset has been written out to 24.428 - disk, but the transaction has not yet been allowed to 24.429 - complete. The <literal role="hook">pretxncommit</literal> 24.430 - hook has the ability to decide whether the transaction can 24.431 - complete, or must be rolled back. 24.432 - </para> 24.433 - 24.434 - <para id="x_21c">If the <literal role="hook">pretxncommit</literal> hook 24.435 - exits with a status code of zero, the transaction is allowed 24.436 - to complete; the commit finishes; and the <literal 24.437 - role="hook">commit</literal> hook is run. If the <literal 24.438 - role="hook">pretxncommit</literal> hook exits with a 24.439 - non-zero status code, the transaction is rolled back; the 24.440 - metadata representing the changeset is erased; and the 24.441 - <literal role="hook">commit</literal> hook is not run. 24.442 - </para> 24.443 - 24.444 -&interaction.hook.simple.pretxncommit; 24.445 - 24.446 - <para id="x_21d">The hook in the example above checks that a commit comment 24.447 - contains a bug ID. If it does, the commit can complete. If 24.448 - not, the commit is rolled back. 24.449 - </para> 24.450 - 24.451 - </sect2> 24.452 - </sect1> 24.453 - <sect1> 24.454 - <title>Writing your own hooks</title> 24.455 - 24.456 - <para id="x_21e">When you are writing a hook, you might find it useful to run 24.457 - Mercurial either with the <option 24.458 - role="hg-opt-global">-v</option> option, or the <envar 24.459 - role="rc-item-ui">verbose</envar> config item set to 24.460 - <quote>true</quote>. When you do so, Mercurial will print a 24.461 - message before it calls each hook. 24.462 - </para> 24.463 - 24.464 - <sect2 id="sec:hook:lang"> 24.465 - <title>Choosing how your hook should run</title> 24.466 - 24.467 - <para id="x_21f">You can write a hook either as a normal 24.468 - program&emdash;typically a shell script&emdash;or as a Python 24.469 - function that is executed within the Mercurial process. 24.470 - </para> 24.471 - 24.472 - <para id="x_220">Writing a hook as an external program has the advantage 24.473 - that it requires no knowledge of Mercurial's internals. You 24.474 - can call normal Mercurial commands to get any added 24.475 - information you need. The trade-off is that external hooks 24.476 - are slower than in-process hooks. 24.477 - </para> 24.478 - 24.479 - <para id="x_221">An in-process Python hook has complete access to the 24.480 - Mercurial API, and does not <quote>shell out</quote> to 24.481 - another process, so it is inherently faster than an external 24.482 - hook. It is also easier to obtain much of the information 24.483 - that a hook requires by using the Mercurial API than by 24.484 - running Mercurial commands. 24.485 - </para> 24.486 - 24.487 - <para id="x_222">If you are comfortable with Python, or require high 24.488 - performance, writing your hooks in Python may be a good 24.489 - choice. However, when you have a straightforward hook to 24.490 - write and you don't need to care about performance (probably 24.491 - the majority of hooks), a shell script is perfectly fine. 24.492 - </para> 24.493 - 24.494 - </sect2> 24.495 - <sect2 id="sec:hook:param"> 24.496 - <title>Hook parameters</title> 24.497 - 24.498 - <para id="x_223">Mercurial calls each hook with a set of well-defined 24.499 - parameters. In Python, a parameter is passed as a keyword 24.500 - argument to your hook function. For an external program, a 24.501 - parameter is passed as an environment variable. 24.502 - </para> 24.503 - 24.504 - <para id="x_224">Whether your hook is written in Python or as a shell 24.505 - script, the hook-specific parameter names and values will be 24.506 - the same. A boolean parameter will be represented as a 24.507 - boolean value in Python, but as the number 1 (for 24.508 - <quote>true</quote>) or 0 (for <quote>false</quote>) as an 24.509 - environment variable for an external hook. If a hook 24.510 - parameter is named <literal>foo</literal>, the keyword 24.511 - argument for a Python hook will also be named 24.512 - <literal>foo</literal>, while the environment variable for an 24.513 - external hook will be named <literal>HG_FOO</literal>. 24.514 - </para> 24.515 - 24.516 - </sect2> 24.517 - <sect2> 24.518 - <title>Hook return values and activity control</title> 24.519 - 24.520 - <para id="x_225">A hook that executes successfully must exit with a status 24.521 - of zero if external, or return boolean <quote>false</quote> if 24.522 - in-process. Failure is indicated with a non-zero exit status 24.523 - from an external hook, or an in-process hook returning boolean 24.524 - <quote>true</quote>. If an in-process hook raises an 24.525 - exception, the hook is considered to have failed. 24.526 - </para> 24.527 - 24.528 - <para id="x_226">For a hook that controls whether an activity can proceed, 24.529 - zero/false means <quote>allow</quote>, while 24.530 - non-zero/true/exception means <quote>deny</quote>. 24.531 - </para> 24.532 - 24.533 - </sect2> 24.534 - <sect2> 24.535 - <title>Writing an external hook</title> 24.536 - 24.537 - <para id="x_227">When you define an external hook in your <filename 24.538 - role="special">~/.hgrc</filename> and the hook is run, its 24.539 - value is passed to your shell, which interprets it. This 24.540 - means that you can use normal shell constructs in the body of 24.541 - the hook. 24.542 - </para> 24.543 - 24.544 - <para id="x_228">An executable hook is always run with its current 24.545 - directory set to a repository's root directory. 24.546 - </para> 24.547 - 24.548 - <para id="x_229">Each hook parameter is passed in as an environment 24.549 - variable; the name is upper-cased, and prefixed with the 24.550 - string <quote><literal>HG_</literal></quote>. 24.551 - </para> 24.552 - 24.553 - <para id="x_22a">With the exception of hook parameters, Mercurial does not 24.554 - set or modify any environment variables when running a hook. 24.555 - This is useful to remember if you are writing a site-wide hook 24.556 - that may be run by a number of different users with differing 24.557 - environment variables set. In multi-user situations, you 24.558 - should not rely on environment variables being set to the 24.559 - values you have in your environment when testing the hook. 24.560 - </para> 24.561 - 24.562 - </sect2> 24.563 - <sect2> 24.564 - <title>Telling Mercurial to use an in-process hook</title> 24.565 - 24.566 - <para id="x_22b">The <filename role="special">~/.hgrc</filename> syntax 24.567 - for defining an in-process hook is slightly different than for 24.568 - an executable hook. The value of the hook must start with the 24.569 - text <quote><literal>python:</literal></quote>, and continue 24.570 - with the fully-qualified name of a callable object to use as 24.571 - the hook's value. 24.572 - </para> 24.573 - 24.574 - <para id="x_22c">The module in which a hook lives is automatically imported 24.575 - when a hook is run. So long as you have the module name and 24.576 - <envar>PYTHONPATH</envar> right, it should <quote>just 24.577 - work</quote>. 24.578 - </para> 24.579 - 24.580 - <para id="x_22d">The following <filename role="special">~/.hgrc</filename> 24.581 - example snippet illustrates the syntax and meaning of the 24.582 - notions we just described. 24.583 - </para> 24.584 - <programlisting>[hooks] 24.585 -commit.example = python:mymodule.submodule.myhook</programlisting> 24.586 - <para id="x_22e">When Mercurial runs the <literal>commit.example</literal> 24.587 - hook, it imports <literal>mymodule.submodule</literal>, looks 24.588 - for the callable object named <literal>myhook</literal>, and 24.589 - calls it. 24.590 - </para> 24.591 - 24.592 - </sect2> 24.593 - <sect2> 24.594 - <title>Writing an in-process hook</title> 24.595 - 24.596 - <para id="x_22f">The simplest in-process hook does nothing, but illustrates 24.597 - the basic shape of the hook API: 24.598 - </para> 24.599 - <programlisting>def myhook(ui, repo, **kwargs): 24.600 - pass</programlisting> 24.601 - <para id="x_230">The first argument to a Python hook is always a <literal 24.602 - role="py-mod-mercurial.ui">ui</literal> object. The second 24.603 - is a repository object; at the moment, it is always an 24.604 - instance of <literal 24.605 - role="py-mod-mercurial.localrepo">localrepository</literal>. 24.606 - Following these two arguments are other keyword arguments. 24.607 - Which ones are passed in depends on the hook being called, but 24.608 - a hook can ignore arguments it doesn't care about by dropping 24.609 - them into a keyword argument dict, as with 24.610 - <literal>**kwargs</literal> above. 24.611 - </para> 24.612 - 24.613 - </sect2> 24.614 - </sect1> 24.615 - <sect1> 24.616 - <title>Some hook examples</title> 24.617 - 24.618 - <sect2> 24.619 - <title>Writing meaningful commit messages</title> 24.620 - 24.621 - <para id="x_231">It's hard to imagine a useful commit message being very 24.622 - short. The simple <literal role="hook">pretxncommit</literal> 24.623 - hook of the example below will prevent you from committing a 24.624 - changeset with a message that is less than ten bytes long. 24.625 - </para> 24.626 - 24.627 -&interaction.hook.msglen.go; 24.628 - 24.629 - </sect2> 24.630 - <sect2> 24.631 - <title>Checking for trailing whitespace</title> 24.632 - 24.633 - <para id="x_232">An interesting use of a commit-related hook is to help you 24.634 - to write cleaner code. A simple example of <quote>cleaner 24.635 - code</quote> is the dictum that a change should not add any 24.636 - new lines of text that contain <quote>trailing 24.637 - whitespace</quote>. Trailing whitespace is a series of 24.638 - space and tab characters at the end of a line of text. In 24.639 - most cases, trailing whitespace is unnecessary, invisible 24.640 - noise, but it is occasionally problematic, and people often 24.641 - prefer to get rid of it. 24.642 - </para> 24.643 - 24.644 - <para id="x_233">You can use either the <literal 24.645 - role="hook">precommit</literal> or <literal 24.646 - role="hook">pretxncommit</literal> hook to tell whether you 24.647 - have a trailing whitespace problem. If you use the <literal 24.648 - role="hook">precommit</literal> hook, the hook will not know 24.649 - which files you are committing, so it will have to check every 24.650 - modified file in the repository for trailing white space. If 24.651 - you want to commit a change to just the file 24.652 - <filename>foo</filename>, but the file 24.653 - <filename>bar</filename> contains trailing whitespace, doing a 24.654 - check in the <literal role="hook">precommit</literal> hook 24.655 - will prevent you from committing <filename>foo</filename> due 24.656 - to the problem with <filename>bar</filename>. This doesn't 24.657 - seem right. 24.658 - </para> 24.659 - 24.660 - <para id="x_234">Should you choose the <literal 24.661 - role="hook">pretxncommit</literal> hook, the check won't 24.662 - occur until just before the transaction for the commit 24.663 - completes. This will allow you to check for problems only the 24.664 - exact files that are being committed. However, if you entered 24.665 - the commit message interactively and the hook fails, the 24.666 - transaction will roll back; you'll have to re-enter the commit 24.667 - message after you fix the trailing whitespace and run <command 24.668 - role="hg-cmd">hg commit</command> again. 24.669 - </para> 24.670 - 24.671 -&interaction.hook.ws.simple; 24.672 - 24.673 - <para id="x_235">In this example, we introduce a simple <literal 24.674 - role="hook">pretxncommit</literal> hook that checks for 24.675 - trailing whitespace. This hook is short, but not very 24.676 - helpful. It exits with an error status if a change adds a 24.677 - line with trailing whitespace to any file, but does not print 24.678 - any information that might help us to identify the offending 24.679 - file or line. It also has the nice property of not paying 24.680 - attention to unmodified lines; only lines that introduce new 24.681 - trailing whitespace cause problems. 24.682 - </para> 24.683 - 24.684 - <para id="x_236">The above version is much more complex, but also more 24.685 - useful. It parses a unified diff to see if any lines add 24.686 - trailing whitespace, and prints the name of the file and the 24.687 - line number of each such occurrence. Even better, if the 24.688 - change adds trailing whitespace, this hook saves the commit 24.689 - comment and prints the name of the save file before exiting 24.690 - and telling Mercurial to roll the transaction back, so you can 24.691 - use the <option role="hg-opt-commit">-l filename</option> 24.692 - option to <command role="hg-cmd">hg commit</command> to reuse 24.693 - the saved commit message once you've corrected the problem. 24.694 - </para> 24.695 - 24.696 -&interaction.hook.ws.better; 24.697 - 24.698 - <para id="x_237">As a final aside, note in the example above the use of 24.699 - <command>perl</command>'s in-place editing feature to get rid 24.700 - of trailing whitespace from a file. This is concise and 24.701 - useful enough that I will reproduce it here. 24.702 - </para> 24.703 - <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting> 24.704 - 24.705 - </sect2> 24.706 - </sect1> 24.707 - <sect1> 24.708 - <title>Bundled hooks</title> 24.709 - 24.710 - <para id="x_238">Mercurial ships with several bundled hooks. You can find 24.711 - them in the <filename class="directory">hgext</filename> 24.712 - directory of a Mercurial source tree. If you are using a 24.713 - Mercurial binary package, the hooks will be located in the 24.714 - <filename class="directory">hgext</filename> directory of 24.715 - wherever your package installer put Mercurial. 24.716 - </para> 24.717 - 24.718 - <sect2> 24.719 - <title><literal role="hg-ext">acl</literal>&emdash;access 24.720 - control for parts of a repository</title> 24.721 - 24.722 - <para id="x_239">The <literal role="hg-ext">acl</literal> extension lets 24.723 - you control which remote users are allowed to push changesets 24.724 - to a networked server. You can protect any portion of a 24.725 - repository (including the entire repo), so that a specific 24.726 - remote user can push changes that do not affect the protected 24.727 - portion. 24.728 - </para> 24.729 - 24.730 - <para id="x_23a">This extension implements access control based on the 24.731 - identity of the user performing a push, 24.732 - <emphasis>not</emphasis> on who committed the changesets 24.733 - they're pushing. It makes sense to use this hook only if you 24.734 - have a locked-down server environment that authenticates 24.735 - remote users, and you want to be sure that only specific users 24.736 - are allowed to push changes to that server. 24.737 - </para> 24.738 - 24.739 - <sect3> 24.740 - <title>Configuring the <literal role="hook">acl</literal> 24.741 - hook</title> 24.742 - 24.743 - <para id="x_23b">In order to manage incoming changesets, the <literal 24.744 - role="hg-ext">acl</literal> hook must be used as a 24.745 - <literal role="hook">pretxnchangegroup</literal> hook. This 24.746 - lets it see which files are modified by each incoming 24.747 - changeset, and roll back a group of changesets if they 24.748 - modify <quote>forbidden</quote> files. Example: 24.749 - </para> 24.750 - <programlisting>[hooks] 24.751 -pretxnchangegroup.acl = python:hgext.acl.hook</programlisting> 24.752 - 24.753 - <para id="x_23c">The <literal role="hg-ext">acl</literal> extension is 24.754 - configured using three sections. 24.755 - </para> 24.756 - 24.757 - <para id="x_23d">The <literal role="rc-acl">acl</literal> section has 24.758 - only one entry, <envar role="rc-item-acl">sources</envar>, 24.759 - which lists the sources of incoming changesets that the hook 24.760 - should pay attention to. You don't normally need to 24.761 - configure this section. 24.762 - </para> 24.763 - <itemizedlist> 24.764 - <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>: 24.765 - Control incoming changesets that are arriving from a 24.766 - remote repository over http or ssh. This is the default 24.767 - value of <envar role="rc-item-acl">sources</envar>, and 24.768 - usually the only setting you'll need for this 24.769 - configuration item. 24.770 - </para> 24.771 - </listitem> 24.772 - <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>: 24.773 - Control incoming changesets that are arriving via a pull 24.774 - from a local repository. 24.775 - </para> 24.776 - </listitem> 24.777 - <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>: 24.778 - Control incoming changesets that are arriving via a push 24.779 - from a local repository. 24.780 - </para> 24.781 - </listitem> 24.782 - <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>: 24.783 - Control incoming changesets that are arriving from 24.784 - another repository via a bundle. 24.785 - </para> 24.786 - </listitem></itemizedlist> 24.787 - 24.788 - <para id="x_242">The <literal role="rc-acl.allow">acl.allow</literal> 24.789 - section controls the users that are allowed to add 24.790 - changesets to the repository. If this section is not 24.791 - present, all users that are not explicitly denied are 24.792 - allowed. If this section is present, all users that are not 24.793 - explicitly allowed are denied (so an empty section means 24.794 - that all users are denied). 24.795 - </para> 24.796 - 24.797 - <para id="x_243">The <literal role="rc-acl.deny">acl.deny</literal> 24.798 - section determines which users are denied from adding 24.799 - changesets to the repository. If this section is not 24.800 - present or is empty, no users are denied. 24.801 - </para> 24.802 - 24.803 - <para id="x_244">The syntaxes for the <literal 24.804 - role="rc-acl.allow">acl.allow</literal> and <literal 24.805 - role="rc-acl.deny">acl.deny</literal> sections are 24.806 - identical. On the left of each entry is a glob pattern that 24.807 - matches files or directories, relative to the root of the 24.808 - repository; on the right, a user name. 24.809 - </para> 24.810 - 24.811 - <para id="x_245">In the following example, the user 24.812 - <literal>docwriter</literal> can only push changes to the 24.813 - <filename class="directory">docs</filename> subtree of the 24.814 - repository, while <literal>intern</literal> can push changes 24.815 - to any file or directory except <filename 24.816 - class="directory">source/sensitive</filename>. 24.817 - </para> 24.818 - <programlisting>[acl.allow] 24.819 -docs/** = docwriter 24.820 -[acl.deny] 24.821 -source/sensitive/** = intern</programlisting> 24.822 - 24.823 - </sect3> 24.824 - <sect3> 24.825 - <title>Testing and troubleshooting</title> 24.826 - 24.827 - <para id="x_246">If you want to test the <literal 24.828 - role="hg-ext">acl</literal> hook, run it with Mercurial's 24.829 - debugging output enabled. Since you'll probably be running 24.830 - it on a server where it's not convenient (or sometimes 24.831 - possible) to pass in the <option 24.832 - role="hg-opt-global">--debug</option> option, don't forget 24.833 - that you can enable debugging output in your <filename 24.834 - role="special">~/.hgrc</filename>: 24.835 - </para> 24.836 - <programlisting>[ui] 24.837 -debug = true</programlisting> 24.838 - <para id="x_247">With this enabled, the <literal 24.839 - role="hg-ext">acl</literal> hook will print enough 24.840 - information to let you figure out why it is allowing or 24.841 - forbidding pushes from specific users. 24.842 - </para> 24.843 - 24.844 - </sect3> 24.845 - </sect2> 24.846 - <sect2> 24.847 - <title><literal 24.848 - role="hg-ext">bugzilla</literal>&emdash;integration with 24.849 - Bugzilla</title> 24.850 - 24.851 - <para id="x_248">The <literal role="hg-ext">bugzilla</literal> extension 24.852 - adds a comment to a Bugzilla bug whenever it finds a reference 24.853 - to that bug ID in a commit comment. You can install this hook 24.854 - on a shared server, so that any time a remote user pushes 24.855 - changes to this server, the hook gets run. 24.856 - </para> 24.857 - 24.858 - <para id="x_249">It adds a comment to the bug that looks like this (you can 24.859 - configure the contents of the comment&emdash;see below): 24.860 - </para> 24.861 - <programlisting>Changeset aad8b264143a, made by Joe User 24.862 - <joe.user@domain.com> in the frobnitz repository, refers 24.863 - to this bug. For complete details, see 24.864 - http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a 24.865 - Changeset description: Fix bug 10483 by guarding against some 24.866 - NULL pointers</programlisting> 24.867 - <para id="x_24a">The value of this hook is that it automates the process of 24.868 - updating a bug any time a changeset refers to it. If you 24.869 - configure the hook properly, it makes it easy for people to 24.870 - browse straight from a Bugzilla bug to a changeset that refers 24.871 - to that bug. 24.872 - </para> 24.873 - 24.874 - <para id="x_24b">You can use the code in this hook as a starting point for 24.875 - some more exotic Bugzilla integration recipes. Here are a few 24.876 - possibilities: 24.877 - </para> 24.878 - <itemizedlist> 24.879 - <listitem><para id="x_24c">Require that every changeset pushed to the 24.880 - server have a valid bug ID in its commit comment. In this 24.881 - case, you'd want to configure the hook as a <literal 24.882 - role="hook">pretxncommit</literal> hook. This would 24.883 - allow the hook to reject changes that didn't contain bug 24.884 - IDs. 24.885 - </para> 24.886 - </listitem> 24.887 - <listitem><para id="x_24d">Allow incoming changesets to automatically 24.888 - modify the <emphasis>state</emphasis> of a bug, as well as 24.889 - simply adding a comment. For example, the hook could 24.890 - recognise the string <quote>fixed bug 31337</quote> as 24.891 - indicating that it should update the state of bug 31337 to 24.892 - <quote>requires testing</quote>. 24.893 - </para> 24.894 - </listitem></itemizedlist> 24.895 - 24.896 - <sect3 id="sec:hook:bugzilla:config"> 24.897 - <title>Configuring the <literal role="hook">bugzilla</literal> 24.898 - hook</title> 24.899 - 24.900 - <para id="x_24e">You should configure this hook in your server's 24.901 - <filename role="special">~/.hgrc</filename> as an <literal 24.902 - role="hook">incoming</literal> hook, for example as 24.903 - follows: 24.904 - </para> 24.905 - <programlisting>[hooks] 24.906 -incoming.bugzilla = python:hgext.bugzilla.hook</programlisting> 24.907 - 24.908 - <para id="x_24f">Because of the specialised nature of this hook, and 24.909 - because Bugzilla was not written with this kind of 24.910 - integration in mind, configuring this hook is a somewhat 24.911 - involved process. 24.912 - </para> 24.913 - 24.914 - <para id="x_250">Before you begin, you must install the MySQL bindings 24.915 - for Python on the host(s) where you'll be running the hook. 24.916 - If this is not available as a binary package for your 24.917 - system, you can download it from 24.918 - <citation>web:mysql-python</citation>. 24.919 - </para> 24.920 - 24.921 - <para id="x_251">Configuration information for this hook lives in the 24.922 - <literal role="rc-bugzilla">bugzilla</literal> section of 24.923 - your <filename role="special">~/.hgrc</filename>. 24.924 - </para> 24.925 - <itemizedlist> 24.926 - <listitem><para id="x_252"><envar 24.927 - role="rc-item-bugzilla">version</envar>: The version 24.928 - of Bugzilla installed on the server. The database 24.929 - schema that Bugzilla uses changes occasionally, so this 24.930 - hook has to know exactly which schema to use. At the 24.931 - moment, the only version supported is 24.932 - <literal>2.16</literal>. 24.933 - </para> 24.934 - </listitem> 24.935 - <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>: 24.936 - The hostname of the MySQL server that stores your 24.937 - Bugzilla data. The database must be configured to allow 24.938 - connections from whatever host you are running the 24.939 - <literal role="hook">bugzilla</literal> hook on. 24.940 - </para> 24.941 - </listitem> 24.942 - <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>: 24.943 - The username with which to connect to the MySQL server. 24.944 - The database must be configured to allow this user to 24.945 - connect from whatever host you are running the <literal 24.946 - role="hook">bugzilla</literal> hook on. This user 24.947 - must be able to access and modify Bugzilla tables. The 24.948 - default value of this item is <literal>bugs</literal>, 24.949 - which is the standard name of the Bugzilla user in a 24.950 - MySQL database. 24.951 - </para> 24.952 - </listitem> 24.953 - <listitem><para id="x_255"><envar 24.954 - role="rc-item-bugzilla">password</envar>: The MySQL 24.955 - password for the user you configured above. This is 24.956 - stored as plain text, so you should make sure that 24.957 - unauthorised users cannot read the <filename 24.958 - role="special">~/.hgrc</filename> file where you 24.959 - store this information. 24.960 - </para> 24.961 - </listitem> 24.962 - <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>: 24.963 - The name of the Bugzilla database on the MySQL server. 24.964 - The default value of this item is 24.965 - <literal>bugs</literal>, which is the standard name of 24.966 - the MySQL database where Bugzilla stores its data. 24.967 - </para> 24.968 - </listitem> 24.969 - <listitem><para id="x_257"><envar 24.970 - role="rc-item-bugzilla">notify</envar>: If you want 24.971 - Bugzilla to send out a notification email to subscribers 24.972 - after this hook has added a comment to a bug, you will 24.973 - need this hook to run a command whenever it updates the 24.974 - database. The command to run depends on where you have 24.975 - installed Bugzilla, but it will typically look something 24.976 - like this, if you have Bugzilla installed in <filename 24.977 - class="directory">/var/www/html/bugzilla</filename>: 24.978 - </para> 24.979 - <programlisting>cd /var/www/html/bugzilla && 24.980 - ./processmail %s nobody@nowhere.com</programlisting> 24.981 - </listitem> 24.982 - <listitem><para id="x_258"> The Bugzilla 24.983 - <literal>processmail</literal> program expects to be 24.984 - given a bug ID (the hook replaces 24.985 - <quote><literal>%s</literal></quote> with the bug ID) 24.986 - and an email address. It also expects to be able to 24.987 - write to some files in the directory that it runs in. 24.988 - If Bugzilla and this hook are not installed on the same 24.989 - machine, you will need to find a way to run 24.990 - <literal>processmail</literal> on the server where 24.991 - Bugzilla is installed. 24.992 - </para> 24.993 - </listitem></itemizedlist> 24.994 - 24.995 - </sect3> 24.996 - <sect3> 24.997 - <title>Mapping committer names to Bugzilla user names</title> 24.998 - 24.999 - <para id="x_259">By default, the <literal 24.1000 - role="hg-ext">bugzilla</literal> hook tries to use the 24.1001 - email address of a changeset's committer as the Bugzilla 24.1002 - user name with which to update a bug. If this does not suit 24.1003 - your needs, you can map committer email addresses to 24.1004 - Bugzilla user names using a <literal 24.1005 - role="rc-usermap">usermap</literal> section. 24.1006 - </para> 24.1007 - 24.1008 - <para id="x_25a">Each item in the <literal 24.1009 - role="rc-usermap">usermap</literal> section contains an 24.1010 - email address on the left, and a Bugzilla user name on the 24.1011 - right. 24.1012 - </para> 24.1013 - <programlisting>[usermap] 24.1014 -jane.user@example.com = jane</programlisting> 24.1015 - <para id="x_25b">You can either keep the <literal 24.1016 - role="rc-usermap">usermap</literal> data in a normal 24.1017 - <filename role="special">~/.hgrc</filename>, or tell the 24.1018 - <literal role="hg-ext">bugzilla</literal> hook to read the 24.1019 - information from an external <filename>usermap</filename> 24.1020 - file. In the latter case, you can store 24.1021 - <filename>usermap</filename> data by itself in (for example) 24.1022 - a user-modifiable repository. This makes it possible to let 24.1023 - your users maintain their own <envar 24.1024 - role="rc-item-bugzilla">usermap</envar> entries. The main 24.1025 - <filename role="special">~/.hgrc</filename> file might look 24.1026 - like this: 24.1027 - </para> 24.1028 - <programlisting># regular hgrc file refers to external usermap file 24.1029 -[bugzilla] 24.1030 -usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting> 24.1031 - <para id="x_25c">While the <filename>usermap</filename> file that it 24.1032 - refers to might look like this: 24.1033 - </para> 24.1034 - <programlisting># bugzilla-usermap.conf - inside a hg repository 24.1035 -[usermap] stephanie@example.com = steph</programlisting> 24.1036 - 24.1037 - </sect3> 24.1038 - <sect3> 24.1039 - <title>Configuring the text that gets added to a bug</title> 24.1040 - 24.1041 - <para id="x_25d">You can configure the text that this hook adds as a 24.1042 - comment; you specify it in the form of a Mercurial template. 24.1043 - Several <filename role="special">~/.hgrc</filename> entries 24.1044 - (still in the <literal role="rc-bugzilla">bugzilla</literal> 24.1045 - section) control this behavior. 24.1046 - </para> 24.1047 - <itemizedlist> 24.1048 - <listitem><para id="x_25e"><literal>strip</literal>: The number of 24.1049 - leading path elements to strip from a repository's path 24.1050 - name to construct a partial path for a URL. For example, 24.1051 - if the repositories on your server live under <filename 24.1052 - class="directory">/home/hg/repos</filename>, and you 24.1053 - have a repository whose path is <filename 24.1054 - class="directory">/home/hg/repos/app/tests</filename>, 24.1055 - then setting <literal>strip</literal> to 24.1056 - <literal>4</literal> will give a partial path of 24.1057 - <filename class="directory">app/tests</filename>. The 24.1058 - hook will make this partial path available when 24.1059 - expanding a template, as <literal>webroot</literal>. 24.1060 - </para> 24.1061 - </listitem> 24.1062 - <listitem><para id="x_25f"><literal>template</literal>: The text of the 24.1063 - template to use. In addition to the usual 24.1064 - changeset-related variables, this template can use 24.1065 - <literal>hgweb</literal> (the value of the 24.1066 - <literal>hgweb</literal> configuration item above) and 24.1067 - <literal>webroot</literal> (the path constructed using 24.1068 - <literal>strip</literal> above). 24.1069 - </para> 24.1070 - </listitem></itemizedlist> 24.1071 - 24.1072 - <para id="x_260">In addition, you can add a <envar 24.1073 - role="rc-item-web">baseurl</envar> item to the <literal 24.1074 - role="rc-web">web</literal> section of your <filename 24.1075 - role="special">~/.hgrc</filename>. The <literal 24.1076 - role="hg-ext">bugzilla</literal> hook will make this 24.1077 - available when expanding a template, as the base string to 24.1078 - use when constructing a URL that will let users browse from 24.1079 - a Bugzilla comment to view a changeset. Example: 24.1080 - </para> 24.1081 - <programlisting>[web] 24.1082 -baseurl = http://hg.domain.com/</programlisting> 24.1083 - 24.1084 - <para id="x_261">Here is an example set of <literal 24.1085 - role="hg-ext">bugzilla</literal> hook config information. 24.1086 - </para> 24.1087 - 24.1088 - &ch10-bugzilla-config.lst; 24.1089 - 24.1090 - </sect3> 24.1091 - <sect3> 24.1092 - <title>Testing and troubleshooting</title> 24.1093 - 24.1094 - <para id="x_262">The most common problems with configuring the <literal 24.1095 - role="hg-ext">bugzilla</literal> hook relate to running 24.1096 - Bugzilla's <filename>processmail</filename> script and 24.1097 - mapping committer names to user names. 24.1098 - </para> 24.1099 - 24.1100 - <para id="x_263">Recall from <xref 24.1101 - linkend="sec:hook:bugzilla:config"/> above that the user 24.1102 - that runs the Mercurial process on the server is also the 24.1103 - one that will run the <filename>processmail</filename> 24.1104 - script. The <filename>processmail</filename> script 24.1105 - sometimes causes Bugzilla to write to files in its 24.1106 - configuration directory, and Bugzilla's configuration files 24.1107 - are usually owned by the user that your web server runs 24.1108 - under. 24.1109 - </para> 24.1110 - 24.1111 - <para id="x_264">You can cause <filename>processmail</filename> to be run 24.1112 - with the suitable user's identity using the 24.1113 - <command>sudo</command> command. Here is an example entry 24.1114 - for a <filename>sudoers</filename> file. 24.1115 - </para> 24.1116 - <programlisting>hg_user = (httpd_user) 24.1117 -NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting> 24.1118 - <para id="x_265">This allows the <literal>hg_user</literal> user to run a 24.1119 - <filename>processmail-wrapper</filename> program under the 24.1120 - identity of <literal>httpd_user</literal>. 24.1121 - </para> 24.1122 - 24.1123 - <para id="x_266">This indirection through a wrapper script is necessary, 24.1124 - because <filename>processmail</filename> expects to be run 24.1125 - with its current directory set to wherever you installed 24.1126 - Bugzilla; you can't specify that kind of constraint in a 24.1127 - <filename>sudoers</filename> file. The contents of the 24.1128 - wrapper script are simple: 24.1129 - </para> 24.1130 - <programlisting>#!/bin/sh 24.1131 -cd `dirname $0` && ./processmail "$1" nobody@example.com</programlisting> 24.1132 - <para id="x_267">It doesn't seem to matter what email address you pass to 24.1133 - <filename>processmail</filename>. 24.1134 - </para> 24.1135 - 24.1136 - <para id="x_268">If your <literal role="rc-usermap">usermap</literal> is 24.1137 - not set up correctly, users will see an error message from 24.1138 - the <literal role="hg-ext">bugzilla</literal> hook when they 24.1139 - push changes to the server. The error message will look 24.1140 - like this: 24.1141 - </para> 24.1142 - <programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting> 24.1143 - <para id="x_269">What this means is that the committer's address, 24.1144 - <literal>john.q.public@example.com</literal>, is not a valid 24.1145 - Bugzilla user name, nor does it have an entry in your 24.1146 - <literal role="rc-usermap">usermap</literal> that maps it to 24.1147 - a valid Bugzilla user name. 24.1148 - </para> 24.1149 - 24.1150 - </sect3> 24.1151 - </sect2> 24.1152 - <sect2> 24.1153 - <title><literal role="hg-ext">notify</literal>&emdash;send email 24.1154 - notifications</title> 24.1155 - 24.1156 - <para id="x_26a">Although Mercurial's built-in web server provides RSS 24.1157 - feeds of changes in every repository, many people prefer to 24.1158 - receive change notifications via email. The <literal 24.1159 - role="hg-ext">notify</literal> hook lets you send out 24.1160 - notifications to a set of email addresses whenever changesets 24.1161 - arrive that those subscribers are interested in. 24.1162 - </para> 24.1163 - 24.1164 - <para id="x_26b">As with the <literal role="hg-ext">bugzilla</literal> 24.1165 - hook, the <literal role="hg-ext">notify</literal> hook is 24.1166 - template-driven, so you can customise the contents of the 24.1167 - notification messages that it sends. 24.1168 - </para> 24.1169 - 24.1170 - <para id="x_26c">By default, the <literal role="hg-ext">notify</literal> 24.1171 - hook includes a diff of every changeset that it sends out; you 24.1172 - can limit the size of the diff, or turn this feature off 24.1173 - entirely. It is useful for letting subscribers review changes 24.1174 - immediately, rather than clicking to follow a URL. 24.1175 - </para> 24.1176 - 24.1177 - <sect3> 24.1178 - <title>Configuring the <literal role="hg-ext">notify</literal> 24.1179 - hook</title> 24.1180 - 24.1181 - <para id="x_26d">You can set up the <literal 24.1182 - role="hg-ext">notify</literal> hook to send one email 24.1183 - message per incoming changeset, or one per incoming group of 24.1184 - changesets (all those that arrived in a single pull or 24.1185 - push). 24.1186 - </para> 24.1187 - <programlisting>[hooks] 24.1188 -# send one email per group of changes 24.1189 -changegroup.notify = python:hgext.notify.hook 24.1190 -# send one email per change 24.1191 -incoming.notify = python:hgext.notify.hook</programlisting> 24.1192 - 24.1193 - <para id="x_26e">Configuration information for this hook lives in the 24.1194 - <literal role="rc-notify">notify</literal> section of a 24.1195 - <filename role="special">~/.hgrc</filename> file. 24.1196 - </para> 24.1197 - <itemizedlist> 24.1198 - <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>: 24.1199 - By default, this hook does not send out email at all; 24.1200 - instead, it prints the message that it 24.1201 - <emphasis>would</emphasis> send. Set this item to 24.1202 - <literal>false</literal> to allow email to be sent. The 24.1203 - reason that sending of email is turned off by default is 24.1204 - that it takes several tries to configure this extension 24.1205 - exactly as you would like, and it would be bad form to 24.1206 - spam subscribers with a number of <quote>broken</quote> 24.1207 - notifications while you debug your configuration. 24.1208 - </para> 24.1209 - </listitem> 24.1210 - <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>: 24.1211 - The path to a configuration file that contains 24.1212 - subscription information. This is kept separate from 24.1213 - the main <filename role="special">~/.hgrc</filename> so 24.1214 - that you can maintain it in a repository of its own. 24.1215 - People can then clone that repository, update their 24.1216 - subscriptions, and push the changes back to your server. 24.1217 - </para> 24.1218 - </listitem> 24.1219 - <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>: 24.1220 - The number of leading path separator characters to strip 24.1221 - from a repository's path, when deciding whether a 24.1222 - repository has subscribers. For example, if the 24.1223 - repositories on your server live in <filename 24.1224 - class="directory">/home/hg/repos</filename>, and 24.1225 - <literal role="hg-ext">notify</literal> is considering a 24.1226 - repository named <filename 24.1227 - class="directory">/home/hg/repos/shared/test</filename>, 24.1228 - setting <envar role="rc-item-notify">strip</envar> to 24.1229 - <literal>4</literal> will cause <literal 24.1230 - role="hg-ext">notify</literal> to trim the path it 24.1231 - considers down to <filename 24.1232 - class="directory">shared/test</filename>, and it will 24.1233 - match subscribers against that. 24.1234 - </para> 24.1235 - </listitem> 24.1236 - <listitem><para id="x_272"><envar 24.1237 - role="rc-item-notify">template</envar>: The template 24.1238 - text to use when sending messages. This specifies both 24.1239 - the contents of the message header and its body. 24.1240 - </para> 24.1241 - </listitem> 24.1242 - <listitem><para id="x_273"><envar 24.1243 - role="rc-item-notify">maxdiff</envar>: The maximum 24.1244 - number of lines of diff data to append to the end of a 24.1245 - message. If a diff is longer than this, it is 24.1246 - truncated. By default, this is set to 300. Set this to 24.1247 - <literal>0</literal> to omit diffs from notification 24.1248 - emails. 24.1249 - </para> 24.1250 - </listitem> 24.1251 - <listitem><para id="x_274"><envar 24.1252 - role="rc-item-notify">sources</envar>: A list of 24.1253 - sources of changesets to consider. This lets you limit 24.1254 - <literal role="hg-ext">notify</literal> to only sending 24.1255 - out email about changes that remote users pushed into 24.1256 - this repository via a server, for example. See 24.1257 - <xref linkend="sec:hook:sources"/> for the sources you 24.1258 - can specify here. 24.1259 - </para> 24.1260 - </listitem></itemizedlist> 24.1261 - 24.1262 - <para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar> 24.1263 - item in the <literal role="rc-web">web</literal> section, 24.1264 - you can use it in a template; it will be available as 24.1265 - <literal>webroot</literal>. 24.1266 - </para> 24.1267 - 24.1268 - <para id="x_276">Here is an example set of <literal 24.1269 - role="hg-ext">notify</literal> configuration information. 24.1270 - </para> 24.1271 - 24.1272 - &ch10-notify-config.lst; 24.1273 - 24.1274 - <para id="x_277">This will produce a message that looks like the 24.1275 - following: 24.1276 - </para> 24.1277 - 24.1278 - &ch10-notify-config-mail.lst; 24.1279 - 24.1280 - </sect3> 24.1281 - <sect3> 24.1282 - <title>Testing and troubleshooting</title> 24.1283 - 24.1284 - <para id="x_278">Do not forget that by default, the <literal 24.1285 - role="hg-ext">notify</literal> extension <emphasis>will not 24.1286 - send any mail</emphasis> until you explicitly configure it to do so, 24.1287 - by setting <envar role="rc-item-notify">test</envar> to 24.1288 - <literal>false</literal>. Until you do that, it simply 24.1289 - prints the message it <emphasis>would</emphasis> send. 24.1290 - </para> 24.1291 - 24.1292 - </sect3> 24.1293 - </sect2> 24.1294 - </sect1> 24.1295 - <sect1 id="sec:hook:ref"> 24.1296 - <title>Information for writers of hooks</title> 24.1297 - 24.1298 - <sect2> 24.1299 - <title>In-process hook execution</title> 24.1300 - 24.1301 - <para id="x_279">An in-process hook is called with arguments of the 24.1302 - following form: 24.1303 - </para> 24.1304 - <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting> 24.1305 - <para id="x_27a">The <literal>ui</literal> parameter is a <literal 24.1306 - role="py-mod-mercurial.ui">ui</literal> object. The 24.1307 - <literal>repo</literal> parameter is a <literal 24.1308 - role="py-mod-mercurial.localrepo">localrepository</literal> 24.1309 - object. The names and values of the 24.1310 - <literal>**kwargs</literal> parameters depend on the hook 24.1311 - being invoked, with the following common features: 24.1312 - </para> 24.1313 - <itemizedlist> 24.1314 - <listitem><para id="x_27b">If a parameter is named 24.1315 - <literal>node</literal> or <literal>parentN</literal>, it 24.1316 - will contain a hexadecimal changeset ID. The empty string 24.1317 - is used to represent <quote>null changeset ID</quote> 24.1318 - instead of a string of zeroes. 24.1319 - </para> 24.1320 - </listitem> 24.1321 - <listitem><para id="x_27c">If a parameter is named 24.1322 - <literal>url</literal>, it will contain the URL of a 24.1323 - remote repository, if that can be determined. 24.1324 - </para> 24.1325 - </listitem> 24.1326 - <listitem><para id="x_27d">Boolean-valued parameters are represented as 24.1327 - Python <literal>bool</literal> objects. 24.1328 - </para> 24.1329 - </listitem></itemizedlist> 24.1330 - 24.1331 - <para id="x_27e">An in-process hook is called without a change to the 24.1332 - process's working directory (unlike external hooks, which are 24.1333 - run in the root of the repository). It must not change the 24.1334 - process's working directory, or it will cause any calls it 24.1335 - makes into the Mercurial API to fail. 24.1336 - </para> 24.1337 - 24.1338 - <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it 24.1339 - is considered to have succeeded. If it returns a boolean 24.1340 - <quote>true</quote> value or raises an exception, it is 24.1341 - considered to have failed. A useful way to think of the 24.1342 - calling convention is <quote>tell me if you fail</quote>. 24.1343 - </para> 24.1344 - 24.1345 - <para id="x_280">Note that changeset IDs are passed into Python hooks as 24.1346 - hexadecimal strings, not the binary hashes that Mercurial's 24.1347 - APIs normally use. To convert a hash from hex to binary, use 24.1348 - the <literal>bin</literal> function. 24.1349 - </para> 24.1350 - 24.1351 - </sect2> 24.1352 - <sect2> 24.1353 - <title>External hook execution</title> 24.1354 - 24.1355 - <para id="x_281">An external hook is passed to the shell of the user 24.1356 - running Mercurial. Features of that shell, such as variable 24.1357 - substitution and command redirection, are available. The hook 24.1358 - is run in the root directory of the repository (unlike 24.1359 - in-process hooks, which are run in the same directory that 24.1360 - Mercurial was run in). 24.1361 - </para> 24.1362 - 24.1363 - <para id="x_282">Hook parameters are passed to the hook as environment 24.1364 - variables. Each environment variable's name is converted in 24.1365 - upper case and prefixed with the string 24.1366 - <quote><literal>HG_</literal></quote>. For example, if the 24.1367 - name of a parameter is <quote><literal>node</literal></quote>, 24.1368 - the name of the environment variable representing that 24.1369 - parameter will be <quote><literal>HG_NODE</literal></quote>. 24.1370 - </para> 24.1371 - 24.1372 - <para id="x_283">A boolean parameter is represented as the string 24.1373 - <quote><literal>1</literal></quote> for <quote>true</quote>, 24.1374 - <quote><literal>0</literal></quote> for <quote>false</quote>. 24.1375 - If an environment variable is named <envar>HG_NODE</envar>, 24.1376 - <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it 24.1377 - contains a changeset ID represented as a hexadecimal string. 24.1378 - The empty string is used to represent <quote>null changeset 24.1379 - ID</quote> instead of a string of zeroes. If an environment 24.1380 - variable is named <envar>HG_URL</envar>, it will contain the 24.1381 - URL of a remote repository, if that can be determined. 24.1382 - </para> 24.1383 - 24.1384 - <para id="x_284">If a hook exits with a status of zero, it is considered to 24.1385 - have succeeded. If it exits with a non-zero status, it is 24.1386 - considered to have failed. 24.1387 - </para> 24.1388 - 24.1389 - </sect2> 24.1390 - <sect2> 24.1391 - <title>Finding out where changesets come from</title> 24.1392 - 24.1393 - <para id="x_285">A hook that involves the transfer of changesets between a 24.1394 - local repository and another may be able to find out 24.1395 - information about the <quote>far side</quote>. Mercurial 24.1396 - knows <emphasis>how</emphasis> changes are being transferred, 24.1397 - and in many cases <emphasis>where</emphasis> they are being 24.1398 - transferred to or from. 24.1399 - </para> 24.1400 - 24.1401 - <sect3 id="sec:hook:sources"> 24.1402 - <title>Sources of changesets</title> 24.1403 - 24.1404 - <para id="x_286">Mercurial will tell a hook what means are, or were, used 24.1405 - to transfer changesets between repositories. This is 24.1406 - provided by Mercurial in a Python parameter named 24.1407 - <literal>source</literal>, or an environment variable named 24.1408 - <envar>HG_SOURCE</envar>. 24.1409 - </para> 24.1410 - 24.1411 - <itemizedlist> 24.1412 - <listitem><para id="x_287"><literal>serve</literal>: Changesets are 24.1413 - transferred to or from a remote repository over http or 24.1414 - ssh. 24.1415 - </para> 24.1416 - </listitem> 24.1417 - <listitem><para id="x_288"><literal>pull</literal>: Changesets are 24.1418 - being transferred via a pull from one repository into 24.1419 - another. 24.1420 - </para> 24.1421 - </listitem> 24.1422 - <listitem><para id="x_289"><literal>push</literal>: Changesets are 24.1423 - being transferred via a push from one repository into 24.1424 - another. 24.1425 - </para> 24.1426 - </listitem> 24.1427 - <listitem><para id="x_28a"><literal>bundle</literal>: Changesets are 24.1428 - being transferred to or from a bundle. 24.1429 - </para> 24.1430 - </listitem></itemizedlist> 24.1431 - 24.1432 - </sect3> 24.1433 - <sect3 id="sec:hook:url"> 24.1434 - <title>Where changes are going&emdash;remote repository 24.1435 - URLs</title> 24.1436 - 24.1437 - <para id="x_28b">When possible, Mercurial will tell a hook the location 24.1438 - of the <quote>far side</quote> of an activity that transfers 24.1439 - changeset data between repositories. This is provided by 24.1440 - Mercurial in a Python parameter named 24.1441 - <literal>url</literal>, or an environment variable named 24.1442 - <envar>HG_URL</envar>. 24.1443 - </para> 24.1444 - 24.1445 - <para id="x_28c">This information is not always known. If a hook is 24.1446 - invoked in a repository that is being served via http or 24.1447 - ssh, Mercurial cannot tell where the remote repository is, 24.1448 - but it may know where the client is connecting from. In 24.1449 - such cases, the URL will take one of the following forms: 24.1450 - </para> 24.1451 - <itemizedlist> 24.1452 - <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 24.1453 - ssh client, at the IP address 24.1454 - <literal>1.2.3.4</literal>. 24.1455 - </para> 24.1456 - </listitem> 24.1457 - <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;remote 24.1458 - http client, at the IP address 24.1459 - <literal>1.2.3.4</literal>. If the client is using SSL, 24.1460 - this will be of the form 24.1461 - <literal>remote:https:1.2.3.4</literal>. 24.1462 - </para> 24.1463 - </listitem> 24.1464 - <listitem><para id="x_28f">Empty&emdash;no information could be 24.1465 - discovered about the remote client. 24.1466 - </para> 24.1467 - </listitem></itemizedlist> 24.1468 - 24.1469 - </sect3> 24.1470 - </sect2> 24.1471 - </sect1> 24.1472 - <sect1> 24.1473 - <title>Hook reference</title> 24.1474 - 24.1475 - <sect2 id="sec:hook:changegroup"> 24.1476 - <title><literal role="hook">changegroup</literal>&emdash;after 24.1477 - remote changesets added</title> 24.1478 - 24.1479 - <para id="x_290">This hook is run after a group of pre-existing changesets 24.1480 - has been added to the repository, for example via a <command 24.1481 - role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg 24.1482 - unbundle</command>. This hook is run once per operation 24.1483 - that added one or more changesets. This is in contrast to the 24.1484 - <literal role="hook">incoming</literal> hook, which is run 24.1485 - once per changeset, regardless of whether the changesets 24.1486 - arrive in a group. 24.1487 - </para> 24.1488 - 24.1489 - <para id="x_291">Some possible uses for this hook include kicking off an 24.1490 - automated build or test of the added changesets, updating a 24.1491 - bug database, or notifying subscribers that a repository 24.1492 - contains new changes. 24.1493 - </para> 24.1494 - 24.1495 - <para id="x_292">Parameters to this hook: 24.1496 - </para> 24.1497 - <itemizedlist> 24.1498 - <listitem><para id="x_293"><literal>node</literal>: A changeset ID. The 24.1499 - changeset ID of the first changeset in the group that was 24.1500 - added. All changesets between this and 24.1501 - <literal role="tag">tip</literal>, inclusive, were added by a single 24.1502 - <command role="hg-cmd">hg pull</command>, <command 24.1503 - role="hg-cmd">hg push</command> or <command 24.1504 - role="hg-cmd">hg unbundle</command>. 24.1505 - </para> 24.1506 - </listitem> 24.1507 - <listitem><para id="x_294"><literal>source</literal>: A 24.1508 - string. The source of these changes. See <xref 24.1509 - linkend="sec:hook:sources"/> for details. 24.1510 - </para> 24.1511 - </listitem> 24.1512 - <listitem><para id="x_295"><literal>url</literal>: A URL. The 24.1513 - location of the remote repository, if known. See <xref 24.1514 - linkend="sec:hook:url"/> for more information. 24.1515 - </para> 24.1516 - </listitem></itemizedlist> 24.1517 - 24.1518 - <para id="x_296">See also: <literal 24.1519 - role="hook">incoming</literal> (<xref 24.1520 - linkend="sec:hook:incoming"/>), <literal 24.1521 - role="hook">prechangegroup</literal> (<xref 24.1522 - linkend="sec:hook:prechangegroup"/>), <literal 24.1523 - role="hook">pretxnchangegroup</literal> (<xref 24.1524 - linkend="sec:hook:pretxnchangegroup"/>) 24.1525 - </para> 24.1526 - 24.1527 - </sect2> 24.1528 - <sect2 id="sec:hook:commit"> 24.1529 - <title><literal role="hook">commit</literal>&emdash;after a new 24.1530 - changeset is created</title> 24.1531 - 24.1532 - <para id="x_297">This hook is run after a new changeset has been created. 24.1533 - </para> 24.1534 - 24.1535 - <para id="x_298">Parameters to this hook: 24.1536 - </para> 24.1537 - <itemizedlist> 24.1538 - <listitem><para id="x_299"><literal>node</literal>: A changeset ID. The 24.1539 - changeset ID of the newly committed changeset. 24.1540 - </para> 24.1541 - </listitem> 24.1542 - <listitem><para id="x_29a"><literal>parent1</literal>: A changeset ID. 24.1543 - The changeset ID of the first parent of the newly 24.1544 - committed changeset. 24.1545 - </para> 24.1546 - </listitem> 24.1547 - <listitem><para id="x_29b"><literal>parent2</literal>: A changeset ID. 24.1548 - The changeset ID of the second parent of the newly 24.1549 - committed changeset. 24.1550 - </para> 24.1551 - </listitem></itemizedlist> 24.1552 - 24.1553 - <para id="x_29c">See also: <literal 24.1554 - role="hook">precommit</literal> (<xref 24.1555 - linkend="sec:hook:precommit"/>), <literal 24.1556 - role="hook">pretxncommit</literal> (<xref 24.1557 - linkend="sec:hook:pretxncommit"/>) 24.1558 - </para> 24.1559 - 24.1560 - </sect2> 24.1561 - <sect2 id="sec:hook:incoming"> 24.1562 - <title><literal role="hook">incoming</literal>&emdash;after one 24.1563 - remote changeset is added</title> 24.1564 - 24.1565 - <para id="x_29d">This hook is run after a pre-existing changeset has been 24.1566 - added to the repository, for example via a <command 24.1567 - role="hg-cmd">hg push</command>. If a group of changesets 24.1568 - was added in a single operation, this hook is called once for 24.1569 - each added changeset. 24.1570 - </para> 24.1571 - 24.1572 - <para id="x_29e">You can use this hook for the same purposes as 24.1573 - the <literal role="hook">changegroup</literal> hook (<xref 24.1574 - linkend="sec:hook:changegroup"/>); it's simply more 24.1575 - convenient sometimes to run a hook once per group of 24.1576 - changesets, while other times it's handier once per changeset. 24.1577 - </para> 24.1578 - 24.1579 - <para id="x_29f">Parameters to this hook: 24.1580 - </para> 24.1581 - <itemizedlist> 24.1582 - <listitem><para id="x_2a0"><literal>node</literal>: A changeset ID. The 24.1583 - ID of the newly added changeset. 24.1584 - </para> 24.1585 - </listitem> 24.1586 - <listitem><para id="x_2a1"><literal>source</literal>: A 24.1587 - string. The source of these changes. See <xref 24.1588 - linkend="sec:hook:sources"/> for details. 24.1589 - </para> 24.1590 - </listitem> 24.1591 - <listitem><para id="x_2a2"><literal>url</literal>: A URL. The 24.1592 - location of the remote repository, if known. See <xref 24.1593 - linkend="sec:hook:url"/> for more information. 24.1594 - </para> 24.1595 - </listitem></itemizedlist> 24.1596 - 24.1597 - <para id="x_2a3">See also: <literal 24.1598 - role="hook">changegroup</literal> (<xref 24.1599 - linkend="sec:hook:changegroup"/>) <literal 24.1600 - role="hook">prechangegroup</literal> (<xref 24.1601 - linkend="sec:hook:prechangegroup"/>), <literal 24.1602 - role="hook">pretxnchangegroup</literal> (<xref 24.1603 - linkend="sec:hook:pretxnchangegroup"/>) 24.1604 - </para> 24.1605 - 24.1606 - </sect2> 24.1607 - <sect2 id="sec:hook:outgoing"> 24.1608 - <title><literal role="hook">outgoing</literal>&emdash;after 24.1609 - changesets are propagated</title> 24.1610 - 24.1611 - <para id="x_2a4">This hook is run after a group of changesets has been 24.1612 - propagated out of this repository, for example by a <command 24.1613 - role="hg-cmd">hg push</command> or <command role="hg-cmd">hg 24.1614 - bundle</command> command. 24.1615 - </para> 24.1616 - 24.1617 - <para id="x_2a5">One possible use for this hook is to notify administrators 24.1618 - that changes have been pulled. 24.1619 - </para> 24.1620 - 24.1621 - <para id="x_2a6">Parameters to this hook: 24.1622 - </para> 24.1623 - <itemizedlist> 24.1624 - <listitem><para id="x_2a7"><literal>node</literal>: A changeset ID. The 24.1625 - changeset ID of the first changeset of the group that was 24.1626 - sent. 24.1627 - </para> 24.1628 - </listitem> 24.1629 - <listitem><para id="x_2a8"><literal>source</literal>: A string. The 24.1630 - source of the of the operation (see <xref 24.1631 - linkend="sec:hook:sources"/>). If a remote 24.1632 - client pulled changes from this repository, 24.1633 - <literal>source</literal> will be 24.1634 - <literal>serve</literal>. If the client that obtained 24.1635 - changes from this repository was local, 24.1636 - <literal>source</literal> will be 24.1637 - <literal>bundle</literal>, <literal>pull</literal>, or 24.1638 - <literal>push</literal>, depending on the operation the 24.1639 - client performed. 24.1640 - </para> 24.1641 - </listitem> 24.1642 - <listitem><para id="x_2a9"><literal>url</literal>: A URL. The 24.1643 - location of the remote repository, if known. See <xref 24.1644 - linkend="sec:hook:url"/> for more information. 24.1645 - </para> 24.1646 - </listitem></itemizedlist> 24.1647 - 24.1648 - <para id="x_2aa">See also: <literal 24.1649 - role="hook">preoutgoing</literal> (<xref 24.1650 - linkend="sec:hook:preoutgoing"/>) 24.1651 - </para> 24.1652 - 24.1653 - </sect2> 24.1654 - <sect2 id="sec:hook:prechangegroup"> 24.1655 - <title><literal 24.1656 - role="hook">prechangegroup</literal>&emdash;before starting 24.1657 - to add remote changesets</title> 24.1658 - 24.1659 - <para id="x_2ab">This controlling hook is run before Mercurial begins to 24.1660 - add a group of changesets from another repository. 24.1661 - </para> 24.1662 - 24.1663 - <para id="x_2ac">This hook does not have any information about the 24.1664 - changesets to be added, because it is run before transmission 24.1665 - of those changesets is allowed to begin. If this hook fails, 24.1666 - the changesets will not be transmitted. 24.1667 - </para> 24.1668 - 24.1669 - <para id="x_2ad">One use for this hook is to prevent external changes from 24.1670 - being added to a repository. For example, you could use this 24.1671 - to <quote>freeze</quote> a server-hosted branch temporarily or 24.1672 - permanently so that users cannot push to it, while still 24.1673 - allowing a local administrator to modify the repository. 24.1674 - </para> 24.1675 - 24.1676 - <para id="x_2ae">Parameters to this hook: 24.1677 - </para> 24.1678 - <itemizedlist> 24.1679 - <listitem><para id="x_2af"><literal>source</literal>: A string. The 24.1680 - source of these changes. See <xref 24.1681 - linkend="sec:hook:sources"/> for details. 24.1682 - </para> 24.1683 - </listitem> 24.1684 - <listitem><para id="x_2b0"><literal>url</literal>: A URL. The 24.1685 - location of the remote repository, if known. See <xref 24.1686 - linkend="sec:hook:url"/> for more information. 24.1687 - </para> 24.1688 - </listitem></itemizedlist> 24.1689 - 24.1690 - <para id="x_2b1">See also: <literal 24.1691 - role="hook">changegroup</literal> (<xref 24.1692 - linkend="sec:hook:changegroup"/>), <literal 24.1693 - role="hook">incoming</literal> (<xref 24.1694 - linkend="sec:hook:incoming"/>), <literal 24.1695 - role="hook">pretxnchangegroup</literal> (<xref 24.1696 - linkend="sec:hook:pretxnchangegroup"/>) 24.1697 - </para> 24.1698 - 24.1699 - </sect2> 24.1700 - <sect2 id="sec:hook:precommit"> 24.1701 - <title><literal role="hook">precommit</literal>&emdash;before 24.1702 - starting to commit a changeset</title> 24.1703 - 24.1704 - <para id="x_2b2">This hook is run before Mercurial begins to commit a new 24.1705 - changeset. It is run before Mercurial has any of the metadata 24.1706 - for the commit, such as the files to be committed, the commit 24.1707 - message, or the commit date. 24.1708 - </para> 24.1709 - 24.1710 - <para id="x_2b3">One use for this hook is to disable the ability to commit 24.1711 - new changesets, while still allowing incoming changesets. 24.1712 - Another is to run a build or test, and only allow the commit 24.1713 - to begin if the build or test succeeds. 24.1714 - </para> 24.1715 - 24.1716 - <para id="x_2b4">Parameters to this hook: 24.1717 - </para> 24.1718 - <itemizedlist> 24.1719 - <listitem><para id="x_2b5"><literal>parent1</literal>: A changeset ID. 24.1720 - The changeset ID of the first parent of the working 24.1721 - directory. 24.1722 - </para> 24.1723 - </listitem> 24.1724 - <listitem><para id="x_2b6"><literal>parent2</literal>: A changeset ID. 24.1725 - The changeset ID of the second parent of the working 24.1726 - directory. 24.1727 - </para> 24.1728 - </listitem></itemizedlist> 24.1729 - <para id="x_2b7">If the commit proceeds, the parents of the working 24.1730 - directory will become the parents of the new changeset. 24.1731 - </para> 24.1732 - 24.1733 - <para id="x_2b8">See also: <literal role="hook">commit</literal> 24.1734 - (<xref linkend="sec:hook:commit"/>), <literal 24.1735 - role="hook">pretxncommit</literal> (<xref 24.1736 - linkend="sec:hook:pretxncommit"/>) 24.1737 - </para> 24.1738 - 24.1739 - </sect2> 24.1740 - <sect2 id="sec:hook:preoutgoing"> 24.1741 - <title><literal role="hook">preoutgoing</literal>&emdash;before 24.1742 - starting to propagate changesets</title> 24.1743 - 24.1744 - <para id="x_2b9">This hook is invoked before Mercurial knows the identities 24.1745 - of the changesets to be transmitted. 24.1746 - </para> 24.1747 - 24.1748 - <para id="x_2ba">One use for this hook is to prevent changes from being 24.1749 - transmitted to another repository. 24.1750 - </para> 24.1751 - 24.1752 - <para id="x_2bb">Parameters to this hook: 24.1753 - </para> 24.1754 - <itemizedlist> 24.1755 - <listitem><para id="x_2bc"><literal>source</literal>: A 24.1756 - string. The source of the operation that is attempting to 24.1757 - obtain changes from this repository (see <xref 24.1758 - linkend="sec:hook:sources"/>). See the documentation 24.1759 - for the <literal>source</literal> parameter to the 24.1760 - <literal role="hook">outgoing</literal> hook, in 24.1761 - <xref linkend="sec:hook:outgoing"/>, for possible values 24.1762 - of this parameter. 24.1763 - </para> 24.1764 - </listitem> 24.1765 - <listitem><para id="x_2bd"><literal>url</literal>: A URL. The 24.1766 - location of the remote repository, if known. See <xref 24.1767 - linkend="sec:hook:url"/> for more information. 24.1768 - </para> 24.1769 - </listitem></itemizedlist> 24.1770 - 24.1771 - <para id="x_2be">See also: <literal 24.1772 - role="hook">outgoing</literal> (<xref 24.1773 - linkend="sec:hook:outgoing"/>) 24.1774 - </para> 24.1775 - 24.1776 - </sect2> 24.1777 - <sect2 id="sec:hook:pretag"> 24.1778 - <title><literal role="hook">pretag</literal>&emdash;before 24.1779 - tagging a changeset</title> 24.1780 - 24.1781 - <para id="x_2bf">This controlling hook is run before a tag is created. If 24.1782 - the hook succeeds, creation of the tag proceeds. If the hook 24.1783 - fails, the tag is not created. 24.1784 - </para> 24.1785 - 24.1786 - <para id="x_2c0">Parameters to this hook: 24.1787 - </para> 24.1788 - <itemizedlist> 24.1789 - <listitem><para id="x_2c1"><literal>local</literal>: A boolean. Whether 24.1790 - the tag is local to this repository instance (i.e. stored 24.1791 - in <filename role="special">.hg/localtags</filename>) or 24.1792 - managed by Mercurial (stored in <filename 24.1793 - role="special">.hgtags</filename>). 24.1794 - </para> 24.1795 - </listitem> 24.1796 - <listitem><para id="x_2c2"><literal>node</literal>: A changeset ID. The 24.1797 - ID of the changeset to be tagged. 24.1798 - </para> 24.1799 - </listitem> 24.1800 - <listitem><para id="x_2c3"><literal>tag</literal>: A string. The name of 24.1801 - the tag to be created. 24.1802 - </para> 24.1803 - </listitem></itemizedlist> 24.1804 - 24.1805 - <para id="x_2c4">If the tag to be created is 24.1806 - revision-controlled, the <literal 24.1807 - role="hook">precommit</literal> and <literal 24.1808 - role="hook">pretxncommit</literal> hooks (<xref 24.1809 - linkend="sec:hook:commit"/> and <xref 24.1810 - linkend="sec:hook:pretxncommit"/>) will also be run. 24.1811 - </para> 24.1812 - 24.1813 - <para id="x_2c5">See also: <literal role="hook">tag</literal> 24.1814 - (<xref linkend="sec:hook:tag"/>) 24.1815 - </para> 24.1816 - </sect2> 24.1817 - <sect2 id="sec:hook:pretxnchangegroup"> 24.1818 - <title><literal 24.1819 - role="hook">pretxnchangegroup</literal>&emdash;before 24.1820 - completing addition of remote changesets</title> 24.1821 - 24.1822 - <para id="x_2c6">This controlling hook is run before a 24.1823 - transaction&emdash;that manages the addition of a group of new 24.1824 - changesets from outside the repository&emdash;completes. If 24.1825 - the hook succeeds, the transaction completes, and all of the 24.1826 - changesets become permanent within this repository. If the 24.1827 - hook fails, the transaction is rolled back, and the data for 24.1828 - the changesets is erased. 24.1829 - </para> 24.1830 - 24.1831 - <para id="x_2c7">This hook can access the metadata associated with the 24.1832 - almost-added changesets, but it should not do anything 24.1833 - permanent with this data. It must also not modify the working 24.1834 - directory. 24.1835 - </para> 24.1836 - 24.1837 - <para id="x_2c8">While this hook is running, if other Mercurial processes 24.1838 - access this repository, they will be able to see the 24.1839 - almost-added changesets as if they are permanent. This may 24.1840 - lead to race conditions if you do not take steps to avoid 24.1841 - them. 24.1842 - </para> 24.1843 - 24.1844 - <para id="x_2c9">This hook can be used to automatically vet a group of 24.1845 - changesets. If the hook fails, all of the changesets are 24.1846 - <quote>rejected</quote> when the transaction rolls back. 24.1847 - </para> 24.1848 - 24.1849 - <para id="x_2ca">Parameters to this hook: 24.1850 - </para> 24.1851 - <itemizedlist> 24.1852 - <listitem><para id="x_2cb"><literal>node</literal>: A changeset ID. The 24.1853 - changeset ID of the first changeset in the group that was 24.1854 - added. All changesets between this and 24.1855 - <literal role="tag">tip</literal>, 24.1856 - inclusive, were added by a single <command 24.1857 - role="hg-cmd">hg pull</command>, <command 24.1858 - role="hg-cmd">hg push</command> or <command 24.1859 - role="hg-cmd">hg unbundle</command>. 24.1860 - </para> 24.1861 - </listitem> 24.1862 - <listitem><para id="x_2cc"><literal>source</literal>: A 24.1863 - string. The source of these changes. See <xref 24.1864 - linkend="sec:hook:sources"/> for details. 24.1865 - </para> 24.1866 - </listitem> 24.1867 - <listitem><para id="x_2cd"><literal>url</literal>: A URL. The 24.1868 - location of the remote repository, if known. See <xref 24.1869 - linkend="sec:hook:url"/> for more information. 24.1870 - </para> 24.1871 - </listitem></itemizedlist> 24.1872 - 24.1873 - <para id="x_2ce">See also: <literal 24.1874 - role="hook">changegroup</literal> (<xref 24.1875 - linkend="sec:hook:changegroup"/>), <literal 24.1876 - role="hook">incoming</literal> (<xref 24.1877 - linkend="sec:hook:incoming"/>), <literal 24.1878 - role="hook">prechangegroup</literal> (<xref 24.1879 - linkend="sec:hook:prechangegroup"/>) 24.1880 - </para> 24.1881 - 24.1882 - </sect2> 24.1883 - <sect2 id="sec:hook:pretxncommit"> 24.1884 - <title><literal role="hook">pretxncommit</literal>&emdash;before 24.1885 - completing commit of new changeset</title> 24.1886 - 24.1887 - <para id="x_2cf">This controlling hook is run before a 24.1888 - transaction&emdash;that manages a new commit&emdash;completes. 24.1889 - If the hook succeeds, the transaction completes and the 24.1890 - changeset becomes permanent within this repository. If the 24.1891 - hook fails, the transaction is rolled back, and the commit 24.1892 - data is erased. 24.1893 - </para> 24.1894 - 24.1895 - <para id="x_2d0">This hook can access the metadata associated with the 24.1896 - almost-new changeset, but it should not do anything permanent 24.1897 - with this data. It must also not modify the working 24.1898 - directory. 24.1899 - </para> 24.1900 - 24.1901 - <para id="x_2d1">While this hook is running, if other Mercurial processes 24.1902 - access this repository, they will be able to see the 24.1903 - almost-new changeset as if it is permanent. This may lead to 24.1904 - race conditions if you do not take steps to avoid them. 24.1905 - </para> 24.1906 - 24.1907 - <para id="x_2d2">Parameters to this hook: 24.1908 - </para> 24.1909 - <itemizedlist> 24.1910 - <listitem><para id="x_2d3"><literal>node</literal>: A changeset ID. The 24.1911 - changeset ID of the newly committed changeset. 24.1912 - </para> 24.1913 - </listitem> 24.1914 - <listitem><para id="x_2d4"><literal>parent1</literal>: A changeset ID. 24.1915 - The changeset ID of the first parent of the newly 24.1916 - committed changeset. 24.1917 - </para> 24.1918 - </listitem> 24.1919 - <listitem><para id="x_2d5"><literal>parent2</literal>: A changeset ID. 24.1920 - The changeset ID of the second parent of the newly 24.1921 - committed changeset. 24.1922 - </para> 24.1923 - </listitem></itemizedlist> 24.1924 - 24.1925 - <para id="x_2d6">See also: <literal 24.1926 - role="hook">precommit</literal> (<xref 24.1927 - linkend="sec:hook:precommit"/>) 24.1928 - </para> 24.1929 - 24.1930 - </sect2> 24.1931 - <sect2 id="sec:hook:preupdate"> 24.1932 - <title><literal role="hook">preupdate</literal>&emdash;before 24.1933 - updating or merging working directory</title> 24.1934 - 24.1935 - <para id="x_2d7">This controlling hook is run before an update 24.1936 - or merge of the working directory begins. It is run only if 24.1937 - Mercurial's normal pre-update checks determine that the update 24.1938 - or merge can proceed. If the hook succeeds, the update or 24.1939 - merge may proceed; if it fails, the update or merge does not 24.1940 - start. 24.1941 - </para> 24.1942 - 24.1943 - <para id="x_2d8">Parameters to this hook: 24.1944 - </para> 24.1945 - <itemizedlist> 24.1946 - <listitem><para id="x_2d9"><literal>parent1</literal>: A 24.1947 - changeset ID. The ID of the parent that the working 24.1948 - directory is to be updated to. If the working directory 24.1949 - is being merged, it will not change this parent. 24.1950 - </para> 24.1951 - </listitem> 24.1952 - <listitem><para id="x_2da"><literal>parent2</literal>: A 24.1953 - changeset ID. Only set if the working directory is being 24.1954 - merged. The ID of the revision that the working directory 24.1955 - is being merged with. 24.1956 - </para> 24.1957 - </listitem></itemizedlist> 24.1958 - 24.1959 - <para id="x_2db">See also: <literal role="hook">update</literal> 24.1960 - (<xref linkend="sec:hook:update"/>)</para> 24.1961 - 24.1962 - </sect2> 24.1963 - <sect2 id="sec:hook:tag"> 24.1964 - <title><literal role="hook">tag</literal>&emdash;after tagging a 24.1965 - changeset</title> 24.1966 - 24.1967 - <para id="x_2dc">This hook is run after a tag has been created. 24.1968 - </para> 24.1969 - 24.1970 - <para id="x_2dd">Parameters to this hook: 24.1971 - </para> 24.1972 - <itemizedlist> 24.1973 - <listitem><para id="x_2de"><literal>local</literal>: A boolean. Whether 24.1974 - the new tag is local to this repository instance (i.e. 24.1975 - stored in <filename 24.1976 - role="special">.hg/localtags</filename>) or managed by 24.1977 - Mercurial (stored in <filename 24.1978 - role="special">.hgtags</filename>). 24.1979 - </para> 24.1980 - </listitem> 24.1981 - <listitem><para id="x_2df"><literal>node</literal>: A changeset ID. The 24.1982 - ID of the changeset that was tagged. 24.1983 - </para> 24.1984 - </listitem> 24.1985 - <listitem><para id="x_2e0"><literal>tag</literal>: A string. The name of 24.1986 - the tag that was created. 24.1987 - </para> 24.1988 - </listitem></itemizedlist> 24.1989 - 24.1990 - <para id="x_2e1">If the created tag is revision-controlled, the <literal 24.1991 - role="hook">commit</literal> hook (section <xref 24.1992 - linkend="sec:hook:commit"/>) is run before this hook. 24.1993 - </para> 24.1994 - 24.1995 - <para id="x_2e2">See also: <literal role="hook">pretag</literal> 24.1996 - (<xref linkend="sec:hook:pretag"/>) 24.1997 - </para> 24.1998 - 24.1999 - </sect2> 24.2000 - <sect2 id="sec:hook:update"> 24.2001 - <title><literal role="hook">update</literal>&emdash;after 24.2002 - updating or merging working directory</title> 24.2003 - 24.2004 - <para id="x_2e3">This hook is run after an update or merge of the working 24.2005 - directory completes. Since a merge can fail (if the external 24.2006 - <command>hgmerge</command> command fails to resolve conflicts 24.2007 - in a file), this hook communicates whether the update or merge 24.2008 - completed cleanly. 24.2009 - </para> 24.2010 - 24.2011 - <itemizedlist> 24.2012 - <listitem><para id="x_2e4"><literal>error</literal>: A boolean. 24.2013 - Indicates whether the update or merge completed 24.2014 - successfully. 24.2015 - </para> 24.2016 - </listitem> 24.2017 - <listitem><para id="x_2e5"><literal>parent1</literal>: A changeset ID. 24.2018 - The ID of the parent that the working directory was 24.2019 - updated to. If the working directory was merged, it will 24.2020 - not have changed this parent. 24.2021 - </para> 24.2022 - </listitem> 24.2023 - <listitem><para id="x_2e6"><literal>parent2</literal>: A changeset ID. 24.2024 - Only set if the working directory was merged. The ID of 24.2025 - the revision that the working directory was merged with. 24.2026 - </para> 24.2027 - </listitem></itemizedlist> 24.2028 - 24.2029 - <para id="x_2e7">See also: <literal role="hook">preupdate</literal> 24.2030 - (<xref linkend="sec:hook:preupdate"/>) 24.2031 - </para> 24.2032 - 24.2033 - </sect2> 24.2034 - </sect1> 24.2035 -</chapter> 24.2036 - 24.2037 -<!-- 24.2038 -local variables: 24.2039 -sgml-parent-document: ("00book.xml" "book" "chapter") 24.2040 -end: 24.2041 --->
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/en/ch09-undo.xml Thu May 21 14:16:17 2009 +0800 25.3 @@ -0,0 +1,1201 @@ 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 id="x_d2">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 id="x_d3">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 id="x_d4">In <xref linkend="sec:concepts:txn"/>, I 25.37 + mentioned that Mercurial treats each modification of a 25.38 + repository as a <emphasis>transaction</emphasis>. Every time 25.39 + you commit a changeset or pull changes from another 25.40 + repository, Mercurial remembers what you did. You can undo, 25.41 + or <emphasis>roll back</emphasis>, exactly one of these 25.42 + actions using the <command role="hg-cmd">hg rollback</command> 25.43 + command. (See <xref linkend="sec:undo:rollback-after-push"/> 25.44 + for an important caveat about the use of this command.)</para> 25.45 + 25.46 + <para id="x_d5">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 id="x_d6">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 id="x_d7">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 id="x_d8">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 id="x_d9">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 id="x_da">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 id="x_db">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 id="x_dc">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 id="x_dd">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 id="x_de">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. If you push a changeset somewhere, then 25.134 + roll it back, then pull from the repository you pushed to, the 25.135 + changeset you thought you'd gotten rid of will simply reappear 25.136 + in your repository.</para> 25.137 + 25.138 + <para id="x_df">(If you absolutely know for sure that the change 25.139 + you want to roll back is the most recent change in the 25.140 + repository that you pushed to, <emphasis>and</emphasis> you 25.141 + know that nobody else could have pulled it from that 25.142 + repository, you can roll back the changeset there, too, but 25.143 + you really should not expect this to work reliably. 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 id="x_e0">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 + behavior you will get.</para> 25.158 + 25.159 + &interaction.rollback.twice; 25.160 + 25.161 + <para id="x_e1">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 id="x_e2">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 id="x_e3">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 id="x_e4">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 id="x_e5">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 + <tip> 25.200 + <title>Be careful with <filename>.orig</filename> files</title> 25.201 + 25.202 + <para id="x_6b8">It's extremely unlikely that you are either using 25.203 + Mercurial to manage files with <filename>.orig</filename> 25.204 + extensions or that you even care about the contents of such 25.205 + files. Just in case, though, it's useful to remember that 25.206 + <command role="hg-cmd">hg revert</command> will 25.207 + unconditionally overwrite an existing file with a 25.208 + <filename>.orig</filename> extension. For instance, if you 25.209 + already have a file named <filename>foo.orig</filename> when 25.210 + you revert <filename>foo</filename>, the contents of 25.211 + <filename>foo.orig</filename> will be clobbered.</para> 25.212 + </tip> 25.213 + 25.214 + <para id="x_e6">Here is a summary of the cases that the <command 25.215 + role="hg-cmd">hg revert</command> command can deal with. We 25.216 + will describe each of these in more detail in the section that 25.217 + follows.</para> 25.218 + <itemizedlist> 25.219 + <listitem><para id="x_e7">If you modify a file, it will restore the file 25.220 + to its unmodified state.</para> 25.221 + </listitem> 25.222 + <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a 25.223 + file, it will undo the <quote>added</quote> state of the 25.224 + file, but leave the file itself untouched.</para> 25.225 + </listitem> 25.226 + <listitem><para id="x_e9">If you delete a file without telling Mercurial, 25.227 + it will restore the file to its unmodified contents.</para> 25.228 + </listitem> 25.229 + <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg 25.230 + remove</command> command to remove a file, it will undo 25.231 + the <quote>removed</quote> state of the file, and restore 25.232 + the file to its unmodified contents.</para> 25.233 + </listitem></itemizedlist> 25.234 + 25.235 + <sect2 id="sec:undo:mgmt"> 25.236 + <title>File management errors</title> 25.237 + 25.238 + <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is 25.239 + useful for more than just modified files. It lets you reverse 25.240 + the results of all of Mercurial's file management 25.241 + commands&emdash;<command role="hg-cmd">hg add</command>, 25.242 + <command role="hg-cmd">hg remove</command>, and so on.</para> 25.243 + 25.244 + <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file, 25.245 + then decide that in fact you don't want Mercurial to track it, 25.246 + use <command role="hg-cmd">hg revert</command> to undo the 25.247 + add. Don't worry; Mercurial will not modify the file in any 25.248 + way. It will just <quote>unmark</quote> the file.</para> 25.249 + 25.250 + &interaction.daily.revert.add; 25.251 + 25.252 + <para id="x_ed">Similarly, if you ask Mercurial to <command 25.253 + role="hg-cmd">hg remove</command> a file, you can use 25.254 + <command role="hg-cmd">hg revert</command> to restore it to 25.255 + the contents it had as of the parent of the working directory. 25.256 + &interaction.daily.revert.remove; This works just as 25.257 + well for a file that you deleted by hand, without telling 25.258 + Mercurial (recall that in Mercurial terminology, this kind of 25.259 + file is called <quote>missing</quote>).</para> 25.260 + 25.261 + &interaction.daily.revert.missing; 25.262 + 25.263 + <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>, 25.264 + the copied-to file remains in your working directory 25.265 + afterwards, untracked. Since a copy doesn't affect the 25.266 + copied-from file in any way, Mercurial doesn't do anything 25.267 + with the copied-from file.</para> 25.268 + 25.269 + &interaction.daily.revert.copy; 25.270 + </sect2> 25.271 + </sect1> 25.272 + 25.273 + <sect1> 25.274 + <title>Dealing with committed changes</title> 25.275 + 25.276 + <para id="x_f5">Consider a case where you have committed a change 25.277 + <emphasis>a</emphasis>, and another change 25.278 + <emphasis>b</emphasis> on top of it; you then realise that 25.279 + change <emphasis>a</emphasis> was incorrect. Mercurial lets you 25.280 + <quote>back out</quote> an entire changeset automatically, and 25.281 + building blocks that let you reverse part of a changeset by 25.282 + hand.</para> 25.283 + 25.284 + <para id="x_f6">Before you read this section, here's something to 25.285 + keep in mind: the <command role="hg-cmd">hg backout</command> 25.286 + command undoes the effect of a change by 25.287 + <emphasis>adding</emphasis> to your repository's history, not by 25.288 + modifying or erasing it. It's the right tool to use if you're 25.289 + fixing bugs, but not if you're trying to undo some change that 25.290 + has catastrophic consequences. To deal with those, see 25.291 + <xref linkend="sec:undo:aaaiiieee"/>.</para> 25.292 + 25.293 + <sect2> 25.294 + <title>Backing out a changeset</title> 25.295 + 25.296 + <para id="x_f7">The <command role="hg-cmd">hg backout</command> command 25.297 + lets you <quote>undo</quote> the effects of an entire 25.298 + changeset in an automated fashion. Because Mercurial's 25.299 + history is immutable, this command <emphasis>does 25.300 + not</emphasis> get rid of the changeset you want to undo. 25.301 + Instead, it creates a new changeset that 25.302 + <emphasis>reverses</emphasis> the effect of the to-be-undone 25.303 + changeset.</para> 25.304 + 25.305 + <para id="x_f8">The operation of the <command role="hg-cmd">hg 25.306 + backout</command> command is a little intricate, so let's 25.307 + illustrate it with some examples. First, we'll create a 25.308 + repository with some simple changes.</para> 25.309 + 25.310 + &interaction.backout.init; 25.311 + 25.312 + <para id="x_f9">The <command role="hg-cmd">hg backout</command> command 25.313 + takes a single changeset ID as its argument; this is the 25.314 + changeset to back out. Normally, <command role="hg-cmd">hg 25.315 + backout</command> will drop you into a text editor to write 25.316 + a commit message, so you can record why you're backing the 25.317 + change out. In this example, we provide a commit message on 25.318 + the command line using the <option 25.319 + role="hg-opt-backout">-m</option> option.</para> 25.320 + 25.321 + </sect2> 25.322 + <sect2> 25.323 + <title>Backing out the tip changeset</title> 25.324 + 25.325 + <para id="x_fa">We're going to start by backing out the last changeset we 25.326 + committed.</para> 25.327 + 25.328 + &interaction.backout.simple; 25.329 + 25.330 + <para id="x_fb">You can see that the second line from 25.331 + <filename>myfile</filename> is no longer present. Taking a 25.332 + look at the output of <command role="hg-cmd">hg log</command> 25.333 + gives us an idea of what the <command role="hg-cmd">hg 25.334 + backout</command> command has done. 25.335 + &interaction.backout.simple.log; Notice that the new changeset 25.336 + that <command role="hg-cmd">hg backout</command> has created 25.337 + is a child of the changeset we backed out. It's easier to see 25.338 + this in <xref linkend="fig:undo:backout"/>, which presents a 25.339 + graphical view of the change history. As you can see, the 25.340 + history is nice and linear.</para> 25.341 + 25.342 + <figure id="fig:undo:backout"> 25.343 + <title>Backing out a change using the <command 25.344 + role="hg-cmd">hg backout</command> command</title> 25.345 + <mediaobject> 25.346 + <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject> 25.347 + <textobject><phrase>XXX add text</phrase></textobject> 25.348 + </mediaobject> 25.349 + </figure> 25.350 + 25.351 + </sect2> 25.352 + <sect2> 25.353 + <title>Backing out a non-tip change</title> 25.354 + 25.355 + <para id="x_fd">If you want to back out a change other than the last one 25.356 + you committed, pass the <option 25.357 + role="hg-opt-backout">--merge</option> option to the 25.358 + <command role="hg-cmd">hg backout</command> command.</para> 25.359 + 25.360 + &interaction.backout.non-tip.clone; 25.361 + 25.362 + <para id="x_fe">This makes backing out any changeset a 25.363 + <quote>one-shot</quote> operation that's usually simple and 25.364 + fast.</para> 25.365 + 25.366 + &interaction.backout.non-tip.backout; 25.367 + 25.368 + <para id="x_ff">If you take a look at the contents of 25.369 + <filename>myfile</filename> after the backout finishes, you'll 25.370 + see that the first and third changes are present, but not the 25.371 + second.</para> 25.372 + 25.373 + &interaction.backout.non-tip.cat; 25.374 + 25.375 + <para id="x_100">As the graphical history in <xref 25.376 + linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial 25.377 + still commits one change in this kind of situation (the 25.378 + box-shaped node is the ones that Mercurial commits 25.379 + automatically), but the revision graph now looks different. 25.380 + Before Mercurial begins the backout process, it first 25.381 + remembers what the current parent of the working directory is. 25.382 + It then backs out the target changeset, and commits that as a 25.383 + changeset. Finally, it merges back to the previous parent of 25.384 + the working directory, but notice that it <emphasis>does not 25.385 + commit</emphasis> the result of the merge. The repository 25.386 + now contains two heads, and the working directory is in a 25.387 + merge state.</para> 25.388 + 25.389 + <figure id="fig:undo:backout-non-tip"> 25.390 + <title>Automated backout of a non-tip change using the 25.391 + <command role="hg-cmd">hg backout</command> command</title> 25.392 + <mediaobject> 25.393 + <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject> 25.394 + <textobject><phrase>XXX add text</phrase></textobject> 25.395 + </mediaobject> 25.396 + </figure> 25.397 + 25.398 + <para id="x_103">The result is that you end up <quote>back where you 25.399 + were</quote>, only with some extra history that undoes the 25.400 + effect of the changeset you wanted to back out.</para> 25.401 + 25.402 + <para id="x_6b9">You might wonder why Mercurial does not commit the result 25.403 + of the merge that it performed. The reason lies in Mercurial 25.404 + behaving conservatively: a merge naturally has more scope for 25.405 + error than simply undoing the effect of the tip changeset, 25.406 + so your work will be safest if you first inspect (and test!) 25.407 + the result of the merge, <emphasis>then</emphasis> commit 25.408 + it.</para> 25.409 + 25.410 + <sect3> 25.411 + <title>Always use the <option 25.412 + role="hg-opt-backout">--merge</option> option</title> 25.413 + 25.414 + <para id="x_104">In fact, since the <option 25.415 + role="hg-opt-backout">--merge</option> option will do the 25.416 + <quote>right thing</quote> whether or not the changeset 25.417 + you're backing out is the tip (i.e. it won't try to merge if 25.418 + it's backing out the tip, since there's no need), you should 25.419 + <emphasis>always</emphasis> use this option when you run the 25.420 + <command role="hg-cmd">hg backout</command> command.</para> 25.421 + 25.422 + </sect3> 25.423 + </sect2> 25.424 + <sect2> 25.425 + <title>Gaining more control of the backout process</title> 25.426 + 25.427 + <para id="x_105">While I've recommended that you always use the <option 25.428 + role="hg-opt-backout">--merge</option> option when backing 25.429 + out a change, the <command role="hg-cmd">hg backout</command> 25.430 + command lets you decide how to merge a backout changeset. 25.431 + Taking control of the backout process by hand is something you 25.432 + will rarely need to do, but it can be useful to understand 25.433 + what the <command role="hg-cmd">hg backout</command> command 25.434 + is doing for you automatically. To illustrate this, let's 25.435 + clone our first repository, but omit the backout change that 25.436 + it contains.</para> 25.437 + 25.438 + &interaction.backout.manual.clone; 25.439 + 25.440 + <para id="x_106">As with our 25.441 + earlier example, We'll commit a third changeset, then back out 25.442 + its parent, and see what happens.</para> 25.443 + 25.444 + &interaction.backout.manual.backout; 25.445 + 25.446 + <para id="x_107">Our new changeset is again a descendant of the changeset 25.447 + we backout out; it's thus a new head, <emphasis>not</emphasis> 25.448 + a descendant of the changeset that was the tip. The <command 25.449 + role="hg-cmd">hg backout</command> command was quite 25.450 + explicit in telling us this.</para> 25.451 + 25.452 + &interaction.backout.manual.log; 25.453 + 25.454 + <para id="x_108">Again, it's easier to see what has happened by looking at 25.455 + a graph of the revision history, in <xref 25.456 + linkend="fig:undo:backout-manual"/>. This makes it clear 25.457 + that when we use <command role="hg-cmd">hg backout</command> 25.458 + to back out a change other than the tip, Mercurial adds a new 25.459 + head to the repository (the change it committed is 25.460 + box-shaped).</para> 25.461 + 25.462 + <figure id="fig:undo:backout-manual"> 25.463 + <title>Backing out a change using the <command 25.464 + role="hg-cmd">hg backout</command> command</title> 25.465 + <mediaobject> 25.466 + <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject> 25.467 + <textobject><phrase>XXX add text</phrase></textobject> 25.468 + </mediaobject> 25.469 + </figure> 25.470 + 25.471 + <para id="x_10a">After the <command role="hg-cmd">hg backout</command> 25.472 + command has completed, it leaves the new 25.473 + <quote>backout</quote> changeset as the parent of the working 25.474 + directory.</para> 25.475 + 25.476 + &interaction.backout.manual.parents; 25.477 + 25.478 + <para id="x_10b">Now we have two isolated sets of changes.</para> 25.479 + 25.480 + &interaction.backout.manual.heads; 25.481 + 25.482 + <para id="x_10c">Let's think about what we expect to see as the contents of 25.483 + <filename>myfile</filename> now. The first change should be 25.484 + present, because we've never backed it out. The second change 25.485 + should be missing, as that's the change we backed out. Since 25.486 + the history graph shows the third change as a separate head, 25.487 + we <emphasis>don't</emphasis> expect to see the third change 25.488 + present in <filename>myfile</filename>.</para> 25.489 + 25.490 + &interaction.backout.manual.cat; 25.491 + 25.492 + <para id="x_10d">To get the third change back into the file, we just do a 25.493 + normal merge of our two heads.</para> 25.494 + 25.495 + &interaction.backout.manual.merge; 25.496 + 25.497 + <para id="x_10e">Afterwards, the graphical history of our 25.498 + repository looks like 25.499 + <xref linkend="fig:undo:backout-manual-merge"/>.</para> 25.500 + 25.501 + <figure id="fig:undo:backout-manual-merge"> 25.502 + <title>Manually merging a backout change</title> 25.503 + <mediaobject> 25.504 + <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject> 25.505 + <textobject><phrase>XXX add text</phrase></textobject> 25.506 + </mediaobject> 25.507 + </figure> 25.508 + 25.509 + </sect2> 25.510 + <sect2> 25.511 + <title>Why <command role="hg-cmd">hg backout</command> works as 25.512 + it does</title> 25.513 + 25.514 + <para id="x_110">Here's a brief description of how the <command 25.515 + role="hg-cmd">hg backout</command> command works.</para> 25.516 + <orderedlist> 25.517 + <listitem><para id="x_111">It ensures that the working directory is 25.518 + <quote>clean</quote>, i.e. that the output of <command 25.519 + role="hg-cmd">hg status</command> would be empty.</para> 25.520 + </listitem> 25.521 + <listitem><para id="x_112">It remembers the current parent of the working 25.522 + directory. Let's call this changeset 25.523 + <literal>orig</literal>.</para> 25.524 + </listitem> 25.525 + <listitem><para id="x_113">It does the equivalent of a <command 25.526 + role="hg-cmd">hg update</command> to sync the working 25.527 + directory to the changeset you want to back out. Let's 25.528 + call this changeset <literal>backout</literal>.</para> 25.529 + </listitem> 25.530 + <listitem><para id="x_114">It finds the parent of that changeset. Let's 25.531 + call that changeset <literal>parent</literal>.</para> 25.532 + </listitem> 25.533 + <listitem><para id="x_115">For each file that the 25.534 + <literal>backout</literal> changeset affected, it does the 25.535 + equivalent of a <command role="hg-cmd">hg revert -r 25.536 + parent</command> on that file, to restore it to the 25.537 + contents it had before that changeset was 25.538 + committed.</para> 25.539 + </listitem> 25.540 + <listitem><para id="x_116">It commits the result as a new changeset. 25.541 + This changeset has <literal>backout</literal> as its 25.542 + parent.</para> 25.543 + </listitem> 25.544 + <listitem><para id="x_117">If you specify <option 25.545 + role="hg-opt-backout">--merge</option> on the command 25.546 + line, it merges with <literal>orig</literal>, and commits 25.547 + the result of the merge.</para> 25.548 + </listitem></orderedlist> 25.549 + 25.550 + <para id="x_118">An alternative way to implement the <command 25.551 + role="hg-cmd">hg backout</command> command would be to 25.552 + <command role="hg-cmd">hg export</command> the 25.553 + to-be-backed-out changeset as a diff, then use the <option 25.554 + role="cmd-opt-patch">--reverse</option> option to the 25.555 + <command>patch</command> command to reverse the effect of the 25.556 + change without fiddling with the working directory. This 25.557 + sounds much simpler, but it would not work nearly as 25.558 + well.</para> 25.559 + 25.560 + <para id="x_119">The reason that <command role="hg-cmd">hg 25.561 + backout</command> does an update, a commit, a merge, and 25.562 + another commit is to give the merge machinery the best chance 25.563 + to do a good job when dealing with all the changes 25.564 + <emphasis>between</emphasis> the change you're backing out and 25.565 + the current tip.</para> 25.566 + 25.567 + <para id="x_11a">If you're backing out a changeset that's 100 revisions 25.568 + back in your project's history, the chances that the 25.569 + <command>patch</command> command will be able to apply a 25.570 + reverse diff cleanly are not good, because intervening changes 25.571 + are likely to have <quote>broken the context</quote> that 25.572 + <command>patch</command> uses to determine whether it can 25.573 + apply a patch (if this sounds like gibberish, see <xref 25.574 + linkend="sec:mq:patch"/> for a 25.575 + discussion of the <command>patch</command> command). Also, 25.576 + Mercurial's merge machinery will handle files and directories 25.577 + being renamed, permission changes, and modifications to binary 25.578 + files, none of which <command>patch</command> can deal 25.579 + with.</para> 25.580 + 25.581 + </sect2> 25.582 + </sect1> 25.583 + <sect1 id="sec:undo:aaaiiieee"> 25.584 + <title>Changes that should never have been</title> 25.585 + 25.586 + <para id="x_11b">Most of the time, the <command role="hg-cmd">hg 25.587 + backout</command> command is exactly what you need if you want 25.588 + to undo the effects of a change. It leaves a permanent record 25.589 + of exactly what you did, both when committing the original 25.590 + changeset and when you cleaned up after it.</para> 25.591 + 25.592 + <para id="x_11c">On rare occasions, though, you may find that you've 25.593 + committed a change that really should not be present in the 25.594 + repository at all. For example, it would be very unusual, and 25.595 + usually considered a mistake, to commit a software project's 25.596 + object files as well as its source files. Object files have 25.597 + almost no intrinsic value, and they're <emphasis>big</emphasis>, 25.598 + so they increase the size of the repository and the amount of 25.599 + time it takes to clone or pull changes.</para> 25.600 + 25.601 + <para id="x_11d">Before I discuss the options that you have if you commit a 25.602 + <quote>brown paper bag</quote> change (the kind that's so bad 25.603 + that you want to pull a brown paper bag over your head), let me 25.604 + first discuss some approaches that probably won't work.</para> 25.605 + 25.606 + <para id="x_11e">Since Mercurial treats history as 25.607 + accumulative&emdash;every change builds on top of all changes 25.608 + that preceded it&emdash;you generally can't just make disastrous 25.609 + changes disappear. The one exception is when you've just 25.610 + committed a change, and it hasn't been pushed or pulled into 25.611 + another repository. That's when you can safely use the <command 25.612 + role="hg-cmd">hg rollback</command> command, as I detailed in 25.613 + <xref linkend="sec:undo:rollback"/>.</para> 25.614 + 25.615 + <para id="x_11f">After you've pushed a bad change to another repository, you 25.616 + <emphasis>could</emphasis> still use <command role="hg-cmd">hg 25.617 + rollback</command> to make your local copy of the change 25.618 + disappear, but it won't have the consequences you want. The 25.619 + change will still be present in the remote repository, so it 25.620 + will reappear in your local repository the next time you 25.621 + pull.</para> 25.622 + 25.623 + <para id="x_120">If a situation like this arises, and you know which 25.624 + repositories your bad change has propagated into, you can 25.625 + <emphasis>try</emphasis> to get rid of the change from 25.626 + <emphasis>every</emphasis> one of those repositories. This is, 25.627 + of course, not a satisfactory solution: if you miss even a 25.628 + single repository while you're expunging, the change is still 25.629 + <quote>in the wild</quote>, and could propagate further.</para> 25.630 + 25.631 + <para id="x_121">If you've committed one or more changes 25.632 + <emphasis>after</emphasis> the change that you'd like to see 25.633 + disappear, your options are further reduced. Mercurial doesn't 25.634 + provide a way to <quote>punch a hole</quote> in history, leaving 25.635 + changesets intact.</para> 25.636 + 25.637 + <sect2> 25.638 + <title>Backing out a merge</title> 25.639 + 25.640 + <para id="x_6ba">Since merges are often complicated, it is not unheard of 25.641 + for a merge to be mangled badly, but committed erroneously. 25.642 + Mercurial provides an important safeguard against bad merges 25.643 + by refusing to commit unresolved files, but human ingenuity 25.644 + guarantees that it is still possible to mess a merge up and 25.645 + commit it.</para> 25.646 + 25.647 + <para id="x_6bb">Given a bad merge that has been committed, usually the 25.648 + best way to approach it is to simply try to repair the damage 25.649 + by hand. A complete disaster that cannot be easily fixed up 25.650 + by hand ought to be very rare, but the <command 25.651 + role="hg-cmd">hg backout</command> command may help in 25.652 + making the cleanup easier. It offers a <option 25.653 + role="hg-opt-backout">--parent</option> option, which lets 25.654 + you specify which parent to revert to when backing out a 25.655 + merge.</para> 25.656 + 25.657 + <figure id="fig:undo:bad-merge-1"> 25.658 + <title>A bad merge</title> 25.659 + <mediaobject> 25.660 + <imageobject><imagedata fileref="figs/bad-merge-1.png"/></imageobject> 25.661 + <textobject><phrase>XXX add text</phrase></textobject> 25.662 + </mediaobject> 25.663 + </figure> 25.664 + 25.665 + <para id="x_6bc">Suppose we have a revision graph like that in <xref 25.666 + linkend="fig:undo:bad-merge-1"/>. What we'd like is to 25.667 + <emphasis>redo</emphasis> the merge of revisions 2 and 25.668 + 3.</para> 25.669 + 25.670 + <para id="x_6bd">One way to do so would be as follows.</para> 25.671 + 25.672 + <orderedlist> 25.673 + <listitem> 25.674 + <para id="x_6be">Call <command role="hg-cmd">hg backout --rev=4 25.675 + --parent=2</command>. This tells <command 25.676 + role="hg-cmd">hg backout</command> to back out revision 25.677 + 4, which is the bad merge, and to when deciding which 25.678 + revision to prefer, to choose parent 2, one of the parents 25.679 + of the merge. The effect can be seen in <xref 25.680 + linkend="fig:undo:bad-merge-2"/>.</para> 25.681 + <figure id="fig:undo:bad-merge-2"> 25.682 + <title>Backing out the merge, favoring one parent</title> 25.683 + <mediaobject> 25.684 + <imageobject><imagedata fileref="figs/bad-merge-2.png"/></imageobject> 25.685 + <textobject><phrase>XXX add text</phrase></textobject> 25.686 + </mediaobject> 25.687 + </figure> 25.688 + </listitem> 25.689 + 25.690 + <listitem> 25.691 + <para id="x_6bf">Call <command role="hg-cmd">hg backout --rev=4 25.692 + --parent=3</command>. This tells <command 25.693 + role="hg-cmd">hg backout</command> to back out revision 25.694 + 4 again, but this time to choose parent 3, the other 25.695 + parent of the merge. The result is visible in <xref 25.696 + linkend="fig:undo:bad-merge-3"/>, in which the repository 25.697 + now contains three heads.</para> 25.698 + <figure id="fig:undo:bad-merge-3"> 25.699 + <title>Backing out the merge, favoring the other 25.700 + parent</title> 25.701 + <mediaobject> 25.702 + <imageobject><imagedata fileref="figs/bad-merge-3.png"/></imageobject> 25.703 + <textobject><phrase>XXX add text</phrase></textobject> 25.704 + </mediaobject> 25.705 + </figure> 25.706 + </listitem> 25.707 + 25.708 + <listitem> 25.709 + <para id="x_6c0">Redo the bad merge by merging the two backout heads, 25.710 + which reduces the number of heads in the repository to 25.711 + two, as can be seen in <xref 25.712 + linkend="fig:undo:bad-merge-4"/>.</para> 25.713 + <figure id="fig:undo:bad-merge-4"> 25.714 + <title>Merging the backouts</title> 25.715 + <mediaobject> 25.716 + <imageobject><imagedata fileref="figs/bad-merge-4.png"/></imageobject> 25.717 + <textobject><phrase>XXX add text</phrase></textobject> 25.718 + </mediaobject> 25.719 + </figure> 25.720 + </listitem> 25.721 + 25.722 + <listitem> 25.723 + <para id="x_6c1">Merge with the commit that was made after the bad 25.724 + merge, as shown in <xref 25.725 + linkend="fig:undo:bad-merge-5"/>.</para> 25.726 + <figure id="fig:undo:bad-merge-5"> 25.727 + <title>Merging the backouts</title> 25.728 + <mediaobject> 25.729 + <imageobject><imagedata fileref="figs/bad-merge-5.png"/></imageobject> 25.730 + <textobject><phrase>XXX add text</phrase></textobject> 25.731 + </mediaobject> 25.732 + </figure> 25.733 + </listitem> 25.734 + </orderedlist> 25.735 + </sect2> 25.736 + 25.737 + <sect2> 25.738 + <title>Protect yourself from <quote>escaped</quote> 25.739 + changes</title> 25.740 + 25.741 + <para id="x_123">If you've committed some changes to your local repository 25.742 + and they've been pushed or pulled somewhere else, this isn't 25.743 + necessarily a disaster. You can protect yourself ahead of 25.744 + time against some classes of bad changeset. This is 25.745 + particularly easy if your team usually pulls changes from a 25.746 + central repository.</para> 25.747 + 25.748 + <para id="x_124">By configuring some hooks on that repository to validate 25.749 + incoming changesets (see chapter <xref linkend="chap:hook"/>), 25.750 + you can 25.751 + automatically prevent some kinds of bad changeset from being 25.752 + pushed to the central repository at all. With such a 25.753 + configuration in place, some kinds of bad changeset will 25.754 + naturally tend to <quote>die out</quote> because they can't 25.755 + propagate into the central repository. Better yet, this 25.756 + happens without any need for explicit intervention.</para> 25.757 + 25.758 + <para id="x_125">For instance, an incoming change hook that 25.759 + verifies that a changeset will actually compile can prevent 25.760 + people from inadvertently <quote>breaking the 25.761 + build</quote>.</para> 25.762 + </sect2> 25.763 + 25.764 + <sect2> 25.765 + <title>What to do about sensitive changes that escape</title> 25.766 + 25.767 + <para id="x_6c2">Even a carefully run project can suffer an unfortunate 25.768 + event such as the committing and uncontrolled propagation of a 25.769 + file that contains important passwords.</para> 25.770 + 25.771 + <para id="x_6c3">If something like this happens to you, and the information 25.772 + that gets accidentally propagated is truly sensitive, your 25.773 + first step should be to mitigate the effect of the leak 25.774 + without trying to control the leak itself. If you are not 100% 25.775 + certain that you know exactly who could have seen the changes, 25.776 + you should immediately change passwords, cancel credit cards, 25.777 + or find some other way to make sure that the information that 25.778 + has leaked is no longer useful. In other words, assume that 25.779 + the change has propagated far and wide, and that there's 25.780 + nothing more you can do.</para> 25.781 + 25.782 + <para id="x_6c4">You might hope that there would be mechanisms you could 25.783 + use to either figure out who has seen a change or to erase the 25.784 + change permanently everywhere, but there are good reasons why 25.785 + these are not possible.</para> 25.786 + 25.787 + <para id="x_6c5">Mercurial does not provide an audit trail of who has 25.788 + pulled changes from a repository, because it is usually either 25.789 + impossible to record such information or trivial to spoof it. 25.790 + In a multi-user or networked environment, you should thus be 25.791 + extremely skeptical of yourself if you think that you have 25.792 + identified every place that a sensitive changeset has 25.793 + propagated to. Don't forget that people can and will send 25.794 + bundles by email, have their backup software save data 25.795 + offsite, carry repositories on USB sticks, and find other 25.796 + completely innocent ways to confound your attempts to track 25.797 + down every copy of a problematic change.</para> 25.798 + 25.799 + <para id="x_6c6">Mercurial also does not provide a way to make a file or 25.800 + changeset completely disappear from history, because there is 25.801 + no way to enforce its disappearance; someone could easily 25.802 + modify their copy of Mercurial to ignore such directives. In 25.803 + addition, even if Mercurial provided such a capability, 25.804 + someone who simply hadn't pulled a <quote>make this file 25.805 + disappear</quote> changeset wouldn't be affected by it, nor 25.806 + would web crawlers visiting at the wrong time, disk backups, 25.807 + or other mechanisms. Indeed, no distributed revision control 25.808 + system can make data reliably vanish. Providing the illusion 25.809 + of such control could easily give a false sense of security, 25.810 + and be worse than not providing it at all.</para> 25.811 + </sect2> 25.812 + </sect1> 25.813 + 25.814 + <sect1 id="sec:undo:bisect"> 25.815 + <title>Finding the source of a bug</title> 25.816 + 25.817 + <para id="x_126">While it's all very well to be able to back out a changeset 25.818 + that introduced a bug, this requires that you know which 25.819 + changeset to back out. Mercurial provides an invaluable 25.820 + command, called <command role="hg-cmd">hg bisect</command>, that 25.821 + helps you to automate this process and accomplish it very 25.822 + efficiently.</para> 25.823 + 25.824 + <para id="x_127">The idea behind the <command role="hg-cmd">hg 25.825 + bisect</command> command is that a changeset has introduced 25.826 + some change of behavior that you can identify with a simple 25.827 + pass/fail test. You don't know which piece of code introduced the 25.828 + change, but you know how to test for the presence of the bug. 25.829 + The <command role="hg-cmd">hg bisect</command> command uses your 25.830 + test to direct its search for the changeset that introduced the 25.831 + code that caused the bug.</para> 25.832 + 25.833 + <para id="x_128">Here are a few scenarios to help you understand how you 25.834 + might apply this command.</para> 25.835 + <itemizedlist> 25.836 + <listitem><para id="x_129">The most recent version of your software has a 25.837 + bug that you remember wasn't present a few weeks ago, but 25.838 + you don't know when it was introduced. Here, your binary 25.839 + test checks for the presence of that bug.</para> 25.840 + </listitem> 25.841 + <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to 25.842 + close the entry in your team's bug database. The bug 25.843 + database requires a changeset ID when you close an entry, 25.844 + but you don't remember which changeset you fixed the bug in. 25.845 + Once again, your binary test checks for the presence of the 25.846 + bug.</para> 25.847 + </listitem> 25.848 + <listitem><para id="x_12b">Your software works correctly, but runs 15% 25.849 + slower than the last time you measured it. You want to know 25.850 + which changeset introduced the performance regression. In 25.851 + this case, your binary test measures the performance of your 25.852 + software, to see whether it's <quote>fast</quote> or 25.853 + <quote>slow</quote>.</para> 25.854 + </listitem> 25.855 + <listitem><para id="x_12c">The sizes of the components of your project that 25.856 + you ship exploded recently, and you suspect that something 25.857 + changed in the way you build your project.</para> 25.858 + </listitem></itemizedlist> 25.859 + 25.860 + <para id="x_12d">From these examples, it should be clear that the <command 25.861 + role="hg-cmd">hg bisect</command> command is not useful only 25.862 + for finding the sources of bugs. You can use it to find any 25.863 + <quote>emergent property</quote> of a repository (anything that 25.864 + you can't find from a simple text search of the files in the 25.865 + tree) for which you can write a binary test.</para> 25.866 + 25.867 + <para id="x_12e">We'll introduce a little bit of terminology here, just to 25.868 + make it clear which parts of the search process are your 25.869 + responsibility, and which are Mercurial's. A 25.870 + <emphasis>test</emphasis> is something that 25.871 + <emphasis>you</emphasis> run when <command role="hg-cmd">hg 25.872 + bisect</command> chooses a changeset. A 25.873 + <emphasis>probe</emphasis> is what <command role="hg-cmd">hg 25.874 + bisect</command> runs to tell whether a revision is good. 25.875 + Finally, we'll use the word <quote>bisect</quote>, as both a 25.876 + noun and a verb, to stand in for the phrase <quote>search using 25.877 + the <command role="hg-cmd">hg bisect</command> 25.878 + command</quote>.</para> 25.879 + 25.880 + <para id="x_12f">One simple way to automate the searching process would be 25.881 + simply to probe every changeset. However, this scales poorly. 25.882 + If it took ten minutes to test a single changeset, and you had 25.883 + 10,000 changesets in your repository, the exhaustive approach 25.884 + would take on average 35 <emphasis>days</emphasis> to find the 25.885 + changeset that introduced a bug. Even if you knew that the bug 25.886 + was introduced by one of the last 500 changesets, and limited 25.887 + your search to those, you'd still be looking at over 40 hours to 25.888 + find the changeset that introduced your bug.</para> 25.889 + 25.890 + <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command 25.891 + does is use its knowledge of the <quote>shape</quote> of your 25.892 + project's revision history to perform a search in time 25.893 + proportional to the <emphasis>logarithm</emphasis> of the number 25.894 + of changesets to check (the kind of search it performs is called 25.895 + a dichotomic search). With this approach, searching through 25.896 + 10,000 changesets will take less than three hours, even at ten 25.897 + minutes per test (the search will require about 14 tests). 25.898 + Limit your search to the last hundred changesets, and it will 25.899 + take only about an hour (roughly seven tests).</para> 25.900 + 25.901 + <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is 25.902 + aware of the <quote>branchy</quote> nature of a Mercurial 25.903 + project's revision history, so it has no problems dealing with 25.904 + branches, merges, or multiple heads in a repository. It can 25.905 + prune entire branches of history with a single probe, which is 25.906 + how it operates so efficiently.</para> 25.907 + 25.908 + <sect2> 25.909 + <title>Using the <command role="hg-cmd">hg bisect</command> 25.910 + command</title> 25.911 + 25.912 + <para id="x_132">Here's an example of <command role="hg-cmd">hg 25.913 + bisect</command> in action.</para> 25.914 + 25.915 + <note> 25.916 + <para id="x_133"> In versions 0.9.5 and earlier of Mercurial, <command 25.917 + role="hg-cmd">hg bisect</command> was not a core command: 25.918 + it was distributed with Mercurial as an extension. This 25.919 + section describes the built-in command, not the old 25.920 + extension.</para> 25.921 + </note> 25.922 + 25.923 + <para id="x_134">Now let's create a repository, so that we can try out the 25.924 + <command role="hg-cmd">hg bisect</command> command in 25.925 + isolation.</para> 25.926 + 25.927 + &interaction.bisect.init; 25.928 + 25.929 + <para id="x_135">We'll simulate a project that has a bug in it in a 25.930 + simple-minded way: create trivial changes in a loop, and 25.931 + nominate one specific change that will have the 25.932 + <quote>bug</quote>. This loop creates 35 changesets, each 25.933 + adding a single file to the repository. We'll represent our 25.934 + <quote>bug</quote> with a file that contains the text <quote>i 25.935 + have a gub</quote>.</para> 25.936 + 25.937 + &interaction.bisect.commits; 25.938 + 25.939 + <para id="x_136">The next thing that we'd like to do is figure out how to 25.940 + use the <command role="hg-cmd">hg bisect</command> command. 25.941 + We can use Mercurial's normal built-in help mechanism for 25.942 + this.</para> 25.943 + 25.944 + &interaction.bisect.help; 25.945 + 25.946 + <para id="x_137">The <command role="hg-cmd">hg bisect</command> command 25.947 + works in steps. Each step proceeds as follows.</para> 25.948 + <orderedlist> 25.949 + <listitem><para id="x_138">You run your binary test.</para> 25.950 + <itemizedlist> 25.951 + <listitem><para id="x_139">If the test succeeded, you tell <command 25.952 + role="hg-cmd">hg bisect</command> by running the 25.953 + <command role="hg-cmd">hg bisect --good</command> 25.954 + command.</para> 25.955 + </listitem> 25.956 + <listitem><para id="x_13a">If it failed, run the <command 25.957 + role="hg-cmd">hg bisect --bad</command> 25.958 + command.</para></listitem></itemizedlist> 25.959 + </listitem> 25.960 + <listitem><para id="x_13b">The command uses your information to decide 25.961 + which changeset to test next.</para> 25.962 + </listitem> 25.963 + <listitem><para id="x_13c">It updates the working directory to that 25.964 + changeset, and the process begins again.</para> 25.965 + </listitem></orderedlist> 25.966 + <para id="x_13d">The process ends when <command role="hg-cmd">hg 25.967 + bisect</command> identifies a unique changeset that marks 25.968 + the point where your test transitioned from 25.969 + <quote>succeeding</quote> to <quote>failing</quote>.</para> 25.970 + 25.971 + <para id="x_13e">To start the search, we must run the <command 25.972 + role="hg-cmd">hg bisect --reset</command> command.</para> 25.973 + 25.974 + &interaction.bisect.search.init; 25.975 + 25.976 + <para id="x_13f">In our case, the binary test we use is simple: we check to 25.977 + see if any file in the repository contains the string <quote>i 25.978 + have a gub</quote>. If it does, this changeset contains the 25.979 + change that <quote>caused the bug</quote>. By convention, a 25.980 + changeset that has the property we're searching for is 25.981 + <quote>bad</quote>, while one that doesn't is 25.982 + <quote>good</quote>.</para> 25.983 + 25.984 + <para id="x_140">Most of the time, the revision to which the working 25.985 + directory is synced (usually the tip) already exhibits the 25.986 + problem introduced by the buggy change, so we'll mark it as 25.987 + <quote>bad</quote>.</para> 25.988 + 25.989 + &interaction.bisect.search.bad-init; 25.990 + 25.991 + <para id="x_141">Our next task is to nominate a changeset that we know 25.992 + <emphasis>doesn't</emphasis> have the bug; the <command 25.993 + role="hg-cmd">hg bisect</command> command will 25.994 + <quote>bracket</quote> its search between the first pair of 25.995 + good and bad changesets. In our case, we know that revision 25.996 + 10 didn't have the bug. (I'll have more words about choosing 25.997 + the first <quote>good</quote> changeset later.)</para> 25.998 + 25.999 + &interaction.bisect.search.good-init; 25.1000 + 25.1001 + <para id="x_142">Notice that this command printed some output.</para> 25.1002 + <itemizedlist> 25.1003 + <listitem><para id="x_143">It told us how many changesets it must 25.1004 + consider before it can identify the one that introduced 25.1005 + the bug, and how many tests that will require.</para> 25.1006 + </listitem> 25.1007 + <listitem><para id="x_144">It updated the working directory to the next 25.1008 + changeset to test, and told us which changeset it's 25.1009 + testing.</para> 25.1010 + </listitem></itemizedlist> 25.1011 + 25.1012 + <para id="x_145">We now run our test in the working directory. We use the 25.1013 + <command>grep</command> command to see if our 25.1014 + <quote>bad</quote> file is present in the working directory. 25.1015 + If it is, this revision is bad; if not, this revision is good. 25.1016 + &interaction.bisect.search.step1;</para> 25.1017 + 25.1018 + <para id="x_146">This test looks like a perfect candidate for automation, 25.1019 + so let's turn it into a shell function.</para> 25.1020 + &interaction.bisect.search.mytest; 25.1021 + 25.1022 + <para id="x_147">We can now run an entire test step with a single command, 25.1023 + <literal>mytest</literal>.</para> 25.1024 + 25.1025 + &interaction.bisect.search.step2; 25.1026 + 25.1027 + <para id="x_148">A few more invocations of our canned test step command, 25.1028 + and we're done.</para> 25.1029 + 25.1030 + &interaction.bisect.search.rest; 25.1031 + 25.1032 + <para id="x_149">Even though we had 40 changesets to search through, the 25.1033 + <command role="hg-cmd">hg bisect</command> command let us find 25.1034 + the changeset that introduced our <quote>bug</quote> with only 25.1035 + five tests. Because the number of tests that the <command 25.1036 + role="hg-cmd">hg bisect</command> command performs grows 25.1037 + logarithmically with the number of changesets to search, the 25.1038 + advantage that it has over the <quote>brute force</quote> 25.1039 + search approach increases with every changeset you add.</para> 25.1040 + 25.1041 + </sect2> 25.1042 + <sect2> 25.1043 + <title>Cleaning up after your search</title> 25.1044 + 25.1045 + <para id="x_14a">When you're finished using the <command role="hg-cmd">hg 25.1046 + bisect</command> command in a repository, you can use the 25.1047 + <command role="hg-cmd">hg bisect --reset</command> command to 25.1048 + drop the information it was using to drive your search. The 25.1049 + command doesn't use much space, so it doesn't matter if you 25.1050 + forget to run this command. However, <command 25.1051 + role="hg-cmd">hg bisect</command> won't let you start a new 25.1052 + search in that repository until you do a <command 25.1053 + role="hg-cmd">hg bisect --reset</command>.</para> 25.1054 + 25.1055 + &interaction.bisect.search.reset; 25.1056 + 25.1057 + </sect2> 25.1058 + </sect1> 25.1059 + <sect1> 25.1060 + <title>Tips for finding bugs effectively</title> 25.1061 + 25.1062 + <sect2> 25.1063 + <title>Give consistent input</title> 25.1064 + 25.1065 + <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command 25.1066 + requires that you correctly report the result of every test 25.1067 + you perform. If you tell it that a test failed when it really 25.1068 + succeeded, it <emphasis>might</emphasis> be able to detect the 25.1069 + inconsistency. If it can identify an inconsistency in your 25.1070 + reports, it will tell you that a particular changeset is both 25.1071 + good and bad. However, it can't do this perfectly; it's about 25.1072 + as likely to report the wrong changeset as the source of the 25.1073 + bug.</para> 25.1074 + 25.1075 + </sect2> 25.1076 + <sect2> 25.1077 + <title>Automate as much as possible</title> 25.1078 + 25.1079 + <para id="x_14c">When I started using the <command role="hg-cmd">hg 25.1080 + bisect</command> command, I tried a few times to run my 25.1081 + tests by hand, on the command line. This is an approach that 25.1082 + I, at least, am not suited to. After a few tries, I found 25.1083 + that I was making enough mistakes that I was having to restart 25.1084 + my searches several times before finally getting correct 25.1085 + results.</para> 25.1086 + 25.1087 + <para id="x_14d">My initial problems with driving the <command 25.1088 + role="hg-cmd">hg bisect</command> command by hand occurred 25.1089 + even with simple searches on small repositories; if the 25.1090 + problem you're looking for is more subtle, or the number of 25.1091 + tests that <command role="hg-cmd">hg bisect</command> must 25.1092 + perform increases, the likelihood of operator error ruining 25.1093 + the search is much higher. Once I started automating my 25.1094 + tests, I had much better results.</para> 25.1095 + 25.1096 + <para id="x_14e">The key to automated testing is twofold:</para> 25.1097 + <itemizedlist> 25.1098 + <listitem><para id="x_14f">always test for the same symptom, and</para> 25.1099 + </listitem> 25.1100 + <listitem><para id="x_150">always feed consistent input to the <command 25.1101 + role="hg-cmd">hg bisect</command> command.</para> 25.1102 + </listitem></itemizedlist> 25.1103 + <para id="x_151">In my tutorial example above, the <command>grep</command> 25.1104 + command tests for the symptom, and the <literal>if</literal> 25.1105 + statement takes the result of this check and ensures that we 25.1106 + always feed the same input to the <command role="hg-cmd">hg 25.1107 + bisect</command> command. The <literal>mytest</literal> 25.1108 + function marries these together in a reproducible way, so that 25.1109 + every test is uniform and consistent.</para> 25.1110 + 25.1111 + </sect2> 25.1112 + <sect2> 25.1113 + <title>Check your results</title> 25.1114 + 25.1115 + <para id="x_152">Because the output of a <command role="hg-cmd">hg 25.1116 + bisect</command> search is only as good as the input you 25.1117 + give it, don't take the changeset it reports as the absolute 25.1118 + truth. A simple way to cross-check its report is to manually 25.1119 + run your test at each of the following changesets:</para> 25.1120 + <itemizedlist> 25.1121 + <listitem><para id="x_153">The changeset that it reports as the first bad 25.1122 + revision. Your test should still report this as 25.1123 + bad.</para> 25.1124 + </listitem> 25.1125 + <listitem><para id="x_154">The parent of that changeset (either parent, 25.1126 + if it's a merge). Your test should report this changeset 25.1127 + as good.</para> 25.1128 + </listitem> 25.1129 + <listitem><para id="x_155">A child of that changeset. Your test should 25.1130 + report this changeset as bad.</para> 25.1131 + </listitem></itemizedlist> 25.1132 + 25.1133 + </sect2> 25.1134 + <sect2> 25.1135 + <title>Beware interference between bugs</title> 25.1136 + 25.1137 + <para id="x_156">It's possible that your search for one bug could be 25.1138 + disrupted by the presence of another. For example, let's say 25.1139 + your software crashes at revision 100, and worked correctly at 25.1140 + revision 50. Unknown to you, someone else introduced a 25.1141 + different crashing bug at revision 60, and fixed it at 25.1142 + revision 80. This could distort your results in one of 25.1143 + several ways.</para> 25.1144 + 25.1145 + <para id="x_157">It is possible that this other bug completely 25.1146 + <quote>masks</quote> yours, which is to say that it occurs 25.1147 + before your bug has a chance to manifest itself. If you can't 25.1148 + avoid that other bug (for example, it prevents your project 25.1149 + from building), and so can't tell whether your bug is present 25.1150 + in a particular changeset, the <command role="hg-cmd">hg 25.1151 + bisect</command> command cannot help you directly. Instead, 25.1152 + you can mark a changeset as untested by running <command 25.1153 + role="hg-cmd">hg bisect --skip</command>.</para> 25.1154 + 25.1155 + <para id="x_158">A different problem could arise if your test for a bug's 25.1156 + presence is not specific enough. If you check for <quote>my 25.1157 + program crashes</quote>, then both your crashing bug and an 25.1158 + unrelated crashing bug that masks it will look like the same 25.1159 + thing, and mislead <command role="hg-cmd">hg 25.1160 + bisect</command>.</para> 25.1161 + 25.1162 + <para id="x_159">Another useful situation in which to use <command 25.1163 + role="hg-cmd">hg bisect --skip</command> is if you can't 25.1164 + test a revision because your project was in a broken and hence 25.1165 + untestable state at that revision, perhaps because someone 25.1166 + checked in a change that prevented the project from 25.1167 + building.</para> 25.1168 + 25.1169 + </sect2> 25.1170 + <sect2> 25.1171 + <title>Bracket your search lazily</title> 25.1172 + 25.1173 + <para id="x_15a">Choosing the first <quote>good</quote> and 25.1174 + <quote>bad</quote> changesets that will mark the end points of 25.1175 + your search is often easy, but it bears a little discussion 25.1176 + nevertheless. From the perspective of <command 25.1177 + role="hg-cmd">hg bisect</command>, the <quote>newest</quote> 25.1178 + changeset is conventionally <quote>bad</quote>, and the older 25.1179 + changeset is <quote>good</quote>.</para> 25.1180 + 25.1181 + <para id="x_15b">If you're having trouble remembering when a suitable 25.1182 + <quote>good</quote> change was, so that you can tell <command 25.1183 + role="hg-cmd">hg bisect</command>, you could do worse than 25.1184 + testing changesets at random. Just remember to eliminate 25.1185 + contenders that can't possibly exhibit the bug (perhaps 25.1186 + because the feature with the bug isn't present yet) and those 25.1187 + where another problem masks the bug (as I discussed 25.1188 + above).</para> 25.1189 + 25.1190 + <para id="x_15c">Even if you end up <quote>early</quote> by thousands of 25.1191 + changesets or months of history, you will only add a handful 25.1192 + of tests to the total number that <command role="hg-cmd">hg 25.1193 + bisect</command> must perform, thanks to its logarithmic 25.1194 + behavior.</para> 25.1195 + 25.1196 + </sect2> 25.1197 + </sect1> 25.1198 +</chapter> 25.1199 + 25.1200 +<!-- 25.1201 +local variables: 25.1202 +sgml-parent-document: ("00book.xml" "book" "chapter") 25.1203 +end: 25.1204 +-->
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/en/ch10-hook.xml Thu May 21 14:16:17 2009 +0800 26.3 @@ -0,0 +1,1928 @@ 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 id="x_1e6">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 id="x_1e7">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 id="x_1e8">Here is a brief list of the hooks that Mercurial 26.24 + supports. We will revisit each of these hooks in more detail 26.25 + later, in <xref linkend="sec:hook:ref"/>.</para> 26.26 + 26.27 + <para id="x_1f6">Each of the hooks whose description begins with the word 26.28 + <quote>Controlling</quote> has the ability to determine whether 26.29 + an activity can proceed. If the hook succeeds, the activity may 26.30 + proceed; if it fails, the activity is either not permitted or 26.31 + undone, depending on the hook.</para> 26.32 + 26.33 + <itemizedlist> 26.34 + <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: This 26.35 + is run after a group of changesets has been brought into the 26.36 + repository from elsewhere.</para> 26.37 + </listitem> 26.38 + <listitem><para id="x_1ea"><literal role="hook">commit</literal>: This is 26.39 + run after a new changeset has been created in the local 26.40 + repository.</para> 26.41 + </listitem> 26.42 + <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: This is 26.43 + run once for each new changeset that is brought into the 26.44 + repository from elsewhere. Notice the difference from 26.45 + <literal role="hook">changegroup</literal>, which is run 26.46 + once per <emphasis>group</emphasis> of changesets brought 26.47 + in.</para> 26.48 + </listitem> 26.49 + <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: This is 26.50 + run after a group of changesets has been transmitted from 26.51 + this repository.</para> 26.52 + </listitem> 26.53 + <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>: 26.54 + This is run before starting to bring a group of changesets 26.55 + into the repository. 26.56 + </para> 26.57 + </listitem> 26.58 + <listitem><para id="x_1ee"><literal role="hook">precommit</literal>: 26.59 + Controlling. This is run before starting a commit. 26.60 + </para> 26.61 + </listitem> 26.62 + <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>: 26.63 + Controlling. This is run before starting to transmit a group 26.64 + of changesets from this repository. 26.65 + </para> 26.66 + </listitem> 26.67 + <listitem><para id="x_1f0"><literal role="hook">pretag</literal>: 26.68 + Controlling. This is run before creating a tag. 26.69 + </para> 26.70 + </listitem> 26.71 + <listitem><para id="x_1f1"><literal 26.72 + role="hook">pretxnchangegroup</literal>: Controlling. This 26.73 + is run after a group of changesets has been brought into the 26.74 + local repository from another, but before the transaction 26.75 + completes that will make the changes permanent in the 26.76 + repository. 26.77 + </para> 26.78 + </listitem> 26.79 + <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>: 26.80 + Controlling. This is run after a new changeset has been 26.81 + created in the local repository, but before the transaction 26.82 + completes that will make it permanent. 26.83 + </para> 26.84 + </listitem> 26.85 + <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>: 26.86 + Controlling. This is run before starting an update or merge 26.87 + of the working directory. 26.88 + </para> 26.89 + </listitem> 26.90 + <listitem><para id="x_1f4"><literal role="hook">tag</literal>: This is run 26.91 + after a tag is created. 26.92 + </para> 26.93 + </listitem> 26.94 + <listitem><para id="x_1f5"><literal role="hook">update</literal>: This is 26.95 + run after an update or merge of the working directory has 26.96 + finished. 26.97 + </para> 26.98 + </listitem></itemizedlist> 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 id="x_1f7">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 id="x_1f8">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 id="x_1f9">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 id="x_1fa"> 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 id="x_1fb">To see what hooks are defined in a repository, 26.146 + use the <command role="hg-cmd">hg showconfig hooks</command> 26.147 + command. If you are working in one repository, but talking to 26.148 + another that you do not own (e.g. using <command 26.149 + role="hg-cmd">hg 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 + </sect2> 26.154 + 26.155 + <sect2> 26.156 + <title>Hooks do not propagate</title> 26.157 + 26.158 + <para id="x_1fc">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 id="x_1fd">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 id="x_1fe">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 id="x_1ff">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 + </sect2> 26.185 + 26.186 + <sect2> 26.187 + <title>Hooks can be overridden</title> 26.188 + 26.189 + <para id="x_200">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 behavior as you wish. 26.192 + </para> 26.193 + 26.194 + <para id="x_201">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 + </sect2> 26.200 + 26.201 + <sect2> 26.202 + <title>Ensuring that critical hooks are run</title> 26.203 + 26.204 + <para id="x_202">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 id="x_203">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 id="x_204">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 id="x_205">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 + 26.239 + <sect1 id="sec:hook:simple"> 26.240 + <title>A short tutorial on using hooks</title> 26.241 + 26.242 + <para id="x_212">It is easy to write a Mercurial hook. Let's start with a 26.243 + hook that runs when you finish a <command role="hg-cmd">hg 26.244 + commit</command>, and simply prints the hash of the changeset 26.245 + you just created. The hook is called <literal 26.246 + role="hook">commit</literal>. 26.247 + </para> 26.248 + 26.249 + <para id="x_213">All hooks follow the pattern in this example.</para> 26.250 + 26.251 +&interaction.hook.simple.init; 26.252 + 26.253 + <para id="x_214">You add an entry to the <literal 26.254 + role="rc-hooks">hooks</literal> section of your <filename 26.255 + role="special">~/.hgrc</filename>. On the left is the name of 26.256 + the event to trigger on; on the right is the action to take. As 26.257 + you can see, you can run an arbitrary shell command in a hook. 26.258 + Mercurial passes extra information to the hook using environment 26.259 + variables (look for <envar>HG_NODE</envar> in the example). 26.260 + </para> 26.261 + 26.262 + <sect2> 26.263 + <title>Performing multiple actions per event</title> 26.264 + 26.265 + <para id="x_215">Quite often, you will want to define more than one hook 26.266 + for a particular kind of event, as shown below.</para> 26.267 + 26.268 +&interaction.hook.simple.ext; 26.269 + 26.270 + <para id="x_216">Mercurial lets you do this by adding an 26.271 + <emphasis>extension</emphasis> to the end of a hook's name. 26.272 + You extend a hook's name by giving the name of the hook, 26.273 + followed by a full stop (the 26.274 + <quote><literal>.</literal></quote> character), followed by 26.275 + some more text of your choosing. For example, Mercurial will 26.276 + run both <literal>commit.foo</literal> and 26.277 + <literal>commit.bar</literal> when the 26.278 + <literal>commit</literal> event occurs. 26.279 + </para> 26.280 + 26.281 + <para id="x_217">To give a well-defined order of execution when there are 26.282 + multiple hooks defined for an event, Mercurial sorts hooks by 26.283 + extension, and executes the hook commands in this sorted 26.284 + order. In the above example, it will execute 26.285 + <literal>commit.bar</literal> before 26.286 + <literal>commit.foo</literal>, and <literal>commit</literal> 26.287 + before both. 26.288 + </para> 26.289 + 26.290 + <para id="x_218">It is a good idea to use a somewhat descriptive 26.291 + extension when you define a new hook. This will help you to 26.292 + remember what the hook was for. If the hook fails, you'll get 26.293 + an error message that contains the hook name and extension, so 26.294 + using a descriptive extension could give you an immediate hint 26.295 + as to why the hook failed (see <xref 26.296 + linkend="sec:hook:perm"/> for an example). 26.297 + </para> 26.298 + 26.299 + </sect2> 26.300 + <sect2 id="sec:hook:perm"> 26.301 + <title>Controlling whether an activity can proceed</title> 26.302 + 26.303 + <para id="x_219">In our earlier examples, we used the <literal 26.304 + role="hook">commit</literal> hook, which is run after a 26.305 + commit has completed. This is one of several Mercurial hooks 26.306 + that run after an activity finishes. Such hooks have no way 26.307 + of influencing the activity itself. 26.308 + </para> 26.309 + 26.310 + <para id="x_21a">Mercurial defines a number of events that occur before an 26.311 + activity starts; or after it starts, but before it finishes. 26.312 + Hooks that trigger on these events have the added ability to 26.313 + choose whether the activity can continue, or will abort. 26.314 + </para> 26.315 + 26.316 + <para id="x_21b">The <literal role="hook">pretxncommit</literal> hook runs 26.317 + after a commit has all but completed. In other words, the 26.318 + metadata representing the changeset has been written out to 26.319 + disk, but the transaction has not yet been allowed to 26.320 + complete. The <literal role="hook">pretxncommit</literal> 26.321 + hook has the ability to decide whether the transaction can 26.322 + complete, or must be rolled back. 26.323 + </para> 26.324 + 26.325 + <para id="x_21c">If the <literal role="hook">pretxncommit</literal> hook 26.326 + exits with a status code of zero, the transaction is allowed 26.327 + to complete; the commit finishes; and the <literal 26.328 + role="hook">commit</literal> hook is run. If the <literal 26.329 + role="hook">pretxncommit</literal> hook exits with a 26.330 + non-zero status code, the transaction is rolled back; the 26.331 + metadata representing the changeset is erased; and the 26.332 + <literal role="hook">commit</literal> hook is not run. 26.333 + </para> 26.334 + 26.335 +&interaction.hook.simple.pretxncommit; 26.336 + 26.337 + <para id="x_21d">The hook in the example above checks that a commit comment 26.338 + contains a bug ID. If it does, the commit can complete. If 26.339 + not, the commit is rolled back. 26.340 + </para> 26.341 + 26.342 + </sect2> 26.343 + </sect1> 26.344 + <sect1> 26.345 + <title>Writing your own hooks</title> 26.346 + 26.347 + <para id="x_21e">When you are writing a hook, you might find it useful to run 26.348 + Mercurial either with the <option 26.349 + role="hg-opt-global">-v</option> option, or the <envar 26.350 + role="rc-item-ui">verbose</envar> config item set to 26.351 + <quote>true</quote>. When you do so, Mercurial will print a 26.352 + message before it calls each hook. 26.353 + </para> 26.354 + 26.355 + <sect2 id="sec:hook:lang"> 26.356 + <title>Choosing how your hook should run</title> 26.357 + 26.358 + <para id="x_21f">You can write a hook either as a normal 26.359 + program&emdash;typically a shell script&emdash;or as a Python 26.360 + function that is executed within the Mercurial process. 26.361 + </para> 26.362 + 26.363 + <para id="x_220">Writing a hook as an external program has the advantage 26.364 + that it requires no knowledge of Mercurial's internals. You 26.365 + can call normal Mercurial commands to get any added 26.366 + information you need. The trade-off is that external hooks 26.367 + are slower than in-process hooks. 26.368 + </para> 26.369 + 26.370 + <para id="x_221">An in-process Python hook has complete access to the 26.371 + Mercurial API, and does not <quote>shell out</quote> to 26.372 + another process, so it is inherently faster than an external 26.373 + hook. It is also easier to obtain much of the information 26.374 + that a hook requires by using the Mercurial API than by 26.375 + running Mercurial commands. 26.376 + </para> 26.377 + 26.378 + <para id="x_222">If you are comfortable with Python, or require high 26.379 + performance, writing your hooks in Python may be a good 26.380 + choice. However, when you have a straightforward hook to 26.381 + write and you don't need to care about performance (probably 26.382 + the majority of hooks), a shell script is perfectly fine. 26.383 + </para> 26.384 + 26.385 + </sect2> 26.386 + <sect2 id="sec:hook:param"> 26.387 + <title>Hook parameters</title> 26.388 + 26.389 + <para id="x_223">Mercurial calls each hook with a set of well-defined 26.390 + parameters. In Python, a parameter is passed as a keyword 26.391 + argument to your hook function. For an external program, a 26.392 + parameter is passed as an environment variable. 26.393 + </para> 26.394 + 26.395 + <para id="x_224">Whether your hook is written in Python or as a shell 26.396 + script, the hook-specific parameter names and values will be 26.397 + the same. A boolean parameter will be represented as a 26.398 + boolean value in Python, but as the number 1 (for 26.399 + <quote>true</quote>) or 0 (for <quote>false</quote>) as an 26.400 + environment variable for an external hook. If a hook 26.401 + parameter is named <literal>foo</literal>, the keyword 26.402 + argument for a Python hook will also be named 26.403 + <literal>foo</literal>, while the environment variable for an 26.404 + external hook will be named <literal>HG_FOO</literal>. 26.405 + </para> 26.406 + </sect2> 26.407 + 26.408 + <sect2> 26.409 + <title>Hook return values and activity control</title> 26.410 + 26.411 + <para id="x_225">A hook that executes successfully must exit with a status 26.412 + of zero if external, or return boolean <quote>false</quote> if 26.413 + in-process. Failure is indicated with a non-zero exit status 26.414 + from an external hook, or an in-process hook returning boolean 26.415 + <quote>true</quote>. If an in-process hook raises an 26.416 + exception, the hook is considered to have failed. 26.417 + </para> 26.418 + 26.419 + <para id="x_226">For a hook that controls whether an activity can proceed, 26.420 + zero/false means <quote>allow</quote>, while 26.421 + non-zero/true/exception means <quote>deny</quote>. 26.422 + </para> 26.423 + </sect2> 26.424 + 26.425 + <sect2> 26.426 + <title>Writing an external hook</title> 26.427 + 26.428 + <para id="x_227">When you define an external hook in your <filename 26.429 + role="special">~/.hgrc</filename> and the hook is run, its 26.430 + value is passed to your shell, which interprets it. This 26.431 + means that you can use normal shell constructs in the body of 26.432 + the hook. 26.433 + </para> 26.434 + 26.435 + <para id="x_228">An executable hook is always run with its current 26.436 + directory set to a repository's root directory. 26.437 + </para> 26.438 + 26.439 + <para id="x_229">Each hook parameter is passed in as an environment 26.440 + variable; the name is upper-cased, and prefixed with the 26.441 + string <quote><literal>HG_</literal></quote>. 26.442 + </para> 26.443 + 26.444 + <para id="x_22a">With the exception of hook parameters, Mercurial does not 26.445 + set or modify any environment variables when running a hook. 26.446 + This is useful to remember if you are writing a site-wide hook 26.447 + that may be run by a number of different users with differing 26.448 + environment variables set. In multi-user situations, you 26.449 + should not rely on environment variables being set to the 26.450 + values you have in your environment when testing the hook. 26.451 + </para> 26.452 + </sect2> 26.453 + 26.454 + <sect2> 26.455 + <title>Telling Mercurial to use an in-process hook</title> 26.456 + 26.457 + <para id="x_22b">The <filename role="special">~/.hgrc</filename> syntax 26.458 + for defining an in-process hook is slightly different than for 26.459 + an executable hook. The value of the hook must start with the 26.460 + text <quote><literal>python:</literal></quote>, and continue 26.461 + with the fully-qualified name of a callable object to use as 26.462 + the hook's value. 26.463 + </para> 26.464 + 26.465 + <para id="x_22c">The module in which a hook lives is automatically imported 26.466 + when a hook is run. So long as you have the module name and 26.467 + <envar>PYTHONPATH</envar> right, it should <quote>just 26.468 + work</quote>. 26.469 + </para> 26.470 + 26.471 + <para id="x_22d">The following <filename role="special">~/.hgrc</filename> 26.472 + example snippet illustrates the syntax and meaning of the 26.473 + notions we just described. 26.474 + </para> 26.475 + <programlisting>[hooks] 26.476 +commit.example = python:mymodule.submodule.myhook</programlisting> 26.477 + <para id="x_22e">When Mercurial runs the <literal>commit.example</literal> 26.478 + hook, it imports <literal>mymodule.submodule</literal>, looks 26.479 + for the callable object named <literal>myhook</literal>, and 26.480 + calls it. 26.481 + </para> 26.482 + </sect2> 26.483 + 26.484 + <sect2> 26.485 + <title>Writing an in-process hook</title> 26.486 + 26.487 + <para id="x_22f">The simplest in-process hook does nothing, but illustrates 26.488 + the basic shape of the hook API: 26.489 + </para> 26.490 + <programlisting>def myhook(ui, repo, **kwargs): 26.491 + pass</programlisting> 26.492 + <para id="x_230">The first argument to a Python hook is always a <literal 26.493 + role="py-mod-mercurial.ui">ui</literal> object. The second 26.494 + is a repository object; at the moment, it is always an 26.495 + instance of <literal 26.496 + role="py-mod-mercurial.localrepo">localrepository</literal>. 26.497 + Following these two arguments are other keyword arguments. 26.498 + Which ones are passed in depends on the hook being called, but 26.499 + a hook can ignore arguments it doesn't care about by dropping 26.500 + them into a keyword argument dict, as with 26.501 + <literal>**kwargs</literal> above. 26.502 + </para> 26.503 + 26.504 + </sect2> 26.505 + </sect1> 26.506 + <sect1> 26.507 + <title>Some hook examples</title> 26.508 + 26.509 + <sect2> 26.510 + <title>Writing meaningful commit messages</title> 26.511 + 26.512 + <para id="x_231">It's hard to imagine a useful commit message being very 26.513 + short. The simple <literal role="hook">pretxncommit</literal> 26.514 + hook of the example below will prevent you from committing a 26.515 + changeset with a message that is less than ten bytes long. 26.516 + </para> 26.517 + 26.518 +&interaction.hook.msglen.go; 26.519 + </sect2> 26.520 + 26.521 + <sect2> 26.522 + <title>Checking for trailing whitespace</title> 26.523 + 26.524 + <para id="x_232">An interesting use of a commit-related hook is to help you 26.525 + to write cleaner code. A simple example of <quote>cleaner 26.526 + code</quote> is the dictum that a change should not add any 26.527 + new lines of text that contain <quote>trailing 26.528 + whitespace</quote>. Trailing whitespace is a series of 26.529 + space and tab characters at the end of a line of text. In 26.530 + most cases, trailing whitespace is unnecessary, invisible 26.531 + noise, but it is occasionally problematic, and people often 26.532 + prefer to get rid of it. 26.533 + </para> 26.534 + 26.535 + <para id="x_233">You can use either the <literal 26.536 + role="hook">precommit</literal> or <literal 26.537 + role="hook">pretxncommit</literal> hook to tell whether you 26.538 + have a trailing whitespace problem. If you use the <literal 26.539 + role="hook">precommit</literal> hook, the hook will not know 26.540 + which files you are committing, so it will have to check every 26.541 + modified file in the repository for trailing white space. If 26.542 + you want to commit a change to just the file 26.543 + <filename>foo</filename>, but the file 26.544 + <filename>bar</filename> contains trailing whitespace, doing a 26.545 + check in the <literal role="hook">precommit</literal> hook 26.546 + will prevent you from committing <filename>foo</filename> due 26.547 + to the problem with <filename>bar</filename>. This doesn't 26.548 + seem right. 26.549 + </para> 26.550 + 26.551 + <para id="x_234">Should you choose the <literal 26.552 + role="hook">pretxncommit</literal> hook, the check won't 26.553 + occur until just before the transaction for the commit 26.554 + completes. This will allow you to check for problems only the 26.555 + exact files that are being committed. However, if you entered 26.556 + the commit message interactively and the hook fails, the 26.557 + transaction will roll back; you'll have to re-enter the commit 26.558 + message after you fix the trailing whitespace and run <command 26.559 + role="hg-cmd">hg commit</command> again. 26.560 + </para> 26.561 + 26.562 + &interaction.ch09-hook.ws.simple; 26.563 + 26.564 + <para id="x_235">In this example, we introduce a simple <literal 26.565 + role="hook">pretxncommit</literal> hook that checks for 26.566 + trailing whitespace. This hook is short, but not very 26.567 + helpful. It exits with an error status if a change adds a 26.568 + line with trailing whitespace to any file, but does not print 26.569 + any information that might help us to identify the offending 26.570 + file or line. It also has the nice property of not paying 26.571 + attention to unmodified lines; only lines that introduce new 26.572 + trailing whitespace cause problems. 26.573 + </para> 26.574 + 26.575 + &ch09-check_whitespace.py.lst; 26.576 + 26.577 + <para id="x_236">The above version is much more complex, but also more 26.578 + useful. It parses a unified diff to see if any lines add 26.579 + trailing whitespace, and prints the name of the file and the 26.580 + line number of each such occurrence. Even better, if the 26.581 + change adds trailing whitespace, this hook saves the commit 26.582 + comment and prints the name of the save file before exiting 26.583 + and telling Mercurial to roll the transaction back, so you can 26.584 + use the <option role="hg-opt-commit">-l filename</option> 26.585 + option to <command role="hg-cmd">hg commit</command> to reuse 26.586 + the saved commit message once you've corrected the problem. 26.587 + </para> 26.588 + 26.589 + &interaction.ch09-hook.ws.better; 26.590 + 26.591 + <para id="x_237">As a final aside, note in the example above the 26.592 + use of <command>sed</command>'s in-place editing feature to 26.593 + get rid of trailing whitespace from a file. This is concise 26.594 + and useful enough that I will reproduce it here (using 26.595 + <command>perl</command> for good measure).</para> 26.596 + <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting> 26.597 + 26.598 + </sect2> 26.599 + </sect1> 26.600 + <sect1> 26.601 + <title>Bundled hooks</title> 26.602 + 26.603 + <para id="x_238">Mercurial ships with several bundled hooks. You can find 26.604 + them in the <filename class="directory">hgext</filename> 26.605 + directory of a Mercurial source tree. If you are using a 26.606 + Mercurial binary package, the hooks will be located in the 26.607 + <filename class="directory">hgext</filename> directory of 26.608 + wherever your package installer put Mercurial. 26.609 + </para> 26.610 + 26.611 + <sect2> 26.612 + <title><literal role="hg-ext">acl</literal>&emdash;access 26.613 + control for parts of a repository</title> 26.614 + 26.615 + <para id="x_239">The <literal role="hg-ext">acl</literal> extension lets 26.616 + you control which remote users are allowed to push changesets 26.617 + to a networked server. You can protect any portion of a 26.618 + repository (including the entire repo), so that a specific 26.619 + remote user can push changes that do not affect the protected 26.620 + portion. 26.621 + </para> 26.622 + 26.623 + <para id="x_23a">This extension implements access control based on the 26.624 + identity of the user performing a push, 26.625 + <emphasis>not</emphasis> on who committed the changesets 26.626 + they're pushing. It makes sense to use this hook only if you 26.627 + have a locked-down server environment that authenticates 26.628 + remote users, and you want to be sure that only specific users 26.629 + are allowed to push changes to that server. 26.630 + </para> 26.631 + 26.632 + <sect3> 26.633 + <title>Configuring the <literal role="hook">acl</literal> 26.634 + hook</title> 26.635 + 26.636 + <para id="x_23b">In order to manage incoming changesets, the <literal 26.637 + role="hg-ext">acl</literal> hook must be used as a 26.638 + <literal role="hook">pretxnchangegroup</literal> hook. This 26.639 + lets it see which files are modified by each incoming 26.640 + changeset, and roll back a group of changesets if they 26.641 + modify <quote>forbidden</quote> files. Example: 26.642 + </para> 26.643 + <programlisting>[hooks] 26.644 +pretxnchangegroup.acl = python:hgext.acl.hook</programlisting> 26.645 + 26.646 + <para id="x_23c">The <literal role="hg-ext">acl</literal> extension is 26.647 + configured using three sections. 26.648 + </para> 26.649 + 26.650 + <para id="x_23d">The <literal role="rc-acl">acl</literal> section has 26.651 + only one entry, <envar role="rc-item-acl">sources</envar>, 26.652 + which lists the sources of incoming changesets that the hook 26.653 + should pay attention to. You don't normally need to 26.654 + configure this section. 26.655 + </para> 26.656 + <itemizedlist> 26.657 + <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>: 26.658 + Control incoming changesets that are arriving from a 26.659 + remote repository over http or ssh. This is the default 26.660 + value of <envar role="rc-item-acl">sources</envar>, and 26.661 + usually the only setting you'll need for this 26.662 + configuration item. 26.663 + </para> 26.664 + </listitem> 26.665 + <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>: 26.666 + Control incoming changesets that are arriving via a pull 26.667 + from a local repository. 26.668 + </para> 26.669 + </listitem> 26.670 + <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>: 26.671 + Control incoming changesets that are arriving via a push 26.672 + from a local repository. 26.673 + </para> 26.674 + </listitem> 26.675 + <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>: 26.676 + Control incoming changesets that are arriving from 26.677 + another repository via a bundle. 26.678 + </para> 26.679 + </listitem></itemizedlist> 26.680 + 26.681 + <para id="x_242">The <literal role="rc-acl.allow">acl.allow</literal> 26.682 + section controls the users that are allowed to add 26.683 + changesets to the repository. If this section is not 26.684 + present, all users that are not explicitly denied are 26.685 + allowed. If this section is present, all users that are not 26.686 + explicitly allowed are denied (so an empty section means 26.687 + that all users are denied). 26.688 + </para> 26.689 + 26.690 + <para id="x_243">The <literal role="rc-acl.deny">acl.deny</literal> 26.691 + section determines which users are denied from adding 26.692 + changesets to the repository. If this section is not 26.693 + present or is empty, no users are denied. 26.694 + </para> 26.695 + 26.696 + <para id="x_244">The syntaxes for the <literal 26.697 + role="rc-acl.allow">acl.allow</literal> and <literal 26.698 + role="rc-acl.deny">acl.deny</literal> sections are 26.699 + identical. On the left of each entry is a glob pattern that 26.700 + matches files or directories, relative to the root of the 26.701 + repository; on the right, a user name. 26.702 + </para> 26.703 + 26.704 + <para id="x_245">In the following example, the user 26.705 + <literal>docwriter</literal> can only push changes to the 26.706 + <filename class="directory">docs</filename> subtree of the 26.707 + repository, while <literal>intern</literal> can push changes 26.708 + to any file or directory except <filename 26.709 + class="directory">source/sensitive</filename>. 26.710 + </para> 26.711 + <programlisting>[acl.allow] 26.712 +docs/** = docwriter 26.713 +[acl.deny] 26.714 +source/sensitive/** = intern</programlisting> 26.715 + 26.716 + </sect3> 26.717 + <sect3> 26.718 + <title>Testing and troubleshooting</title> 26.719 + 26.720 + <para id="x_246">If you want to test the <literal 26.721 + role="hg-ext">acl</literal> hook, run it with Mercurial's 26.722 + debugging output enabled. Since you'll probably be running 26.723 + it on a server where it's not convenient (or sometimes 26.724 + possible) to pass in the <option 26.725 + role="hg-opt-global">--debug</option> option, don't forget 26.726 + that you can enable debugging output in your <filename 26.727 + role="special">~/.hgrc</filename>: 26.728 + </para> 26.729 + <programlisting>[ui] 26.730 +debug = true</programlisting> 26.731 + <para id="x_247">With this enabled, the <literal 26.732 + role="hg-ext">acl</literal> hook will print enough 26.733 + information to let you figure out why it is allowing or 26.734 + forbidding pushes from specific users. 26.735 + </para> 26.736 + 26.737 + </sect3> </sect2> 26.738 + 26.739 + <sect2> 26.740 + <title><literal 26.741 + role="hg-ext">bugzilla</literal>&emdash;integration with 26.742 + Bugzilla</title> 26.743 + 26.744 + <para id="x_248">The <literal role="hg-ext">bugzilla</literal> extension 26.745 + adds a comment to a Bugzilla bug whenever it finds a reference 26.746 + to that bug ID in a commit comment. You can install this hook 26.747 + on a shared server, so that any time a remote user pushes 26.748 + changes to this server, the hook gets run. 26.749 + </para> 26.750 + 26.751 + <para id="x_249">It adds a comment to the bug that looks like this (you can 26.752 + configure the contents of the comment&emdash;see below): 26.753 + </para> 26.754 + <programlisting>Changeset aad8b264143a, made by Joe User 26.755 + <joe.user@domain.com> in the frobnitz repository, refers 26.756 + to this bug. For complete details, see 26.757 + http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a 26.758 + Changeset description: Fix bug 10483 by guarding against some 26.759 + NULL pointers</programlisting> 26.760 + <para id="x_24a">The value of this hook is that it automates the process of 26.761 + updating a bug any time a changeset refers to it. If you 26.762 + configure the hook properly, it makes it easy for people to 26.763 + browse straight from a Bugzilla bug to a changeset that refers 26.764 + to that bug. 26.765 + </para> 26.766 + 26.767 + <para id="x_24b">You can use the code in this hook as a starting point for 26.768 + some more exotic Bugzilla integration recipes. Here are a few 26.769 + possibilities: 26.770 + </para> 26.771 + <itemizedlist> 26.772 + <listitem><para id="x_24c">Require that every changeset pushed to the 26.773 + server have a valid bug ID in its commit comment. In this 26.774 + case, you'd want to configure the hook as a <literal 26.775 + role="hook">pretxncommit</literal> hook. This would 26.776 + allow the hook to reject changes that didn't contain bug 26.777 + IDs. 26.778 + </para> 26.779 + </listitem> 26.780 + <listitem><para id="x_24d">Allow incoming changesets to automatically 26.781 + modify the <emphasis>state</emphasis> of a bug, as well as 26.782 + simply adding a comment. For example, the hook could 26.783 + recognise the string <quote>fixed bug 31337</quote> as 26.784 + indicating that it should update the state of bug 31337 to 26.785 + <quote>requires testing</quote>. 26.786 + </para> 26.787 + </listitem></itemizedlist> 26.788 + 26.789 + <sect3 id="sec:hook:bugzilla:config"> 26.790 + <title>Configuring the <literal role="hook">bugzilla</literal> 26.791 + hook</title> 26.792 + 26.793 + <para id="x_24e">You should configure this hook in your server's 26.794 + <filename role="special">~/.hgrc</filename> as an <literal 26.795 + role="hook">incoming</literal> hook, for example as 26.796 + follows: 26.797 + </para> 26.798 + <programlisting>[hooks] 26.799 +incoming.bugzilla = python:hgext.bugzilla.hook</programlisting> 26.800 + 26.801 + <para id="x_24f">Because of the specialised nature of this hook, and 26.802 + because Bugzilla was not written with this kind of 26.803 + integration in mind, configuring this hook is a somewhat 26.804 + involved process. 26.805 + </para> 26.806 + 26.807 + <para id="x_250">Before you begin, you must install the MySQL bindings 26.808 + for Python on the host(s) where you'll be running the hook. 26.809 + If this is not available as a binary package for your 26.810 + system, you can download it from 26.811 + <citation>web:mysql-python</citation>. 26.812 + </para> 26.813 + 26.814 + <para id="x_251">Configuration information for this hook lives in the 26.815 + <literal role="rc-bugzilla">bugzilla</literal> section of 26.816 + your <filename role="special">~/.hgrc</filename>. 26.817 + </para> 26.818 + <itemizedlist> 26.819 + <listitem><para id="x_252"><envar 26.820 + role="rc-item-bugzilla">version</envar>: The version 26.821 + of Bugzilla installed on the server. The database 26.822 + schema that Bugzilla uses changes occasionally, so this 26.823 + hook has to know exactly which schema to use.</para> 26.824 + </listitem> 26.825 + <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>: 26.826 + The hostname of the MySQL server that stores your 26.827 + Bugzilla data. The database must be configured to allow 26.828 + connections from whatever host you are running the 26.829 + <literal role="hook">bugzilla</literal> hook on. 26.830 + </para> 26.831 + </listitem> 26.832 + <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>: 26.833 + The username with which to connect to the MySQL server. 26.834 + The database must be configured to allow this user to 26.835 + connect from whatever host you are running the <literal 26.836 + role="hook">bugzilla</literal> hook on. This user 26.837 + must be able to access and modify Bugzilla tables. The 26.838 + default value of this item is <literal>bugs</literal>, 26.839 + which is the standard name of the Bugzilla user in a 26.840 + MySQL database. 26.841 + </para> 26.842 + </listitem> 26.843 + <listitem><para id="x_255"><envar 26.844 + role="rc-item-bugzilla">password</envar>: The MySQL 26.845 + password for the user you configured above. This is 26.846 + stored as plain text, so you should make sure that 26.847 + unauthorised users cannot read the <filename 26.848 + role="special">~/.hgrc</filename> file where you 26.849 + store this information. 26.850 + </para> 26.851 + </listitem> 26.852 + <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>: 26.853 + The name of the Bugzilla database on the MySQL server. 26.854 + The default value of this item is 26.855 + <literal>bugs</literal>, which is the standard name of 26.856 + the MySQL database where Bugzilla stores its data. 26.857 + </para> 26.858 + </listitem> 26.859 + <listitem><para id="x_257"><envar 26.860 + role="rc-item-bugzilla">notify</envar>: If you want 26.861 + Bugzilla to send out a notification email to subscribers 26.862 + after this hook has added a comment to a bug, you will 26.863 + need this hook to run a command whenever it updates the 26.864 + database. The command to run depends on where you have 26.865 + installed Bugzilla, but it will typically look something 26.866 + like this, if you have Bugzilla installed in <filename 26.867 + class="directory">/var/www/html/bugzilla</filename>: 26.868 + </para> 26.869 + <programlisting>cd /var/www/html/bugzilla && 26.870 + ./processmail %s nobody@nowhere.com</programlisting> 26.871 + </listitem> 26.872 + <listitem><para id="x_258"> The Bugzilla 26.873 + <literal>processmail</literal> program expects to be 26.874 + given a bug ID (the hook replaces 26.875 + <quote><literal>%s</literal></quote> with the bug ID) 26.876 + and an email address. It also expects to be able to 26.877 + write to some files in the directory that it runs in. 26.878 + If Bugzilla and this hook are not installed on the same 26.879 + machine, you will need to find a way to run 26.880 + <literal>processmail</literal> on the server where 26.881 + Bugzilla is installed. 26.882 + </para> 26.883 + </listitem></itemizedlist> 26.884 + 26.885 + </sect3> 26.886 + <sect3> 26.887 + <title>Mapping committer names to Bugzilla user names</title> 26.888 + 26.889 + <para id="x_259">By default, the <literal 26.890 + role="hg-ext">bugzilla</literal> hook tries to use the 26.891 + email address of a changeset's committer as the Bugzilla 26.892 + user name with which to update a bug. If this does not suit 26.893 + your needs, you can map committer email addresses to 26.894 + Bugzilla user names using a <literal 26.895 + role="rc-usermap">usermap</literal> section. 26.896 + </para> 26.897 + 26.898 + <para id="x_25a">Each item in the <literal 26.899 + role="rc-usermap">usermap</literal> section contains an 26.900 + email address on the left, and a Bugzilla user name on the 26.901 + right. 26.902 + </para> 26.903 + <programlisting>[usermap] 26.904 +jane.user@example.com = jane</programlisting> 26.905 + <para id="x_25b">You can either keep the <literal 26.906 + role="rc-usermap">usermap</literal> data in a normal 26.907 + <filename role="special">~/.hgrc</filename>, or tell the 26.908 + <literal role="hg-ext">bugzilla</literal> hook to read the 26.909 + information from an external <filename>usermap</filename> 26.910 + file. In the latter case, you can store 26.911 + <filename>usermap</filename> data by itself in (for example) 26.912 + a user-modifiable repository. This makes it possible to let 26.913 + your users maintain their own <envar 26.914 + role="rc-item-bugzilla">usermap</envar> entries. The main 26.915 + <filename role="special">~/.hgrc</filename> file might look 26.916 + like this: 26.917 + </para> 26.918 + <programlisting># regular hgrc file refers to external usermap file 26.919 +[bugzilla] 26.920 +usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting> 26.921 + <para id="x_25c">While the <filename>usermap</filename> file that it 26.922 + refers to might look like this: 26.923 + </para> 26.924 + <programlisting># bugzilla-usermap.conf - inside a hg repository 26.925 +[usermap] stephanie@example.com = steph</programlisting> 26.926 + 26.927 + </sect3> 26.928 + <sect3> 26.929 + <title>Configuring the text that gets added to a bug</title> 26.930 + 26.931 + <para id="x_25d">You can configure the text that this hook adds as a 26.932 + comment; you specify it in the form of a Mercurial template. 26.933 + Several <filename role="special">~/.hgrc</filename> entries 26.934 + (still in the <literal role="rc-bugzilla">bugzilla</literal> 26.935 + section) control this behavior. 26.936 + </para> 26.937 + <itemizedlist> 26.938 + <listitem><para id="x_25e"><literal>strip</literal>: The number of 26.939 + leading path elements to strip from a repository's path 26.940 + name to construct a partial path for a URL. For example, 26.941 + if the repositories on your server live under <filename 26.942 + class="directory">/home/hg/repos</filename>, and you 26.943 + have a repository whose path is <filename 26.944 + class="directory">/home/hg/repos/app/tests</filename>, 26.945 + then setting <literal>strip</literal> to 26.946 + <literal>4</literal> will give a partial path of 26.947 + <filename class="directory">app/tests</filename>. The 26.948 + hook will make this partial path available when 26.949 + expanding a template, as <literal>webroot</literal>. 26.950 + </para> 26.951 + </listitem> 26.952 + <listitem><para id="x_25f"><literal>template</literal>: The text of the 26.953 + template to use. In addition to the usual 26.954 + changeset-related variables, this template can use 26.955 + <literal>hgweb</literal> (the value of the 26.956 + <literal>hgweb</literal> configuration item above) and 26.957 + <literal>webroot</literal> (the path constructed using 26.958 + <literal>strip</literal> above). 26.959 + </para> 26.960 + </listitem></itemizedlist> 26.961 + 26.962 + <para id="x_260">In addition, you can add a <envar 26.963 + role="rc-item-web">baseurl</envar> item to the <literal 26.964 + role="rc-web">web</literal> section of your <filename 26.965 + role="special">~/.hgrc</filename>. The <literal 26.966 + role="hg-ext">bugzilla</literal> hook will make this 26.967 + available when expanding a template, as the base string to 26.968 + use when constructing a URL that will let users browse from 26.969 + a Bugzilla comment to view a changeset. Example: 26.970 + </para> 26.971 + <programlisting>[web] 26.972 +baseurl = http://hg.domain.com/</programlisting> 26.973 + 26.974 + <para id="x_261">Here is an example set of <literal 26.975 + role="hg-ext">bugzilla</literal> hook config information. 26.976 + </para> 26.977 + 26.978 + &ch10-bugzilla-config.lst; 26.979 + 26.980 + </sect3> 26.981 + <sect3> 26.982 + <title>Testing and troubleshooting</title> 26.983 + 26.984 + <para id="x_262">The most common problems with configuring the <literal 26.985 + role="hg-ext">bugzilla</literal> hook relate to running 26.986 + Bugzilla's <filename>processmail</filename> script and 26.987 + mapping committer names to user names. 26.988 + </para> 26.989 + 26.990 + <para id="x_263">Recall from <xref 26.991 + linkend="sec:hook:bugzilla:config"/> above that the user 26.992 + that runs the Mercurial process on the server is also the 26.993 + one that will run the <filename>processmail</filename> 26.994 + script. The <filename>processmail</filename> script 26.995 + sometimes causes Bugzilla to write to files in its 26.996 + configuration directory, and Bugzilla's configuration files 26.997 + are usually owned by the user that your web server runs 26.998 + under. 26.999 + </para> 26.1000 + 26.1001 + <para id="x_264">You can cause <filename>processmail</filename> to be run 26.1002 + with the suitable user's identity using the 26.1003 + <command>sudo</command> command. Here is an example entry 26.1004 + for a <filename>sudoers</filename> file. 26.1005 + </para> 26.1006 + <programlisting>hg_user = (httpd_user) 26.1007 +NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting> 26.1008 + <para id="x_265">This allows the <literal>hg_user</literal> user to run a 26.1009 + <filename>processmail-wrapper</filename> program under the 26.1010 + identity of <literal>httpd_user</literal>. 26.1011 + </para> 26.1012 + 26.1013 + <para id="x_266">This indirection through a wrapper script is necessary, 26.1014 + because <filename>processmail</filename> expects to be run 26.1015 + with its current directory set to wherever you installed 26.1016 + Bugzilla; you can't specify that kind of constraint in a 26.1017 + <filename>sudoers</filename> file. The contents of the 26.1018 + wrapper script are simple: 26.1019 + </para> 26.1020 + <programlisting>#!/bin/sh 26.1021 +cd `dirname $0` && ./processmail "$1" nobody@example.com</programlisting> 26.1022 + <para id="x_267">It doesn't seem to matter what email address you pass to 26.1023 + <filename>processmail</filename>. 26.1024 + </para> 26.1025 + 26.1026 + <para id="x_268">If your <literal role="rc-usermap">usermap</literal> is 26.1027 + not set up correctly, users will see an error message from 26.1028 + the <literal role="hg-ext">bugzilla</literal> hook when they 26.1029 + push changes to the server. The error message will look 26.1030 + like this: 26.1031 + </para> 26.1032 + <programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting> 26.1033 + <para id="x_269">What this means is that the committer's address, 26.1034 + <literal>john.q.public@example.com</literal>, is not a valid 26.1035 + Bugzilla user name, nor does it have an entry in your 26.1036 + <literal role="rc-usermap">usermap</literal> that maps it to 26.1037 + a valid Bugzilla user name. 26.1038 + </para> 26.1039 + 26.1040 + </sect3> </sect2> 26.1041 + 26.1042 + <sect2> 26.1043 + <title><literal role="hg-ext">notify</literal>&emdash;send email 26.1044 + notifications</title> 26.1045 + 26.1046 + <para id="x_26a">Although Mercurial's built-in web server provides RSS 26.1047 + feeds of changes in every repository, many people prefer to 26.1048 + receive change notifications via email. The <literal 26.1049 + role="hg-ext">notify</literal> hook lets you send out 26.1050 + notifications to a set of email addresses whenever changesets 26.1051 + arrive that those subscribers are interested in. 26.1052 + </para> 26.1053 + 26.1054 + <para id="x_26b">As with the <literal role="hg-ext">bugzilla</literal> 26.1055 + hook, the <literal role="hg-ext">notify</literal> hook is 26.1056 + template-driven, so you can customise the contents of the 26.1057 + notification messages that it sends. 26.1058 + </para> 26.1059 + 26.1060 + <para id="x_26c">By default, the <literal role="hg-ext">notify</literal> 26.1061 + hook includes a diff of every changeset that it sends out; you 26.1062 + can limit the size of the diff, or turn this feature off 26.1063 + entirely. It is useful for letting subscribers review changes 26.1064 + immediately, rather than clicking to follow a URL. 26.1065 + </para> 26.1066 + 26.1067 + <sect3> 26.1068 + <title>Configuring the <literal role="hg-ext">notify</literal> 26.1069 + hook</title> 26.1070 + 26.1071 + <para id="x_26d">You can set up the <literal 26.1072 + role="hg-ext">notify</literal> hook to send one email 26.1073 + message per incoming changeset, or one per incoming group of 26.1074 + changesets (all those that arrived in a single pull or 26.1075 + push). 26.1076 + </para> 26.1077 + <programlisting>[hooks] 26.1078 +# send one email per group of changes 26.1079 +changegroup.notify = python:hgext.notify.hook 26.1080 +# send one email per change 26.1081 +incoming.notify = python:hgext.notify.hook</programlisting> 26.1082 + 26.1083 + <para id="x_26e">Configuration information for this hook lives in the 26.1084 + <literal role="rc-notify">notify</literal> section of a 26.1085 + <filename role="special">~/.hgrc</filename> file. 26.1086 + </para> 26.1087 + <itemizedlist> 26.1088 + <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>: 26.1089 + By default, this hook does not send out email at all; 26.1090 + instead, it prints the message that it 26.1091 + <emphasis>would</emphasis> send. Set this item to 26.1092 + <literal>false</literal> to allow email to be sent. The 26.1093 + reason that sending of email is turned off by default is 26.1094 + that it takes several tries to configure this extension 26.1095 + exactly as you would like, and it would be bad form to 26.1096 + spam subscribers with a number of <quote>broken</quote> 26.1097 + notifications while you debug your configuration. 26.1098 + </para> 26.1099 + </listitem> 26.1100 + <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>: 26.1101 + The path to a configuration file that contains 26.1102 + subscription information. This is kept separate from 26.1103 + the main <filename role="special">~/.hgrc</filename> so 26.1104 + that you can maintain it in a repository of its own. 26.1105 + People can then clone that repository, update their 26.1106 + subscriptions, and push the changes back to your server. 26.1107 + </para> 26.1108 + </listitem> 26.1109 + <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>: 26.1110 + The number of leading path separator characters to strip 26.1111 + from a repository's path, when deciding whether a 26.1112 + repository has subscribers. For example, if the 26.1113 + repositories on your server live in <filename 26.1114 + class="directory">/home/hg/repos</filename>, and 26.1115 + <literal role="hg-ext">notify</literal> is considering a 26.1116 + repository named <filename 26.1117 + class="directory">/home/hg/repos/shared/test</filename>, 26.1118 + setting <envar role="rc-item-notify">strip</envar> to 26.1119 + <literal>4</literal> will cause <literal 26.1120 + role="hg-ext">notify</literal> to trim the path it 26.1121 + considers down to <filename 26.1122 + class="directory">shared/test</filename>, and it will 26.1123 + match subscribers against that. 26.1124 + </para> 26.1125 + </listitem> 26.1126 + <listitem><para id="x_272"><envar 26.1127 + role="rc-item-notify">template</envar>: The template 26.1128 + text to use when sending messages. This specifies both 26.1129 + the contents of the message header and its body. 26.1130 + </para> 26.1131 + </listitem> 26.1132 + <listitem><para id="x_273"><envar 26.1133 + role="rc-item-notify">maxdiff</envar>: The maximum 26.1134 + number of lines of diff data to append to the end of a 26.1135 + message. If a diff is longer than this, it is 26.1136 + truncated. By default, this is set to 300. Set this to 26.1137 + <literal>0</literal> to omit diffs from notification 26.1138 + emails. 26.1139 + </para> 26.1140 + </listitem> 26.1141 + <listitem><para id="x_274"><envar 26.1142 + role="rc-item-notify">sources</envar>: A list of 26.1143 + sources of changesets to consider. This lets you limit 26.1144 + <literal role="hg-ext">notify</literal> to only sending 26.1145 + out email about changes that remote users pushed into 26.1146 + this repository via a server, for example. See 26.1147 + <xref linkend="sec:hook:sources"/> for the sources you 26.1148 + can specify here. 26.1149 + </para> 26.1150 + </listitem></itemizedlist> 26.1151 + 26.1152 + <para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar> 26.1153 + item in the <literal role="rc-web">web</literal> section, 26.1154 + you can use it in a template; it will be available as 26.1155 + <literal>webroot</literal>. 26.1156 + </para> 26.1157 + 26.1158 + <para id="x_276">Here is an example set of <literal 26.1159 + role="hg-ext">notify</literal> configuration information. 26.1160 + </para> 26.1161 + 26.1162 + &ch10-notify-config.lst; 26.1163 + 26.1164 + <para id="x_277">This will produce a message that looks like the 26.1165 + following: 26.1166 + </para> 26.1167 + 26.1168 + &ch10-notify-config-mail.lst; 26.1169 + 26.1170 + </sect3> 26.1171 + <sect3> 26.1172 + <title>Testing and troubleshooting</title> 26.1173 + 26.1174 + <para id="x_278">Do not forget that by default, the <literal 26.1175 + role="hg-ext">notify</literal> extension <emphasis>will not 26.1176 + send any mail</emphasis> until you explicitly configure it to do so, 26.1177 + by setting <envar role="rc-item-notify">test</envar> to 26.1178 + <literal>false</literal>. Until you do that, it simply 26.1179 + prints the message it <emphasis>would</emphasis> send. 26.1180 + </para> 26.1181 + 26.1182 + </sect3> 26.1183 + </sect2> 26.1184 + </sect1> 26.1185 + <sect1 id="sec:hook:ref"> 26.1186 + <title>Information for writers of hooks</title> 26.1187 + 26.1188 + <sect2> 26.1189 + <title>In-process hook execution</title> 26.1190 + 26.1191 + <para id="x_279">An in-process hook is called with arguments of the 26.1192 + following form: 26.1193 + </para> 26.1194 + <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting> 26.1195 + <para id="x_27a">The <literal>ui</literal> parameter is a <literal 26.1196 + role="py-mod-mercurial.ui">ui</literal> object. The 26.1197 + <literal>repo</literal> parameter is a <literal 26.1198 + role="py-mod-mercurial.localrepo">localrepository</literal> 26.1199 + object. The names and values of the 26.1200 + <literal>**kwargs</literal> parameters depend on the hook 26.1201 + being invoked, with the following common features: 26.1202 + </para> 26.1203 + <itemizedlist> 26.1204 + <listitem><para id="x_27b">If a parameter is named 26.1205 + <literal>node</literal> or <literal>parentN</literal>, it 26.1206 + will contain a hexadecimal changeset ID. The empty string 26.1207 + is used to represent <quote>null changeset ID</quote> 26.1208 + instead of a string of zeroes. 26.1209 + </para> 26.1210 + </listitem> 26.1211 + <listitem><para id="x_27c">If a parameter is named 26.1212 + <literal>url</literal>, it will contain the URL of a 26.1213 + remote repository, if that can be determined. 26.1214 + </para> 26.1215 + </listitem> 26.1216 + <listitem><para id="x_27d">Boolean-valued parameters are represented as 26.1217 + Python <literal>bool</literal> objects. 26.1218 + </para> 26.1219 + </listitem></itemizedlist> 26.1220 + 26.1221 + <para id="x_27e">An in-process hook is called without a change to the 26.1222 + process's working directory (unlike external hooks, which are 26.1223 + run in the root of the repository). It must not change the 26.1224 + process's working directory, or it will cause any calls it 26.1225 + makes into the Mercurial API to fail. 26.1226 + </para> 26.1227 + 26.1228 + <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it 26.1229 + is considered to have succeeded. If it returns a boolean 26.1230 + <quote>true</quote> value or raises an exception, it is 26.1231 + considered to have failed. A useful way to think of the 26.1232 + calling convention is <quote>tell me if you fail</quote>. 26.1233 + </para> 26.1234 + 26.1235 + <para id="x_280">Note that changeset IDs are passed into Python hooks as 26.1236 + hexadecimal strings, not the binary hashes that Mercurial's 26.1237 + APIs normally use. To convert a hash from hex to binary, use 26.1238 + the <literal>bin</literal> function. 26.1239 + </para> 26.1240 + </sect2> 26.1241 + 26.1242 + <sect2> 26.1243 + <title>External hook execution</title> 26.1244 + 26.1245 + <para id="x_281">An external hook is passed to the shell of the user 26.1246 + running Mercurial. Features of that shell, such as variable 26.1247 + substitution and command redirection, are available. The hook 26.1248 + is run in the root directory of the repository (unlike 26.1249 + in-process hooks, which are run in the same directory that 26.1250 + Mercurial was run in). 26.1251 + </para> 26.1252 + 26.1253 + <para id="x_282">Hook parameters are passed to the hook as environment 26.1254 + variables. Each environment variable's name is converted in 26.1255 + upper case and prefixed with the string 26.1256 + <quote><literal>HG_</literal></quote>. For example, if the 26.1257 + name of a parameter is <quote><literal>node</literal></quote>, 26.1258 + the name of the environment variable representing that 26.1259 + parameter will be <quote><literal>HG_NODE</literal></quote>. 26.1260 + </para> 26.1261 + 26.1262 + <para id="x_283">A boolean parameter is represented as the string 26.1263 + <quote><literal>1</literal></quote> for <quote>true</quote>, 26.1264 + <quote><literal>0</literal></quote> for <quote>false</quote>. 26.1265 + If an environment variable is named <envar>HG_NODE</envar>, 26.1266 + <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it 26.1267 + contains a changeset ID represented as a hexadecimal string. 26.1268 + The empty string is used to represent <quote>null changeset 26.1269 + ID</quote> instead of a string of zeroes. If an environment 26.1270 + variable is named <envar>HG_URL</envar>, it will contain the 26.1271 + URL of a remote repository, if that can be determined. 26.1272 + </para> 26.1273 + 26.1274 + <para id="x_284">If a hook exits with a status of zero, it is considered to 26.1275 + have succeeded. If it exits with a non-zero status, it is 26.1276 + considered to have failed. 26.1277 + </para> 26.1278 + </sect2> 26.1279 + 26.1280 + <sect2> 26.1281 + <title>Finding out where changesets come from</title> 26.1282 + 26.1283 + <para id="x_285">A hook that involves the transfer of changesets between a 26.1284 + local repository and another may be able to find out 26.1285 + information about the <quote>far side</quote>. Mercurial 26.1286 + knows <emphasis>how</emphasis> changes are being transferred, 26.1287 + and in many cases <emphasis>where</emphasis> they are being 26.1288 + transferred to or from. 26.1289 + </para> 26.1290 + 26.1291 + <sect3 id="sec:hook:sources"> 26.1292 + <title>Sources of changesets</title> 26.1293 + 26.1294 + <para id="x_286">Mercurial will tell a hook what means are, or were, used 26.1295 + to transfer changesets between repositories. This is 26.1296 + provided by Mercurial in a Python parameter named 26.1297 + <literal>source</literal>, or an environment variable named 26.1298 + <envar>HG_SOURCE</envar>. 26.1299 + </para> 26.1300 + 26.1301 + <itemizedlist> 26.1302 + <listitem><para id="x_287"><literal>serve</literal>: Changesets are 26.1303 + transferred to or from a remote repository over http or 26.1304 + ssh. 26.1305 + </para> 26.1306 + </listitem> 26.1307 + <listitem><para id="x_288"><literal>pull</literal>: Changesets are 26.1308 + being transferred via a pull from one repository into 26.1309 + another. 26.1310 + </para> 26.1311 + </listitem> 26.1312 + <listitem><para id="x_289"><literal>push</literal>: Changesets are 26.1313 + being transferred via a push from one repository into 26.1314 + another. 26.1315 + </para> 26.1316 + </listitem> 26.1317 + <listitem><para id="x_28a"><literal>bundle</literal>: Changesets are 26.1318 + being transferred to or from a bundle. 26.1319 + </para> 26.1320 + </listitem></itemizedlist> 26.1321 + </sect3> 26.1322 + 26.1323 + <sect3 id="sec:hook:url"> 26.1324 + <title>Where changes are going&emdash;remote repository 26.1325 + URLs</title> 26.1326 + 26.1327 + <para id="x_28b">When possible, Mercurial will tell a hook the location 26.1328 + of the <quote>far side</quote> of an activity that transfers 26.1329 + changeset data between repositories. This is provided by 26.1330 + Mercurial in a Python parameter named 26.1331 + <literal>url</literal>, or an environment variable named 26.1332 + <envar>HG_URL</envar>. 26.1333 + </para> 26.1334 + 26.1335 + <para id="x_28c">This information is not always known. If a hook is 26.1336 + invoked in a repository that is being served via http or 26.1337 + ssh, Mercurial cannot tell where the remote repository is, 26.1338 + but it may know where the client is connecting from. In 26.1339 + such cases, the URL will take one of the following forms: 26.1340 + </para> 26.1341 + <itemizedlist> 26.1342 + <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 26.1343 + ssh client, at the IP address 26.1344 + <literal>1.2.3.4</literal>. 26.1345 + </para> 26.1346 + </listitem> 26.1347 + <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;remote 26.1348 + http client, at the IP address 26.1349 + <literal>1.2.3.4</literal>. If the client is using SSL, 26.1350 + this will be of the form 26.1351 + <literal>remote:https:1.2.3.4</literal>. 26.1352 + </para> 26.1353 + </listitem> 26.1354 + <listitem><para id="x_28f">Empty&emdash;no information could be 26.1355 + discovered about the remote client. 26.1356 + </para> 26.1357 + </listitem></itemizedlist> 26.1358 + </sect3> 26.1359 + </sect2> 26.1360 + </sect1> 26.1361 + <sect1> 26.1362 + <title>Hook reference</title> 26.1363 + 26.1364 + <sect2 id="sec:hook:changegroup"> 26.1365 + <title><literal role="hook">changegroup</literal>&emdash;after 26.1366 + remote changesets added</title> 26.1367 + 26.1368 + <para id="x_290">This hook is run after a group of pre-existing changesets 26.1369 + has been added to the repository, for example via a <command 26.1370 + role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg 26.1371 + unbundle</command>. This hook is run once per operation 26.1372 + that added one or more changesets. This is in contrast to the 26.1373 + <literal role="hook">incoming</literal> hook, which is run 26.1374 + once per changeset, regardless of whether the changesets 26.1375 + arrive in a group. 26.1376 + </para> 26.1377 + 26.1378 + <para id="x_291">Some possible uses for this hook include kicking off an 26.1379 + automated build or test of the added changesets, updating a 26.1380 + bug database, or notifying subscribers that a repository 26.1381 + contains new changes. 26.1382 + </para> 26.1383 + 26.1384 + <para id="x_292">Parameters to this hook: 26.1385 + </para> 26.1386 + <itemizedlist> 26.1387 + <listitem><para id="x_293"><literal>node</literal>: A changeset ID. The 26.1388 + changeset ID of the first changeset in the group that was 26.1389 + added. All changesets between this and 26.1390 + <literal role="tag">tip</literal>, inclusive, were added by a single 26.1391 + <command role="hg-cmd">hg pull</command>, <command 26.1392 + role="hg-cmd">hg push</command> or <command 26.1393 + role="hg-cmd">hg unbundle</command>. 26.1394 + </para> 26.1395 + </listitem> 26.1396 + <listitem><para id="x_294"><literal>source</literal>: A 26.1397 + string. The source of these changes. See <xref 26.1398 + linkend="sec:hook:sources"/> for details. 26.1399 + </para> 26.1400 + </listitem> 26.1401 + <listitem><para id="x_295"><literal>url</literal>: A URL. The 26.1402 + location of the remote repository, if known. See <xref 26.1403 + linkend="sec:hook:url"/> for more information. 26.1404 + </para> 26.1405 + </listitem></itemizedlist> 26.1406 + 26.1407 + <para id="x_296">See also: <literal 26.1408 + role="hook">incoming</literal> (<xref 26.1409 + linkend="sec:hook:incoming"/>), <literal 26.1410 + role="hook">prechangegroup</literal> (<xref 26.1411 + linkend="sec:hook:prechangegroup"/>), <literal 26.1412 + role="hook">pretxnchangegroup</literal> (<xref 26.1413 + linkend="sec:hook:pretxnchangegroup"/>) 26.1414 + </para> 26.1415 + </sect2> 26.1416 + 26.1417 + <sect2 id="sec:hook:commit"> 26.1418 + <title><literal role="hook">commit</literal>&emdash;after a new 26.1419 + changeset is created</title> 26.1420 + 26.1421 + <para id="x_297">This hook is run after a new changeset has been created. 26.1422 + </para> 26.1423 + 26.1424 + <para id="x_298">Parameters to this hook: 26.1425 + </para> 26.1426 + <itemizedlist> 26.1427 + <listitem><para id="x_299"><literal>node</literal>: A changeset ID. The 26.1428 + changeset ID of the newly committed changeset. 26.1429 + </para> 26.1430 + </listitem> 26.1431 + <listitem><para id="x_29a"><literal>parent1</literal>: A changeset ID. 26.1432 + The changeset ID of the first parent of the newly 26.1433 + committed changeset. 26.1434 + </para> 26.1435 + </listitem> 26.1436 + <listitem><para id="x_29b"><literal>parent2</literal>: A changeset ID. 26.1437 + The changeset ID of the second parent of the newly 26.1438 + committed changeset. 26.1439 + </para> 26.1440 + </listitem></itemizedlist> 26.1441 + 26.1442 + <para id="x_29c">See also: <literal 26.1443 + role="hook">precommit</literal> (<xref 26.1444 + linkend="sec:hook:precommit"/>), <literal 26.1445 + role="hook">pretxncommit</literal> (<xref 26.1446 + linkend="sec:hook:pretxncommit"/>) 26.1447 + </para> 26.1448 + </sect2> 26.1449 + 26.1450 + <sect2 id="sec:hook:incoming"> 26.1451 + <title><literal role="hook">incoming</literal>&emdash;after one 26.1452 + remote changeset is added</title> 26.1453 + 26.1454 + <para id="x_29d">This hook is run after a pre-existing changeset has been 26.1455 + added to the repository, for example via a <command 26.1456 + role="hg-cmd">hg push</command>. If a group of changesets 26.1457 + was added in a single operation, this hook is called once for 26.1458 + each added changeset. 26.1459 + </para> 26.1460 + 26.1461 + <para id="x_29e">You can use this hook for the same purposes as 26.1462 + the <literal role="hook">changegroup</literal> hook (<xref 26.1463 + linkend="sec:hook:changegroup"/>); it's simply more 26.1464 + convenient sometimes to run a hook once per group of 26.1465 + changesets, while other times it's handier once per changeset. 26.1466 + </para> 26.1467 + 26.1468 + <para id="x_29f">Parameters to this hook: 26.1469 + </para> 26.1470 + <itemizedlist> 26.1471 + <listitem><para id="x_2a0"><literal>node</literal>: A changeset ID. The 26.1472 + ID of the newly added changeset. 26.1473 + </para> 26.1474 + </listitem> 26.1475 + <listitem><para id="x_2a1"><literal>source</literal>: A 26.1476 + string. The source of these changes. See <xref 26.1477 + linkend="sec:hook:sources"/> for details. 26.1478 + </para> 26.1479 + </listitem> 26.1480 + <listitem><para id="x_2a2"><literal>url</literal>: A URL. The 26.1481 + location of the remote repository, if known. See <xref 26.1482 + linkend="sec:hook:url"/> for more information. 26.1483 + </para> 26.1484 + </listitem></itemizedlist> 26.1485 + 26.1486 + <para id="x_2a3">See also: <literal 26.1487 + role="hook">changegroup</literal> (<xref 26.1488 + linkend="sec:hook:changegroup"/>) <literal 26.1489 + role="hook">prechangegroup</literal> (<xref 26.1490 + linkend="sec:hook:prechangegroup"/>), <literal 26.1491 + role="hook">pretxnchangegroup</literal> (<xref 26.1492 + linkend="sec:hook:pretxnchangegroup"/>) 26.1493 + </para> 26.1494 + </sect2> 26.1495 + 26.1496 + <sect2 id="sec:hook:outgoing"> 26.1497 + <title><literal role="hook">outgoing</literal>&emdash;after 26.1498 + changesets are propagated</title> 26.1499 + 26.1500 + <para id="x_2a4">This hook is run after a group of changesets has been 26.1501 + propagated out of this repository, for example by a <command 26.1502 + role="hg-cmd">hg push</command> or <command role="hg-cmd">hg 26.1503 + bundle</command> command. 26.1504 + </para> 26.1505 + 26.1506 + <para id="x_2a5">One possible use for this hook is to notify administrators 26.1507 + that changes have been pulled. 26.1508 + </para> 26.1509 + 26.1510 + <para id="x_2a6">Parameters to this hook: 26.1511 + </para> 26.1512 + <itemizedlist> 26.1513 + <listitem><para id="x_2a7"><literal>node</literal>: A changeset ID. The 26.1514 + changeset ID of the first changeset of the group that was 26.1515 + sent. 26.1516 + </para> 26.1517 + </listitem> 26.1518 + <listitem><para id="x_2a8"><literal>source</literal>: A string. The 26.1519 + source of the of the operation (see <xref 26.1520 + linkend="sec:hook:sources"/>). If a remote 26.1521 + client pulled changes from this repository, 26.1522 + <literal>source</literal> will be 26.1523 + <literal>serve</literal>. If the client that obtained 26.1524 + changes from this repository was local, 26.1525 + <literal>source</literal> will be 26.1526 + <literal>bundle</literal>, <literal>pull</literal>, or 26.1527 + <literal>push</literal>, depending on the operation the 26.1528 + client performed. 26.1529 + </para> 26.1530 + </listitem> 26.1531 + <listitem><para id="x_2a9"><literal>url</literal>: A URL. The 26.1532 + location of the remote repository, if known. See <xref 26.1533 + linkend="sec:hook:url"/> for more information. 26.1534 + </para> 26.1535 + </listitem></itemizedlist> 26.1536 + 26.1537 + <para id="x_2aa">See also: <literal 26.1538 + role="hook">preoutgoing</literal> (<xref 26.1539 + linkend="sec:hook:preoutgoing"/>) 26.1540 + </para> 26.1541 + </sect2> 26.1542 + 26.1543 + <sect2 id="sec:hook:prechangegroup"> 26.1544 + <title><literal 26.1545 + role="hook">prechangegroup</literal>&emdash;before starting 26.1546 + to add remote changesets</title> 26.1547 + 26.1548 + <para id="x_2ab">This controlling hook is run before Mercurial begins to 26.1549 + add a group of changesets from another repository. 26.1550 + </para> 26.1551 + 26.1552 + <para id="x_2ac">This hook does not have any information about the 26.1553 + changesets to be added, because it is run before transmission 26.1554 + of those changesets is allowed to begin. If this hook fails, 26.1555 + the changesets will not be transmitted. 26.1556 + </para> 26.1557 + 26.1558 + <para id="x_2ad">One use for this hook is to prevent external changes from 26.1559 + being added to a repository. For example, you could use this 26.1560 + to <quote>freeze</quote> a server-hosted branch temporarily or 26.1561 + permanently so that users cannot push to it, while still 26.1562 + allowing a local administrator to modify the repository. 26.1563 + </para> 26.1564 + 26.1565 + <para id="x_2ae">Parameters to this hook: 26.1566 + </para> 26.1567 + <itemizedlist> 26.1568 + <listitem><para id="x_2af"><literal>source</literal>: A string. The 26.1569 + source of these changes. See <xref 26.1570 + linkend="sec:hook:sources"/> for details. 26.1571 + </para> 26.1572 + </listitem> 26.1573 + <listitem><para id="x_2b0"><literal>url</literal>: A URL. The 26.1574 + location of the remote repository, if known. See <xref 26.1575 + linkend="sec:hook:url"/> for more information. 26.1576 + </para> 26.1577 + </listitem></itemizedlist> 26.1578 + 26.1579 + <para id="x_2b1">See also: <literal 26.1580 + role="hook">changegroup</literal> (<xref 26.1581 + linkend="sec:hook:changegroup"/>), <literal 26.1582 + role="hook">incoming</literal> (<xref 26.1583 + linkend="sec:hook:incoming"/>), <literal 26.1584 + role="hook">pretxnchangegroup</literal> (<xref 26.1585 + linkend="sec:hook:pretxnchangegroup"/>) 26.1586 + </para> 26.1587 + </sect2> 26.1588 + 26.1589 + <sect2 id="sec:hook:precommit"> 26.1590 + <title><literal role="hook">precommit</literal>&emdash;before 26.1591 + starting to commit a changeset</title> 26.1592 + 26.1593 + <para id="x_2b2">This hook is run before Mercurial begins to commit a new 26.1594 + changeset. It is run before Mercurial has any of the metadata 26.1595 + for the commit, such as the files to be committed, the commit 26.1596 + message, or the commit date. 26.1597 + </para> 26.1598 + 26.1599 + <para id="x_2b3">One use for this hook is to disable the ability to commit 26.1600 + new changesets, while still allowing incoming changesets. 26.1601 + Another is to run a build or test, and only allow the commit 26.1602 + to begin if the build or test succeeds. 26.1603 + </para> 26.1604 + 26.1605 + <para id="x_2b4">Parameters to this hook: 26.1606 + </para> 26.1607 + <itemizedlist> 26.1608 + <listitem><para id="x_2b5"><literal>parent1</literal>: A changeset ID. 26.1609 + The changeset ID of the first parent of the working 26.1610 + directory. 26.1611 + </para> 26.1612 + </listitem> 26.1613 + <listitem><para id="x_2b6"><literal>parent2</literal>: A changeset ID. 26.1614 + The changeset ID of the second parent of the working 26.1615 + directory. 26.1616 + </para> 26.1617 + </listitem></itemizedlist> 26.1618 + <para id="x_2b7">If the commit proceeds, the parents of the working 26.1619 + directory will become the parents of the new changeset. 26.1620 + </para> 26.1621 + 26.1622 + <para id="x_2b8">See also: <literal role="hook">commit</literal> 26.1623 + (<xref linkend="sec:hook:commit"/>), <literal 26.1624 + role="hook">pretxncommit</literal> (<xref 26.1625 + linkend="sec:hook:pretxncommit"/>) 26.1626 + </para> 26.1627 + </sect2> 26.1628 + 26.1629 + <sect2 id="sec:hook:preoutgoing"> 26.1630 + <title><literal role="hook">preoutgoing</literal>&emdash;before 26.1631 + starting to propagate changesets</title> 26.1632 + 26.1633 + <para id="x_2b9">This hook is invoked before Mercurial knows the identities 26.1634 + of the changesets to be transmitted. 26.1635 + </para> 26.1636 + 26.1637 + <para id="x_2ba">One use for this hook is to prevent changes from being 26.1638 + transmitted to another repository. 26.1639 + </para> 26.1640 + 26.1641 + <para id="x_2bb">Parameters to this hook: 26.1642 + </para> 26.1643 + <itemizedlist> 26.1644 + <listitem><para id="x_2bc"><literal>source</literal>: A 26.1645 + string. The source of the operation that is attempting to 26.1646 + obtain changes from this repository (see <xref 26.1647 + linkend="sec:hook:sources"/>). See the documentation 26.1648 + for the <literal>source</literal> parameter to the 26.1649 + <literal role="hook">outgoing</literal> hook, in 26.1650 + <xref linkend="sec:hook:outgoing"/>, for possible values 26.1651 + of this parameter. 26.1652 + </para> 26.1653 + </listitem> 26.1654 + <listitem><para id="x_2bd"><literal>url</literal>: A URL. The 26.1655 + location of the remote repository, if known. See <xref 26.1656 + linkend="sec:hook:url"/> for more information. 26.1657 + </para> 26.1658 + </listitem></itemizedlist> 26.1659 + 26.1660 + <para id="x_2be">See also: <literal 26.1661 + role="hook">outgoing</literal> (<xref 26.1662 + linkend="sec:hook:outgoing"/>) 26.1663 + </para> 26.1664 + </sect2> 26.1665 + 26.1666 + <sect2 id="sec:hook:pretag"> 26.1667 + <title><literal role="hook">pretag</literal>&emdash;before 26.1668 + tagging a changeset</title> 26.1669 + 26.1670 + <para id="x_2bf">This controlling hook is run before a tag is created. If 26.1671 + the hook succeeds, creation of the tag proceeds. If the hook 26.1672 + fails, the tag is not created. 26.1673 + </para> 26.1674 + 26.1675 + <para id="x_2c0">Parameters to this hook: 26.1676 + </para> 26.1677 + <itemizedlist> 26.1678 + <listitem><para id="x_2c1"><literal>local</literal>: A boolean. Whether 26.1679 + the tag is local to this repository instance (i.e. stored 26.1680 + in <filename role="special">.hg/localtags</filename>) or 26.1681 + managed by Mercurial (stored in <filename 26.1682 + role="special">.hgtags</filename>). 26.1683 + </para> 26.1684 + </listitem> 26.1685 + <listitem><para id="x_2c2"><literal>node</literal>: A changeset ID. The 26.1686 + ID of the changeset to be tagged. 26.1687 + </para> 26.1688 + </listitem> 26.1689 + <listitem><para id="x_2c3"><literal>tag</literal>: A string. The name of 26.1690 + the tag to be created. 26.1691 + </para> 26.1692 + </listitem></itemizedlist> 26.1693 + 26.1694 + <para id="x_2c4">If the tag to be created is 26.1695 + revision-controlled, the <literal 26.1696 + role="hook">precommit</literal> and <literal 26.1697 + role="hook">pretxncommit</literal> hooks (<xref 26.1698 + linkend="sec:hook:commit"/> and <xref 26.1699 + linkend="sec:hook:pretxncommit"/>) will also be run. 26.1700 + </para> 26.1701 + 26.1702 + <para id="x_2c5">See also: <literal role="hook">tag</literal> 26.1703 + (<xref linkend="sec:hook:tag"/>) 26.1704 + </para> 26.1705 + </sect2> 26.1706 + 26.1707 + <sect2 id="sec:hook:pretxnchangegroup"> 26.1708 + <title><literal 26.1709 + role="hook">pretxnchangegroup</literal>&emdash;before 26.1710 + completing addition of remote changesets</title> 26.1711 + 26.1712 + <para id="x_2c6">This controlling hook is run before a 26.1713 + transaction&emdash;that manages the addition of a group of new 26.1714 + changesets from outside the repository&emdash;completes. If 26.1715 + the hook succeeds, the transaction completes, and all of the 26.1716 + changesets become permanent within this repository. If the 26.1717 + hook fails, the transaction is rolled back, and the data for 26.1718 + the changesets is erased. 26.1719 + </para> 26.1720 + 26.1721 + <para id="x_2c7">This hook can access the metadata associated with the 26.1722 + almost-added changesets, but it should not do anything 26.1723 + permanent with this data. It must also not modify the working 26.1724 + directory. 26.1725 + </para> 26.1726 + 26.1727 + <para id="x_2c8">While this hook is running, if other Mercurial processes 26.1728 + access this repository, they will be able to see the 26.1729 + almost-added changesets as if they are permanent. This may 26.1730 + lead to race conditions if you do not take steps to avoid 26.1731 + them. 26.1732 + </para> 26.1733 + 26.1734 + <para id="x_2c9">This hook can be used to automatically vet a group of 26.1735 + changesets. If the hook fails, all of the changesets are 26.1736 + <quote>rejected</quote> when the transaction rolls back. 26.1737 + </para> 26.1738 + 26.1739 + <para id="x_2ca">Parameters to this hook: 26.1740 + </para> 26.1741 + <itemizedlist> 26.1742 + <listitem><para id="x_2cb"><literal>node</literal>: A changeset ID. The 26.1743 + changeset ID of the first changeset in the group that was 26.1744 + added. All changesets between this and 26.1745 + <literal role="tag">tip</literal>, 26.1746 + inclusive, were added by a single <command 26.1747 + role="hg-cmd">hg pull</command>, <command 26.1748 + role="hg-cmd">hg push</command> or <command 26.1749 + role="hg-cmd">hg unbundle</command>. 26.1750 + </para> 26.1751 + </listitem> 26.1752 + <listitem><para id="x_2cc"><literal>source</literal>: A 26.1753 + string. The source of these changes. See <xref 26.1754 + linkend="sec:hook:sources"/> for details. 26.1755 + </para> 26.1756 + </listitem> 26.1757 + <listitem><para id="x_2cd"><literal>url</literal>: A URL. The 26.1758 + location of the remote repository, if known. See <xref 26.1759 + linkend="sec:hook:url"/> for more information. 26.1760 + </para> 26.1761 + </listitem></itemizedlist> 26.1762 + 26.1763 + <para id="x_2ce">See also: <literal 26.1764 + role="hook">changegroup</literal> (<xref 26.1765 + linkend="sec:hook:changegroup"/>), <literal 26.1766 + role="hook">incoming</literal> (<xref 26.1767 + linkend="sec:hook:incoming"/>), <literal 26.1768 + role="hook">prechangegroup</literal> (<xref 26.1769 + linkend="sec:hook:prechangegroup"/>) 26.1770 + </para> 26.1771 + </sect2> 26.1772 + 26.1773 + <sect2 id="sec:hook:pretxncommit"> 26.1774 + <title><literal role="hook">pretxncommit</literal>&emdash;before 26.1775 + completing commit of new changeset</title> 26.1776 + 26.1777 + <para id="x_2cf">This controlling hook is run before a 26.1778 + transaction&emdash;that manages a new commit&emdash;completes. 26.1779 + If the hook succeeds, the transaction completes and the 26.1780 + changeset becomes permanent within this repository. If the 26.1781 + hook fails, the transaction is rolled back, and the commit 26.1782 + data is erased. 26.1783 + </para> 26.1784 + 26.1785 + <para id="x_2d0">This hook can access the metadata associated with the 26.1786 + almost-new changeset, but it should not do anything permanent 26.1787 + with this data. It must also not modify the working 26.1788 + directory. 26.1789 + </para> 26.1790 + 26.1791 + <para id="x_2d1">While this hook is running, if other Mercurial processes 26.1792 + access this repository, they will be able to see the 26.1793 + almost-new changeset as if it is permanent. This may lead to 26.1794 + race conditions if you do not take steps to avoid them. 26.1795 + </para> 26.1796 + 26.1797 + <para id="x_2d2">Parameters to this hook:</para> 26.1798 + 26.1799 + <itemizedlist> 26.1800 + <listitem><para id="x_2d3"><literal>node</literal>: A changeset ID. The 26.1801 + changeset ID of the newly committed changeset. 26.1802 + </para> 26.1803 + </listitem> 26.1804 + <listitem><para id="x_2d4"><literal>parent1</literal>: A changeset ID. 26.1805 + The changeset ID of the first parent of the newly 26.1806 + committed changeset. 26.1807 + </para> 26.1808 + </listitem> 26.1809 + <listitem><para id="x_2d5"><literal>parent2</literal>: A changeset ID. 26.1810 + The changeset ID of the second parent of the newly 26.1811 + committed changeset. 26.1812 + </para> 26.1813 + </listitem></itemizedlist> 26.1814 + 26.1815 + <para id="x_2d6">See also: <literal 26.1816 + role="hook">precommit</literal> (<xref 26.1817 + linkend="sec:hook:precommit"/>) 26.1818 + </para> 26.1819 + </sect2> 26.1820 + 26.1821 + <sect2 id="sec:hook:preupdate"> 26.1822 + <title><literal role="hook">preupdate</literal>&emdash;before 26.1823 + updating or merging working directory</title> 26.1824 + 26.1825 + <para id="x_2d7">This controlling hook is run before an update 26.1826 + or merge of the working directory begins. It is run only if 26.1827 + Mercurial's normal pre-update checks determine that the update 26.1828 + or merge can proceed. If the hook succeeds, the update or 26.1829 + merge may proceed; if it fails, the update or merge does not 26.1830 + start. 26.1831 + </para> 26.1832 + 26.1833 + <para id="x_2d8">Parameters to this hook: 26.1834 + </para> 26.1835 + <itemizedlist> 26.1836 + <listitem><para id="x_2d9"><literal>parent1</literal>: A 26.1837 + changeset ID. The ID of the parent that the working 26.1838 + directory is to be updated to. If the working directory 26.1839 + is being merged, it will not change this parent. 26.1840 + </para> 26.1841 + </listitem> 26.1842 + <listitem><para id="x_2da"><literal>parent2</literal>: A 26.1843 + changeset ID. Only set if the working directory is being 26.1844 + merged. The ID of the revision that the working directory 26.1845 + is being merged with. 26.1846 + </para> 26.1847 + </listitem></itemizedlist> 26.1848 + 26.1849 + <para id="x_2db">See also: <literal role="hook">update</literal> 26.1850 + (<xref linkend="sec:hook:update"/>)</para> 26.1851 + </sect2> 26.1852 + 26.1853 + <sect2 id="sec:hook:tag"> 26.1854 + <title><literal role="hook">tag</literal>&emdash;after tagging a 26.1855 + changeset</title> 26.1856 + 26.1857 + <para id="x_2dc">This hook is run after a tag has been created. 26.1858 + </para> 26.1859 + 26.1860 + <para id="x_2dd">Parameters to this hook: 26.1861 + </para> 26.1862 + <itemizedlist> 26.1863 + <listitem><para id="x_2de"><literal>local</literal>: A boolean. Whether 26.1864 + the new tag is local to this repository instance (i.e. 26.1865 + stored in <filename 26.1866 + role="special">.hg/localtags</filename>) or managed by 26.1867 + Mercurial (stored in <filename 26.1868 + role="special">.hgtags</filename>). 26.1869 + </para> 26.1870 + </listitem> 26.1871 + <listitem><para id="x_2df"><literal>node</literal>: A changeset ID. The 26.1872 + ID of the changeset that was tagged. 26.1873 + </para> 26.1874 + </listitem> 26.1875 + <listitem><para id="x_2e0"><literal>tag</literal>: A string. The name of 26.1876 + the tag that was created. 26.1877 + </para> 26.1878 + </listitem></itemizedlist> 26.1879 + 26.1880 + <para id="x_2e1">If the created tag is revision-controlled, the <literal 26.1881 + role="hook">commit</literal> hook (section <xref 26.1882 + linkend="sec:hook:commit"/>) is run before this hook. 26.1883 + </para> 26.1884 + 26.1885 + <para id="x_2e2">See also: <literal role="hook">pretag</literal> 26.1886 + (<xref linkend="sec:hook:pretag"/>) 26.1887 + </para> 26.1888 + </sect2> 26.1889 + 26.1890 + <sect2 id="sec:hook:update"> 26.1891 + <title><literal role="hook">update</literal>&emdash;after 26.1892 + updating or merging working directory</title> 26.1893 + 26.1894 + <para id="x_2e3">This hook is run after an update or merge of the working 26.1895 + directory completes. Since a merge can fail (if the external 26.1896 + <command>hgmerge</command> command fails to resolve conflicts 26.1897 + in a file), this hook communicates whether the update or merge 26.1898 + completed cleanly. 26.1899 + </para> 26.1900 + 26.1901 + <itemizedlist> 26.1902 + <listitem><para id="x_2e4"><literal>error</literal>: A boolean. 26.1903 + Indicates whether the update or merge completed 26.1904 + successfully. 26.1905 + </para> 26.1906 + </listitem> 26.1907 + <listitem><para id="x_2e5"><literal>parent1</literal>: A changeset ID. 26.1908 + The ID of the parent that the working directory was 26.1909 + updated to. If the working directory was merged, it will 26.1910 + not have changed this parent. 26.1911 + </para> 26.1912 + </listitem> 26.1913 + <listitem><para id="x_2e6"><literal>parent2</literal>: A changeset ID. 26.1914 + Only set if the working directory was merged. The ID of 26.1915 + the revision that the working directory was merged with. 26.1916 + </para> 26.1917 + </listitem></itemizedlist> 26.1918 + 26.1919 + <para id="x_2e7">See also: <literal role="hook">preupdate</literal> 26.1920 + (<xref linkend="sec:hook:preupdate"/>) 26.1921 + </para> 26.1922 + 26.1923 + </sect2> 26.1924 + </sect1> 26.1925 +</chapter> 26.1926 + 26.1927 +<!-- 26.1928 +local variables: 26.1929 +sgml-parent-document: ("00book.xml" "book" "chapter") 26.1930 +end: 26.1931 +-->
27.1 --- a/en/ch10-template.xml Sat Apr 18 11:52:33 2009 +0800 27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3 @@ -1,673 +0,0 @@ 27.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 27.5 - 27.6 -<chapter id="chap:template"> 27.7 - <?dbhtml filename="customizing-the-output-of-mercurial.html"?> 27.8 - <title>Customising the output of Mercurial</title> 27.9 - 27.10 - <para id="x_578">Mercurial provides a powerful mechanism to let you control how 27.11 - it displays information. The mechanism is based on templates. 27.12 - You can use templates to generate specific output for a single 27.13 - command, or to customise the entire appearance of the built-in web 27.14 - interface.</para> 27.15 - 27.16 - <sect1 id="sec:style"> 27.17 - <title>Using precanned output styles</title> 27.18 - 27.19 - <para id="x_579">Packaged with Mercurial are some output styles that you can 27.20 - use immediately. A style is simply a precanned template that 27.21 - someone wrote and installed somewhere that Mercurial can 27.22 - find.</para> 27.23 - 27.24 - <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's 27.25 - review its normal output.</para> 27.26 - 27.27 - &interaction.template.simple.normal; 27.28 - 27.29 - <para id="x_57b">This is somewhat informative, but it takes up a lot of 27.30 - space&emdash;five lines of output per changeset. The 27.31 - <literal>compact</literal> style reduces this to three lines, 27.32 - presented in a sparse manner.</para> 27.33 - 27.34 - &interaction.template.simple.compact; 27.35 - 27.36 - <para id="x_57c">The <literal>changelog</literal> style hints at the 27.37 - expressive power of Mercurial's templating engine. This style 27.38 - attempts to follow the GNU Project's changelog 27.39 - guidelines<citation>web:changelog</citation>.</para> 27.40 - 27.41 - &interaction.template.simple.changelog; 27.42 - 27.43 - <para id="x_57d">You will not be shocked to learn that Mercurial's default 27.44 - output style is named <literal>default</literal>.</para> 27.45 - 27.46 - <sect2> 27.47 - <title>Setting a default style</title> 27.48 - 27.49 - <para id="x_57e">You can modify the output style that Mercurial will use 27.50 - for every command by editing your <filename 27.51 - role="special">~/.hgrc</filename> file, naming the style 27.52 - you would prefer to use.</para> 27.53 - 27.54 - <programlisting>[ui] 27.55 -style = compact</programlisting> 27.56 - 27.57 - <para id="x_57f">If you write a style of your own, you can use it by either 27.58 - providing the path to your style file, or copying your style 27.59 - file into a location where Mercurial can find it (typically 27.60 - the <literal>templates</literal> subdirectory of your 27.61 - Mercurial install directory).</para> 27.62 - 27.63 - </sect2> 27.64 - </sect1> 27.65 - <sect1> 27.66 - <title>Commands that support styles and templates</title> 27.67 - 27.68 - <para id="x_580">All of Mercurial's 27.69 - <quote><literal>log</literal>-like</quote> commands let you use 27.70 - styles and templates: <command role="hg-cmd">hg 27.71 - incoming</command>, <command role="hg-cmd">hg log</command>, 27.72 - <command role="hg-cmd">hg outgoing</command>, and <command 27.73 - role="hg-cmd">hg tip</command>.</para> 27.74 - 27.75 - <para id="x_581">As I write this manual, these are so far the only commands 27.76 - that support styles and templates. Since these are the most 27.77 - important commands that need customisable output, there has been 27.78 - little pressure from the Mercurial user community to add style 27.79 - and template support to other commands.</para> 27.80 - 27.81 - </sect1> 27.82 - <sect1> 27.83 - <title>The basics of templating</title> 27.84 - 27.85 - <para id="x_582">At its simplest, a Mercurial template is a piece of text. 27.86 - Some of the text never changes, while other parts are 27.87 - <emphasis>expanded</emphasis>, or replaced with new text, when 27.88 - necessary.</para> 27.89 - 27.90 - <para id="x_583">Before we continue, let's look again at a simple example of 27.91 - Mercurial's normal output.</para> 27.92 - 27.93 - &interaction.template.simple.normal; 27.94 - 27.95 - <para id="x_584">Now, let's run the same command, but using a template to 27.96 - change its output.</para> 27.97 - 27.98 - &interaction.template.simple.simplest; 27.99 - 27.100 - <para id="x_585">The example above illustrates the simplest possible 27.101 - template; it's just a piece of static text, printed once for 27.102 - each changeset. The <option 27.103 - role="hg-opt-log">--template</option> option to the <command 27.104 - role="hg-cmd">hg log</command> command tells Mercurial to use 27.105 - the given text as the template when printing each 27.106 - changeset.</para> 27.107 - 27.108 - <para id="x_586">Notice that the template string above ends with the text 27.109 - <quote><literal>\n</literal></quote>. This is an 27.110 - <emphasis>escape sequence</emphasis>, telling Mercurial to print 27.111 - a newline at the end of each template item. If you omit this 27.112 - newline, Mercurial will run each piece of output together. See 27.113 - <xref linkend="sec:template:escape"/> for more details 27.114 - of escape sequences.</para> 27.115 - 27.116 - <para id="x_587">A template that prints a fixed string of text all the time 27.117 - isn't very useful; let's try something a bit more 27.118 - complex.</para> 27.119 - 27.120 - &interaction.template.simple.simplesub; 27.121 - 27.122 - <para id="x_588">As you can see, the string 27.123 - <quote><literal>{desc}</literal></quote> in the template has 27.124 - been replaced in the output with the description of each 27.125 - changeset. Every time Mercurial finds text enclosed in curly 27.126 - braces (<quote><literal>{</literal></quote> and 27.127 - <quote><literal>}</literal></quote>), it will try to replace the 27.128 - braces and text with the expansion of whatever is inside. To 27.129 - print a literal curly brace, you must escape it, as described in 27.130 - <xref linkend="sec:template:escape"/>.</para> 27.131 - 27.132 - </sect1> 27.133 - <sect1 id="sec:template:keyword"> 27.134 - <title>Common template keywords</title> 27.135 - 27.136 - <para id="x_589">You can start writing simple templates immediately using the 27.137 - keywords below.</para> 27.138 - 27.139 - <itemizedlist> 27.140 - <listitem><para id="x_58a"><literal 27.141 - role="template-keyword">author</literal>: String. The 27.142 - unmodified author of the changeset.</para> 27.143 - </listitem> 27.144 - <listitem><para id="x_58b"><literal 27.145 - role="template-keyword">branches</literal>: String. The 27.146 - name of the branch on which the changeset was committed. 27.147 - Will be empty if the branch name was 27.148 - <literal>default</literal>.</para> 27.149 - </listitem> 27.150 - <listitem><para id="x_58c"><literal role="template-keyword">date</literal>: 27.151 - Date information. The date when the changeset was 27.152 - committed. This is <emphasis>not</emphasis> human-readable; 27.153 - you must pass it through a filter that will render it 27.154 - appropriately. See <xref 27.155 - linkend="sec:template:filter"/> for more information 27.156 - on filters. The date is expressed as a pair of numbers. The 27.157 - first number is a Unix UTC timestamp (seconds since January 27.158 - 1, 1970); the second is the offset of the committer's 27.159 - timezone from UTC, in seconds.</para> 27.160 - </listitem> 27.161 - <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>: 27.162 - String. The text of the changeset description.</para> 27.163 - </listitem> 27.164 - <listitem><para id="x_58e"><literal 27.165 - role="template-keyword">files</literal>: List of strings. 27.166 - All files modified, added, or removed by this 27.167 - changeset.</para> 27.168 - </listitem> 27.169 - <listitem><para id="x_58f"><literal 27.170 - role="template-keyword">file_adds</literal>: List of 27.171 - strings. Files added by this changeset.</para> 27.172 - </listitem> 27.173 - <listitem><para id="x_590"><literal 27.174 - role="template-keyword">file_dels</literal>: List of 27.175 - strings. Files removed by this changeset.</para> 27.176 - </listitem> 27.177 - <listitem><para id="x_591"><literal role="template-keyword">node</literal>: 27.178 - String. The changeset identification hash, as a 27.179 - 40-character hexadecimal string.</para> 27.180 - </listitem> 27.181 - <listitem><para id="x_592"><literal 27.182 - role="template-keyword">parents</literal>: List of 27.183 - strings. The parents of the changeset.</para> 27.184 - </listitem> 27.185 - <listitem><para id="x_593"><literal role="template-keyword">rev</literal>: 27.186 - Integer. The repository-local changeset revision 27.187 - number.</para> 27.188 - </listitem> 27.189 - <listitem><para id="x_594"><literal role="template-keyword">tags</literal>: 27.190 - List of strings. Any tags associated with the 27.191 - changeset.</para> 27.192 - </listitem></itemizedlist> 27.193 - 27.194 - <para id="x_595">A few simple experiments will show us what to expect when we 27.195 - use these keywords; you can see the results below.</para> 27.196 - 27.197 -&interaction.template.simple.keywords; 27.198 - 27.199 - <para id="x_596">As we noted above, the date keyword does not produce 27.200 - human-readable output, so we must treat it specially. This 27.201 - involves using a <emphasis>filter</emphasis>, about which more 27.202 - in <xref linkend="sec:template:filter"/>.</para> 27.203 - 27.204 - &interaction.template.simple.datekeyword; 27.205 - 27.206 - </sect1> 27.207 - <sect1 id="sec:template:escape"> 27.208 - <title>Escape sequences</title> 27.209 - 27.210 - <para id="x_597">Mercurial's templating engine recognises the most commonly 27.211 - used escape sequences in strings. When it sees a backslash 27.212 - (<quote><literal>\</literal></quote>) character, it looks at the 27.213 - following character and substitutes the two characters with a 27.214 - single replacement, as described below.</para> 27.215 - 27.216 - <itemizedlist> 27.217 - <listitem><para id="x_598"><literal>\</literal>: 27.218 - Backslash, <quote><literal>\</literal></quote>, ASCII 27.219 - 134.</para> 27.220 - </listitem> 27.221 - <listitem><para id="x_599"><literal>\n</literal>: Newline, 27.222 - ASCII 12.</para> 27.223 - </listitem> 27.224 - <listitem><para id="x_59a"><literal>\r</literal>: Carriage 27.225 - return, ASCII 15.</para> 27.226 - </listitem> 27.227 - <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII 27.228 - 11.</para> 27.229 - </listitem> 27.230 - <listitem><para id="x_59c"><literal>\v</literal>: Vertical 27.231 - tab, ASCII 13.</para> 27.232 - </listitem> 27.233 - <listitem><para id="x_59d"><literal>{</literal>: Open curly 27.234 - brace, <quote><literal>{</literal></quote>, ASCII 27.235 - 173.</para> 27.236 - </listitem> 27.237 - <listitem><para id="x_59e"><literal>}</literal>: Close curly 27.238 - brace, <quote><literal>}</literal></quote>, ASCII 27.239 - 175.</para> 27.240 - </listitem></itemizedlist> 27.241 - 27.242 - <para id="x_59f">As indicated above, if you want the expansion of a template 27.243 - to contain a literal <quote><literal>\</literal></quote>, 27.244 - <quote><literal>{</literal></quote>, or 27.245 - <quote><literal>{</literal></quote> character, you must escape 27.246 - it.</para> 27.247 - 27.248 - </sect1> 27.249 - <sect1 id="sec:template:filter"> 27.250 - <title>Filtering keywords to change their results</title> 27.251 - 27.252 - <para id="x_5a0">Some of the results of template expansion are not 27.253 - immediately easy to use. Mercurial lets you specify an optional 27.254 - chain of <emphasis>filters</emphasis> to modify the result of 27.255 - expanding a keyword. You have already seen a common filter, 27.256 - <literal role="template-kw-filt-date">isodate</literal>, in 27.257 - action above, to make a date readable.</para> 27.258 - 27.259 - <para id="x_5a1">Below is a list of the most commonly used filters that 27.260 - Mercurial supports. While some filters can be applied to any 27.261 - text, others can only be used in specific circumstances. The 27.262 - name of each filter is followed first by an indication of where 27.263 - it can be used, then a description of its effect.</para> 27.264 - 27.265 - <itemizedlist> 27.266 - <listitem><para id="x_5a2"><literal 27.267 - role="template-filter">addbreaks</literal>: Any text. Add 27.268 - an XHTML <quote><literal><br/></literal></quote> tag 27.269 - before the end of every line except the last. For example, 27.270 - <quote><literal>foo\nbar</literal></quote> becomes 27.271 - <quote><literal>foo<br/>\nbar</literal></quote>.</para> 27.272 - </listitem> 27.273 - <listitem><para id="x_5a3"><literal 27.274 - role="template-kw-filt-date">age</literal>: <literal 27.275 - role="template-keyword">date</literal> keyword. Render 27.276 - the age of the date, relative to the current time. Yields a 27.277 - string like <quote><literal>10 27.278 - minutes</literal></quote>.</para> 27.279 - </listitem> 27.280 - <listitem><para id="x_5a4"><literal 27.281 - role="template-filter">basename</literal>: Any text, but 27.282 - most useful for the <literal 27.283 - role="template-keyword">files</literal> keyword and its 27.284 - relatives. Treat the text as a path, and return the 27.285 - basename. For example, 27.286 - <quote><literal>foo/bar/baz</literal></quote> becomes 27.287 - <quote><literal>baz</literal></quote>.</para> 27.288 - </listitem> 27.289 - <listitem><para id="x_5a5"><literal 27.290 - role="template-kw-filt-date">date</literal>: <literal 27.291 - role="template-keyword">date</literal> keyword. Render a 27.292 - date in a similar format to the Unix <literal 27.293 - role="template-keyword">date</literal> command, but with 27.294 - timezone included. Yields a string like <quote><literal>Mon 27.295 - Sep 04 15:13:13 2006 -0700</literal></quote>.</para> 27.296 - </listitem> 27.297 - <listitem><para id="x_5a6"><literal 27.298 - role="template-kw-filt-author">domain</literal>: Any text, 27.299 - but most useful for the <literal 27.300 - role="template-keyword">author</literal> keyword. Finds 27.301 - the first string that looks like an email address, and 27.302 - extract just the domain component. For example, 27.303 - <quote><literal>Bryan O'Sullivan 27.304 - <bos@serpentine.com></literal></quote> becomes 27.305 - <quote><literal>serpentine.com</literal></quote>.</para> 27.306 - </listitem> 27.307 - <listitem><para id="x_5a7"><literal 27.308 - role="template-kw-filt-author">email</literal>: Any text, 27.309 - but most useful for the <literal 27.310 - role="template-keyword">author</literal> keyword. Extract 27.311 - the first string that looks like an email address. For 27.312 - example, <quote><literal>Bryan O'Sullivan 27.313 - <bos@serpentine.com></literal></quote> becomes 27.314 - <quote><literal>bos@serpentine.com</literal></quote>.</para> 27.315 - </listitem> 27.316 - <listitem><para id="x_5a8"><literal 27.317 - role="template-filter">escape</literal>: Any text. 27.318 - Replace the special XML/XHTML characters 27.319 - <quote><literal>&</literal></quote>, 27.320 - <quote><literal><</literal></quote> and 27.321 - <quote><literal>></literal></quote> with XML 27.322 - entities.</para> 27.323 - </listitem> 27.324 - <listitem><para id="x_5a9"><literal 27.325 - role="template-filter">fill68</literal>: Any text. Wrap 27.326 - the text to fit in 68 columns. This is useful before you 27.327 - pass text through the <literal 27.328 - role="template-filter">tabindent</literal> filter, and 27.329 - still want it to fit in an 80-column fixed-font 27.330 - window.</para> 27.331 - </listitem> 27.332 - <listitem><para id="x_5aa"><literal 27.333 - role="template-filter">fill76</literal>: Any text. Wrap 27.334 - the text to fit in 76 columns.</para> 27.335 - </listitem> 27.336 - <listitem><para id="x_5ab"><literal 27.337 - role="template-filter">firstline</literal>: Any text. 27.338 - Yield the first line of text, without any trailing 27.339 - newlines.</para> 27.340 - </listitem> 27.341 - <listitem><para id="x_5ac"><literal 27.342 - role="template-kw-filt-date">hgdate</literal>: <literal 27.343 - role="template-keyword">date</literal> keyword. Render 27.344 - the date as a pair of readable numbers. Yields a string 27.345 - like <quote><literal>1157407993 27.346 - 25200</literal></quote>.</para> 27.347 - </listitem> 27.348 - <listitem><para id="x_5ad"><literal 27.349 - role="template-kw-filt-date">isodate</literal>: <literal 27.350 - role="template-keyword">date</literal> keyword. Render 27.351 - the date as a text string in ISO 8601 format. Yields a 27.352 - string like <quote><literal>2006-09-04 15:13:13 27.353 - -0700</literal></quote>.</para> 27.354 - </listitem> 27.355 - <listitem><para id="x_5ae"><literal 27.356 - role="template-filter">obfuscate</literal>: Any text, but 27.357 - most useful for the <literal 27.358 - role="template-keyword">author</literal> keyword. Yield 27.359 - the input text rendered as a sequence of XML entities. This 27.360 - helps to defeat some particularly stupid screen-scraping 27.361 - email harvesting spambots.</para> 27.362 - </listitem> 27.363 - <listitem><para id="x_5af"><literal 27.364 - role="template-kw-filt-author">person</literal>: Any text, 27.365 - but most useful for the <literal 27.366 - role="template-keyword">author</literal> keyword. Yield 27.367 - the text before an email address. For example, 27.368 - <quote><literal>Bryan O'Sullivan 27.369 - <bos@serpentine.com></literal></quote> becomes 27.370 - <quote><literal>Bryan O'Sullivan</literal></quote>.</para> 27.371 - </listitem> 27.372 - <listitem><para id="x_5b0"><literal 27.373 - role="template-kw-filt-date">rfc822date</literal>: 27.374 - <literal role="template-keyword">date</literal> keyword. 27.375 - Render a date using the same format used in email headers. 27.376 - Yields a string like <quote><literal>Mon, 04 Sep 2006 27.377 - 15:13:13 -0700</literal></quote>.</para> 27.378 - </listitem> 27.379 - <listitem><para id="x_5b1"><literal 27.380 - role="template-kw-filt-node">short</literal>: Changeset 27.381 - hash. Yield the short form of a changeset hash, i.e. a 27.382 - 12-character hexadecimal string.</para> 27.383 - </listitem> 27.384 - <listitem><para id="x_5b2"><literal 27.385 - role="template-kw-filt-date">shortdate</literal>: <literal 27.386 - role="template-keyword">date</literal> keyword. Render 27.387 - the year, month, and day of the date. Yields a string like 27.388 - <quote><literal>2006-09-04</literal></quote>.</para> 27.389 - </listitem> 27.390 - <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>: 27.391 - Any text. Strip all leading and trailing whitespace from 27.392 - the string.</para> 27.393 - </listitem> 27.394 - <listitem><para id="x_5b4"><literal 27.395 - role="template-filter">tabindent</literal>: Any text. 27.396 - Yield the text, with every line except the first starting 27.397 - with a tab character.</para> 27.398 - </listitem> 27.399 - <listitem><para id="x_5b5"><literal 27.400 - role="template-filter">urlescape</literal>: Any text. 27.401 - Escape all characters that are considered 27.402 - <quote>special</quote> by URL parsers. For example, 27.403 - <literal>foo bar</literal> becomes 27.404 - <literal>foo%20bar</literal>.</para> 27.405 - </listitem> 27.406 - <listitem><para id="x_5b6"><literal 27.407 - role="template-kw-filt-author">user</literal>: Any text, 27.408 - but most useful for the <literal 27.409 - role="template-keyword">author</literal> keyword. Return 27.410 - the <quote>user</quote> portion of an email address. For 27.411 - example, <quote><literal>Bryan O'Sullivan 27.412 - <bos@serpentine.com></literal></quote> becomes 27.413 - <quote><literal>bos</literal></quote>.</para> 27.414 - </listitem></itemizedlist> 27.415 - 27.416 -&interaction.template.simple.manyfilters; 27.417 - 27.418 - <note> 27.419 - <para id="x_5b7"> If you try to apply a filter to a piece of data that it 27.420 - cannot process, Mercurial will fail and print a Python 27.421 - exception. For example, trying to run the output of the 27.422 - <literal role="template-keyword">desc</literal> keyword into 27.423 - the <literal role="template-kw-filt-date">isodate</literal> 27.424 - filter is not a good idea.</para> 27.425 - </note> 27.426 - 27.427 - <sect2> 27.428 - <title>Combining filters</title> 27.429 - 27.430 - <para id="x_5b8">It is easy to combine filters to yield output in the form 27.431 - you would like. The following chain of filters tidies up a 27.432 - description, then makes sure that it fits cleanly into 68 27.433 - columns, then indents it by a further 8 characters (at least 27.434 - on Unix-like systems, where a tab is conventionally 8 27.435 - characters wide).</para> 27.436 - 27.437 - &interaction.template.simple.combine; 27.438 - 27.439 - <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a 27.440 - tab character) in the template to force the first line to be 27.441 - indented; this is necessary since <literal 27.442 - role="template-keyword">tabindent</literal> indents all 27.443 - lines <emphasis>except</emphasis> the first.</para> 27.444 - 27.445 - <para id="x_5ba">Keep in mind that the order of filters in a chain is 27.446 - significant. The first filter is applied to the result of the 27.447 - keyword; the second to the result of the first filter; and so 27.448 - on. For example, using <literal>fill68|tabindent</literal> 27.449 - gives very different results from 27.450 - <literal>tabindent|fill68</literal>.</para> 27.451 - 27.452 - 27.453 - </sect2> 27.454 - </sect1> 27.455 - <sect1> 27.456 - <title>From templates to styles</title> 27.457 - 27.458 - <para id="x_5bb">A command line template provides a quick and simple way to 27.459 - format some output. Templates can become verbose, though, and 27.460 - it's useful to be able to give a template a name. A style file 27.461 - is a template with a name, stored in a file.</para> 27.462 - 27.463 - <para id="x_5bc">More than that, using a style file unlocks the power of 27.464 - Mercurial's templating engine in ways that are not possible 27.465 - using the command line <option 27.466 - role="hg-opt-log">--template</option> option.</para> 27.467 - 27.468 - <sect2> 27.469 - <title>The simplest of style files</title> 27.470 - 27.471 - <para id="x_5bd">Our simple style file contains just one line:</para> 27.472 - 27.473 - &interaction.template.simple.rev; 27.474 - 27.475 - <para id="x_5be">This tells Mercurial, <quote>if you're printing a 27.476 - changeset, use the text on the right as the 27.477 - template</quote>.</para> 27.478 - 27.479 - </sect2> 27.480 - <sect2> 27.481 - <title>Style file syntax</title> 27.482 - 27.483 - <para id="x_5bf">The syntax rules for a style file are simple.</para> 27.484 - 27.485 - <itemizedlist> 27.486 - <listitem><para id="x_5c0">The file is processed one line at a 27.487 - time.</para> 27.488 - </listitem> 27.489 - <listitem><para id="x_5c1">Leading and trailing white space are 27.490 - ignored.</para> 27.491 - </listitem> 27.492 - <listitem><para id="x_5c2">Empty lines are skipped.</para> 27.493 - </listitem> 27.494 - <listitem><para id="x_5c3">If a line starts with either of the characters 27.495 - <quote><literal>#</literal></quote> or 27.496 - <quote><literal>;</literal></quote>, the entire line is 27.497 - treated as a comment, and skipped as if empty.</para> 27.498 - </listitem> 27.499 - <listitem><para id="x_5c4">A line starts with a keyword. This must start 27.500 - with an alphabetic character or underscore, and can 27.501 - subsequently contain any alphanumeric character or 27.502 - underscore. (In regexp notation, a keyword must match 27.503 - <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para> 27.504 - </listitem> 27.505 - <listitem><para id="x_5c5">The next element must be an 27.506 - <quote><literal>=</literal></quote> character, which can 27.507 - be preceded or followed by an arbitrary amount of white 27.508 - space.</para> 27.509 - </listitem> 27.510 - <listitem><para id="x_5c6">If the rest of the line starts and ends with 27.511 - matching quote characters (either single or double quote), 27.512 - it is treated as a template body.</para> 27.513 - </listitem> 27.514 - <listitem><para id="x_5c7">If the rest of the line <emphasis>does 27.515 - not</emphasis> start with a quote character, it is 27.516 - treated as the name of a file; the contents of this file 27.517 - will be read and used as a template body.</para> 27.518 - </listitem></itemizedlist> 27.519 - 27.520 - </sect2> 27.521 - </sect1> 27.522 - <sect1> 27.523 - <title>Style files by example</title> 27.524 - 27.525 - <para id="x_5c8">To illustrate how to write a style file, we will construct a 27.526 - few by example. Rather than provide a complete style file and 27.527 - walk through it, we'll mirror the usual process of developing a 27.528 - style file by starting with something very simple, and walking 27.529 - through a series of successively more complete examples.</para> 27.530 - 27.531 - <sect2> 27.532 - <title>Identifying mistakes in style files</title> 27.533 - 27.534 - <para id="x_5c9">If Mercurial encounters a problem in a style file you are 27.535 - working on, it prints a terse error message that, once you 27.536 - figure out what it means, is actually quite useful.</para> 27.537 - 27.538 -&interaction.template.svnstyle.syntax.input; 27.539 - 27.540 - <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to 27.541 - define a <literal>changeset</literal> keyword, but forgets to 27.542 - give any content for it. When instructed to use this style 27.543 - file, Mercurial promptly complains.</para> 27.544 - 27.545 - &interaction.template.svnstyle.syntax.error; 27.546 - 27.547 - <para id="x_5cb">This error message looks intimidating, but it is not too 27.548 - hard to follow.</para> 27.549 - 27.550 - <itemizedlist> 27.551 - <listitem><para id="x_5cc">The first component is simply Mercurial's way 27.552 - of saying <quote>I am giving up</quote>.</para> 27.553 - <programlisting>___abort___: broken.style:1: parse error</programlisting> 27.554 - </listitem> 27.555 - <listitem><para id="x_5cd">Next comes the name of the style file that 27.556 - contains the error.</para> 27.557 - <programlisting>abort: ___broken.style___:1: parse error</programlisting> 27.558 - </listitem> 27.559 - <listitem><para id="x_5ce">Following the file name is the line number 27.560 - where the error was encountered.</para> 27.561 - <programlisting>abort: broken.style:___1___: parse error</programlisting> 27.562 - </listitem> 27.563 - <listitem><para id="x_5cf">Finally, a description of what went 27.564 - wrong.</para> 27.565 - <programlisting>abort: broken.style:1: ___parse error___</programlisting> 27.566 - </listitem> 27.567 - <listitem><para id="x_5d0">The description of the problem is not always 27.568 - clear (as in this case), but even when it is cryptic, it 27.569 - is almost always trivial to visually inspect the offending 27.570 - line in the style file and see what is wrong.</para> 27.571 - </listitem></itemizedlist> 27.572 - 27.573 - </sect2> 27.574 - <sect2> 27.575 - <title>Uniquely identifying a repository</title> 27.576 - 27.577 - <para id="x_5d1">If you would like to be able to identify a Mercurial 27.578 - repository <quote>fairly uniquely</quote> using a short string 27.579 - as an identifier, you can use the first revision in the 27.580 - repository.</para> 27.581 - 27.582 - &interaction.template.svnstyle.id; 27.583 - 27.584 - <para id="x_5d2">This is not guaranteed to be unique, but it is 27.585 - nevertheless useful in many cases.</para> 27.586 - <itemizedlist> 27.587 - <listitem><para id="x_5d3">It will not work in a completely empty 27.588 - repository, because such a repository does not have a 27.589 - revision zero.</para> 27.590 - </listitem> 27.591 - <listitem><para id="x_5d4">Neither will it work in the (extremely rare) 27.592 - case where a repository is a merge of two or more formerly 27.593 - independent repositories, and you still have those 27.594 - repositories around.</para> 27.595 - </listitem></itemizedlist> 27.596 - <para id="x_5d5">Here are some uses to which you could put this 27.597 - identifier:</para> 27.598 - <itemizedlist> 27.599 - <listitem><para id="x_5d6">As a key into a table for a database that 27.600 - manages repositories on a server.</para> 27.601 - </listitem> 27.602 - <listitem><para id="x_5d7">As half of a {<emphasis>repository 27.603 - ID</emphasis>, <emphasis>revision ID</emphasis>} tuple. 27.604 - Save this information away when you run an automated build 27.605 - or other activity, so that you can <quote>replay</quote> 27.606 - the build later if necessary.</para> 27.607 - </listitem></itemizedlist> 27.608 - 27.609 - </sect2> 27.610 - <sect2> 27.611 - <title>Mimicking Subversion's output</title> 27.612 - 27.613 - <para id="x_5d8">Let's try to emulate the default output format used by 27.614 - another revision control tool, Subversion.</para> 27.615 - 27.616 - &interaction.template.svnstyle.short; 27.617 - 27.618 - <para id="x_5d9">Since Subversion's output style is fairly simple, it is 27.619 - easy to copy-and-paste a hunk of its output into a file, and 27.620 - replace the text produced above by Subversion with the 27.621 - template values we'd like to see expanded.</para> 27.622 - 27.623 - &interaction.template.svnstyle.template; 27.624 - 27.625 - <para id="x_5da">There are a few small ways in which this template deviates 27.626 - from the output produced by Subversion.</para> 27.627 - <itemizedlist> 27.628 - <listitem><para id="x_5db">Subversion prints a <quote>readable</quote> 27.629 - date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the 27.630 - example output above) in parentheses. Mercurial's 27.631 - templating engine does not provide a way to display a date 27.632 - in this format without also printing the time and time 27.633 - zone.</para> 27.634 - </listitem> 27.635 - <listitem><para id="x_5dc">We emulate Subversion's printing of 27.636 - <quote>separator</quote> lines full of 27.637 - <quote><literal>-</literal></quote> characters by ending 27.638 - the template with such a line. We use the templating 27.639 - engine's <literal role="template-keyword">header</literal> 27.640 - keyword to print a separator line as the first line of 27.641 - output (see below), thus achieving similar output to 27.642 - Subversion.</para> 27.643 - </listitem> 27.644 - <listitem><para id="x_5dd">Subversion's output includes a count in the 27.645 - header of the number of lines in the commit message. We 27.646 - cannot replicate this in Mercurial; the templating engine 27.647 - does not currently provide a filter that counts the number 27.648 - of lines the template generates.</para> 27.649 - </listitem></itemizedlist> 27.650 - <para id="x_5de">It took me no more than a minute or two of work to replace 27.651 - literal text from an example of Subversion's output with some 27.652 - keywords and filters to give the template above. The style 27.653 - file simply refers to the template.</para> 27.654 - 27.655 - &interaction.template.svnstyle.style; 27.656 - 27.657 - <para id="x_5df">We could have included the text of the template file 27.658 - directly in the style file by enclosing it in quotes and 27.659 - replacing the newlines with 27.660 - <quote><literal>\n</literal></quote> sequences, but it would 27.661 - have made the style file too difficult to read. Readability 27.662 - is a good guide when you're trying to decide whether some text 27.663 - belongs in a style file, or in a template file that the style 27.664 - file points to. If the style file will look too big or 27.665 - cluttered if you insert a literal piece of text, drop it into 27.666 - a template instead.</para> 27.667 - 27.668 - </sect2> 27.669 - </sect1> 27.670 -</chapter> 27.671 - 27.672 -<!-- 27.673 -local variables: 27.674 -sgml-parent-document: ("00book.xml" "book" "chapter") 27.675 -end: 27.676 --->
28.1 --- a/en/ch11-mq.xml Sat Apr 18 11:52:33 2009 +0800 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,1321 +0,0 @@ 28.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 28.5 - 28.6 -<chapter id="chap:mq"> 28.7 - <?dbhtml filename="managing-change-with-mercurial-queues.html"?> 28.8 - <title>Managing change with Mercurial Queues</title> 28.9 - 28.10 - <sect1 id="sec:mq:patch-mgmt"> 28.11 - <title>The patch management problem</title> 28.12 - 28.13 - <para id="x_3ac">Here is a common scenario: you need to install a software 28.14 - package from source, but you find a bug that you must fix in the 28.15 - source before you can start using the package. You make your 28.16 - changes, forget about the package for a while, and a few months 28.17 - later you need to upgrade to a newer version of the package. If 28.18 - the newer version of the package still has the bug, you must 28.19 - extract your fix from the older source tree and apply it against 28.20 - the newer version. This is a tedious task, and it's easy to 28.21 - make mistakes.</para> 28.22 - 28.23 - <para id="x_3ad">This is a simple case of the <quote>patch management</quote> 28.24 - problem. You have an <quote>upstream</quote> source tree that 28.25 - you can't change; you need to make some local changes on top of 28.26 - the upstream tree; and you'd like to be able to keep those 28.27 - changes separate, so that you can apply them to newer versions 28.28 - of the upstream source.</para> 28.29 - 28.30 - <para id="x_3ae">The patch management problem arises in many situations. 28.31 - Probably the most visible is that a user of an open source 28.32 - software project will contribute a bug fix or new feature to the 28.33 - project's maintainers in the form of a patch.</para> 28.34 - 28.35 - <para id="x_3af">Distributors of operating systems that include open source 28.36 - software often need to make changes to the packages they 28.37 - distribute so that they will build properly in their 28.38 - environments.</para> 28.39 - 28.40 - <para id="x_3b0">When you have few changes to maintain, it is easy to manage 28.41 - a single patch using the standard <command>diff</command> and 28.42 - <command>patch</command> programs (see <xref 28.43 - linkend="sec:mq:patch"/> for a discussion of these 28.44 - tools). Once the number of changes grows, it starts to make 28.45 - sense to maintain patches as discrete <quote>chunks of 28.46 - work,</quote> so that for example a single patch will contain 28.47 - only one bug fix (the patch might modify several files, but it's 28.48 - doing <quote>only one thing</quote>), and you may have a number 28.49 - of such patches for different bugs you need fixed and local 28.50 - changes you require. In this situation, if you submit a bug fix 28.51 - patch to the upstream maintainers of a package and they include 28.52 - your fix in a subsequent release, you can simply drop that 28.53 - single patch when you're updating to the newer release.</para> 28.54 - 28.55 - <para id="x_3b1">Maintaining a single patch against an upstream tree is a 28.56 - little tedious and error-prone, but not difficult. However, the 28.57 - complexity of the problem grows rapidly as the number of patches 28.58 - you have to maintain increases. With more than a tiny number of 28.59 - patches in hand, understanding which ones you have applied and 28.60 - maintaining them moves from messy to overwhelming.</para> 28.61 - 28.62 - <para id="x_3b2">Fortunately, Mercurial includes a powerful extension, 28.63 - Mercurial Queues (or simply <quote>MQ</quote>), that massively 28.64 - simplifies the patch management problem.</para> 28.65 - 28.66 - </sect1> 28.67 - <sect1 id="sec:mq:history"> 28.68 - <title>The prehistory of Mercurial Queues</title> 28.69 - 28.70 - <para id="x_3b3">During the late 1990s, several Linux kernel developers 28.71 - started to maintain <quote>patch series</quote> that modified 28.72 - the behavior of the Linux kernel. Some of these series were 28.73 - focused on stability, some on feature coverage, and others were 28.74 - more speculative.</para> 28.75 - 28.76 - <para id="x_3b4">The sizes of these patch series grew rapidly. In 2002, 28.77 - Andrew Morton published some shell scripts he had been using to 28.78 - automate the task of managing his patch queues. Andrew was 28.79 - successfully using these scripts to manage hundreds (sometimes 28.80 - thousands) of patches on top of the Linux kernel.</para> 28.81 - 28.82 - <sect2 id="sec:mq:quilt"> 28.83 - <title>A patchwork quilt</title> 28.84 - 28.85 - <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson 28.86 - borrowed the approach of Andrew's scripts and published a tool 28.87 - called <quote>patchwork quilt</quote> 28.88 - <citation>web:quilt</citation>, or simply <quote>quilt</quote> 28.89 - (see <citation>gruenbacher:2005</citation> for a paper 28.90 - describing it). Because quilt substantially automated patch 28.91 - management, it rapidly gained a large following among open 28.92 - source software developers.</para> 28.93 - 28.94 - <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on 28.95 - top of a directory tree. To begin, you tell quilt to manage a 28.96 - directory tree, and tell it which files you want to manage; it 28.97 - stores away the names and contents of those files. To fix a 28.98 - bug, you create a new patch (using a single command), edit the 28.99 - files you need to fix, then <quote>refresh</quote> the 28.100 - patch.</para> 28.101 - 28.102 - <para id="x_3b7">The refresh step causes quilt to scan the directory tree; 28.103 - it updates the patch with all of the changes you have made. 28.104 - You can create another patch on top of the first, which will 28.105 - track the changes required to modify the tree from <quote>tree 28.106 - with one patch applied</quote> to <quote>tree with two 28.107 - patches applied</quote>.</para> 28.108 - 28.109 - <para id="x_3b8">You can <emphasis>change</emphasis> which patches are 28.110 - applied to the tree. If you <quote>pop</quote> a patch, the 28.111 - changes made by that patch will vanish from the directory 28.112 - tree. Quilt remembers which patches you have popped, though, 28.113 - so you can <quote>push</quote> a popped patch again, and the 28.114 - directory tree will be restored to contain the modifications 28.115 - in the patch. Most importantly, you can run the 28.116 - <quote>refresh</quote> command at any time, and the topmost 28.117 - applied patch will be updated. This means that you can, at 28.118 - any time, change both which patches are applied and what 28.119 - modifications those patches make.</para> 28.120 - 28.121 - <para id="x_3b9">Quilt knows nothing about revision control tools, so it 28.122 - works equally well on top of an unpacked tarball or a 28.123 - Subversion working copy.</para> 28.124 - 28.125 - </sect2> 28.126 - <sect2 id="sec:mq:quilt-mq"> 28.127 - <title>From patchwork quilt to Mercurial Queues</title> 28.128 - 28.129 - <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and 28.130 - wrote an extension that he called Mercurial Queues, which 28.131 - added quilt-like behavior to Mercurial.</para> 28.132 - 28.133 - <para id="x_3bb">The key difference between quilt and MQ is that quilt 28.134 - knows nothing about revision control systems, while MQ is 28.135 - <emphasis>integrated</emphasis> into Mercurial. Each patch 28.136 - that you push is represented as a Mercurial changeset. Pop a 28.137 - patch, and the changeset goes away.</para> 28.138 - 28.139 - <para id="x_3bc">Because quilt does not care about revision control tools, 28.140 - it is still a tremendously useful piece of software to know 28.141 - about for situations where you cannot use Mercurial and 28.142 - MQ.</para> 28.143 - 28.144 - </sect2> 28.145 - </sect1> 28.146 - <sect1> 28.147 - <title>The huge advantage of MQ</title> 28.148 - 28.149 - <para id="x_3bd">I cannot overstate the value that MQ offers through the 28.150 - unification of patches and revision control.</para> 28.151 - 28.152 - <para id="x_3be">A major reason that patches have persisted in the free 28.153 - software and open source world&emdash;in spite of the 28.154 - availability of increasingly capable revision control tools over 28.155 - the years&emdash;is the <emphasis>agility</emphasis> they 28.156 - offer.</para> 28.157 - 28.158 - <para id="x_3bf">Traditional revision control tools make a permanent, 28.159 - irreversible record of everything that you do. While this has 28.160 - great value, it's also somewhat stifling. If you want to 28.161 - perform a wild-eyed experiment, you have to be careful in how 28.162 - you go about it, or you risk leaving unneeded&emdash;or worse, 28.163 - misleading or destabilising&emdash;traces of your missteps and 28.164 - errors in the permanent revision record.</para> 28.165 - 28.166 - <para id="x_3c0">By contrast, MQ's marriage of distributed revision control 28.167 - with patches makes it much easier to isolate your work. Your 28.168 - patches live on top of normal revision history, and you can make 28.169 - them disappear or reappear at will. If you don't like a patch, 28.170 - you can drop it. If a patch isn't quite as you want it to be, 28.171 - simply fix it&emdash;as many times as you need to, until you 28.172 - have refined it into the form you desire.</para> 28.173 - 28.174 - <para id="x_3c1">As an example, the integration of patches with revision 28.175 - control makes understanding patches and debugging their 28.176 - effects&emdash;and their interplay with the code they're based 28.177 - on&emdash;<emphasis>enormously</emphasis> easier. Since every 28.178 - applied patch has an associated changeset, you can give <command 28.179 - role="hg-cmd">hg log</command> a file name to see which 28.180 - changesets and patches affected the file. You can use the 28.181 - <command role="hg-cmd">hg bisect</command> command to 28.182 - binary-search through all changesets and applied patches to see 28.183 - where a bug got introduced or fixed. You can use the <command 28.184 - role="hg-cmd">hg annotate</command> command to see which 28.185 - changeset or patch modified a particular line of a source file. 28.186 - And so on.</para> 28.187 - 28.188 - </sect1> 28.189 - <sect1 id="sec:mq:patch"> 28.190 - <title>Understanding patches</title> 28.191 - 28.192 - <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is 28.193 - helpful to understand what patches are, and a little about the 28.194 - tools that work with them.</para> 28.195 - 28.196 - <para id="x_3c3">The traditional Unix <command>diff</command> command 28.197 - compares two files, and prints a list of differences between 28.198 - them. The <command>patch</command> command understands these 28.199 - differences as <emphasis>modifications</emphasis> to make to a 28.200 - file. Take a look below for a simple example of these commands 28.201 - in action.</para> 28.202 - 28.203 -&interaction.mq.dodiff.diff; 28.204 - 28.205 - <para id="x_3c4">The type of file that <command>diff</command> generates (and 28.206 - <command>patch</command> takes as input) is called a 28.207 - <quote>patch</quote> or a <quote>diff</quote>; there is no 28.208 - difference between a patch and a diff. (We'll use the term 28.209 - <quote>patch</quote>, since it's more commonly used.)</para> 28.210 - 28.211 - <para id="x_3c5">A patch file can start with arbitrary text; the 28.212 - <command>patch</command> command ignores this text, but MQ uses 28.213 - it as the commit message when creating changesets. To find the 28.214 - beginning of the patch content, <command>patch</command> 28.215 - searches for the first line that starts with the string 28.216 - <quote><literal>diff -</literal></quote>.</para> 28.217 - 28.218 - <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs 28.219 - (<command>patch</command> can accept several other diff formats, 28.220 - but MQ doesn't). A unified diff contains two kinds of header. 28.221 - The <emphasis>file header</emphasis> describes the file being 28.222 - modified; it contains the name of the file to modify. When 28.223 - <command>patch</command> sees a new file header, it looks for a 28.224 - file with that name to start modifying.</para> 28.225 - 28.226 - <para id="x_3c7">After the file header comes a series of 28.227 - <emphasis>hunks</emphasis>. Each hunk starts with a header; 28.228 - this identifies the range of line numbers within the file that 28.229 - the hunk should modify. Following the header, a hunk starts and 28.230 - ends with a few (usually three) lines of text from the 28.231 - unmodified file; these are called the 28.232 - <emphasis>context</emphasis> for the hunk. If there's only a 28.233 - small amount of context between successive hunks, 28.234 - <command>diff</command> doesn't print a new hunk header; it just 28.235 - runs the hunks together, with a few lines of context between 28.236 - modifications.</para> 28.237 - 28.238 - <para id="x_3c8">Each line of context begins with a space character. Within 28.239 - the hunk, a line that begins with 28.240 - <quote><literal>-</literal></quote> means <quote>remove this 28.241 - line,</quote> while a line that begins with 28.242 - <quote><literal>+</literal></quote> means <quote>insert this 28.243 - line.</quote> For example, a line that is modified is 28.244 - represented by one deletion and one insertion.</para> 28.245 - 28.246 - <para id="x_3c9">We will return to some of the more subtle aspects of patches 28.247 - later (in <xref linkend="sec:mq:adv-patch"/>), but you 28.248 - should have 28.249 - enough information now to use MQ.</para> 28.250 - 28.251 - </sect1> 28.252 - <sect1 id="sec:mq:start"> 28.253 - <title>Getting started with Mercurial Queues</title> 28.254 - 28.255 - <para id="x_3ca">Because MQ is implemented as an extension, you must 28.256 - explicitly enable before you can use it. (You don't need to 28.257 - download anything; MQ ships with the standard Mercurial 28.258 - distribution.) To enable MQ, edit your <filename 28.259 - role="home">~/.hgrc</filename> file, and add the lines 28.260 - below.</para> 28.261 - 28.262 - <programlisting>[extensions] 28.263 -hgext.mq =</programlisting> 28.264 - 28.265 - <para id="x_3cb">Once the extension is enabled, it will make a number of new 28.266 - commands available. To verify that the extension is working, 28.267 - you can use <command role="hg-cmd">hg help</command> to see if 28.268 - the <command role="hg-ext-mq">qinit</command> command is now 28.269 - available.</para> 28.270 - 28.271 -&interaction.mq.qinit-help.help; 28.272 - 28.273 - <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial 28.274 - repository, and its commands only operate within that 28.275 - repository. To get started, simply prepare the repository using 28.276 - the <command role="hg-ext-mq">qinit</command> command.</para> 28.277 - 28.278 -&interaction.mq.tutorial.qinit; 28.279 - 28.280 - <para id="x_3cd">This command creates an empty directory called <filename 28.281 - role="special" class="directory">.hg/patches</filename>, where 28.282 - MQ will keep its metadata. As with many Mercurial commands, the 28.283 - <command role="hg-ext-mq">qinit</command> command prints nothing 28.284 - if it succeeds.</para> 28.285 - 28.286 - <sect2> 28.287 - <title>Creating a new patch</title> 28.288 - 28.289 - <para id="x_3ce">To begin work on a new patch, use the <command 28.290 - role="hg-ext-mq">qnew</command> command. This command takes 28.291 - one argument, the name of the patch to create.</para> 28.292 - 28.293 - <para id="x_3cf">MQ will use this as the name of an actual file in the 28.294 - <filename role="special" 28.295 - class="directory">.hg/patches</filename> directory, as you 28.296 - can see below.</para> 28.297 - 28.298 -&interaction.mq.tutorial.qnew; 28.299 - 28.300 - <para id="x_3d0">Also newly present in the <filename role="special" 28.301 - class="directory">.hg/patches</filename> directory are two 28.302 - other files, <filename role="special">series</filename> and 28.303 - <filename role="special">status</filename>. The <filename 28.304 - role="special">series</filename> file lists all of the 28.305 - patches that MQ knows about for this repository, with one 28.306 - patch per line. Mercurial uses the <filename 28.307 - role="special">status</filename> file for internal 28.308 - book-keeping; it tracks all of the patches that MQ has 28.309 - <emphasis>applied</emphasis> in this repository.</para> 28.310 - 28.311 - <note> 28.312 - <para id="x_3d1"> You may sometimes want to edit the <filename 28.313 - role="special">series</filename> file by hand; for 28.314 - example, to change the sequence in which some patches are 28.315 - applied. However, manually editing the <filename 28.316 - role="special">status</filename> file is almost always a 28.317 - bad idea, as it's easy to corrupt MQ's idea of what is 28.318 - happening.</para> 28.319 - </note> 28.320 - 28.321 - <para id="x_3d2">Once you have created your new patch, you can edit files 28.322 - in the working directory as you usually would. All of the 28.323 - normal Mercurial commands, such as <command role="hg-cmd">hg 28.324 - diff</command> and <command role="hg-cmd">hg 28.325 - annotate</command>, work exactly as they did before.</para> 28.326 - 28.327 - </sect2> 28.328 - <sect2> 28.329 - <title>Refreshing a patch</title> 28.330 - 28.331 - <para id="x_3d3">When you reach a point where you want to save your work, 28.332 - use the <command role="hg-ext-mq">qrefresh</command> command 28.333 - to update the patch you are working on.</para> 28.334 - 28.335 -&interaction.mq.tutorial.qrefresh; 28.336 - 28.337 - <para id="x_3d4">This command folds the changes you have made in the 28.338 - working directory into your patch, and updates its 28.339 - corresponding changeset to contain those changes.</para> 28.340 - 28.341 - <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command> 28.342 - as often as you like, so it's a good way to 28.343 - <quote>checkpoint</quote> your work. Refresh your patch at an 28.344 - opportune time; try an experiment; and if the experiment 28.345 - doesn't work out, <command role="hg-cmd">hg revert</command> 28.346 - your modifications back to the last time you refreshed.</para> 28.347 - 28.348 -&interaction.mq.tutorial.qrefresh2; 28.349 - 28.350 - </sect2> 28.351 - <sect2> 28.352 - <title>Stacking and tracking patches</title> 28.353 - 28.354 - <para id="x_3d6">Once you have finished working on a patch, or need to work 28.355 - on another, you can use the <command 28.356 - role="hg-ext-mq">qnew</command> command again to create a 28.357 - new patch. Mercurial will apply this patch on top of your 28.358 - existing patch.</para> 28.359 - 28.360 -&interaction.mq.tutorial.qnew2; 28.361 - <para id="x_3d7">Notice that the patch contains the changes in our prior 28.362 - patch as part of its context (you can see this more clearly in 28.363 - the output of <command role="hg-cmd">hg 28.364 - annotate</command>).</para> 28.365 - 28.366 - <para id="x_3d8">So far, with the exception of <command 28.367 - role="hg-ext-mq">qnew</command> and <command 28.368 - role="hg-ext-mq">qrefresh</command>, we've been careful to 28.369 - only use regular Mercurial commands. However, MQ provides 28.370 - many commands that are easier to use when you are thinking 28.371 - about patches, as illustrated below.</para> 28.372 - 28.373 -&interaction.mq.tutorial.qseries; 28.374 - 28.375 - <itemizedlist> 28.376 - <listitem><para id="x_3d9">The <command 28.377 - role="hg-ext-mq">qseries</command> command lists every 28.378 - patch that MQ knows about in this repository, from oldest 28.379 - to newest (most recently 28.380 - <emphasis>created</emphasis>).</para> 28.381 - </listitem> 28.382 - <listitem><para id="x_3da">The <command 28.383 - role="hg-ext-mq">qapplied</command> command lists every 28.384 - patch that MQ has <emphasis>applied</emphasis> in this 28.385 - repository, again from oldest to newest (most recently 28.386 - applied).</para> 28.387 - </listitem></itemizedlist> 28.388 - 28.389 - </sect2> 28.390 - <sect2> 28.391 - <title>Manipulating the patch stack</title> 28.392 - 28.393 - <para id="x_3db">The previous discussion implied that there must be a 28.394 - difference between <quote>known</quote> and 28.395 - <quote>applied</quote> patches, and there is. MQ can manage a 28.396 - patch without it being applied in the repository.</para> 28.397 - 28.398 - <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding 28.399 - changeset in the repository, and the effects of the patch and 28.400 - changeset are visible in the working directory. You can undo 28.401 - the application of a patch using the <command 28.402 - role="hg-ext-mq">qpop</command> command. MQ still 28.403 - <emphasis>knows about</emphasis>, or manages, a popped patch, 28.404 - but the patch no longer has a corresponding changeset in the 28.405 - repository, and the working directory does not contain the 28.406 - changes made by the patch. <xref 28.407 - linkend="fig:mq:stack"/> illustrates 28.408 - the difference between applied and tracked patches.</para> 28.409 - 28.410 - <figure id="fig:mq:stack"> 28.411 - <title>Applied and unapplied patches in the MQ patch 28.412 - stack</title> 28.413 - <mediaobject> 28.414 - <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject> 28.415 - <textobject><phrase>XXX add text</phrase></textobject> 28.416 - </mediaobject> 28.417 - </figure> 28.418 - 28.419 - <para id="x_3de">You can reapply an unapplied, or popped, patch using the 28.420 - <command role="hg-ext-mq">qpush</command> command. This 28.421 - creates a new changeset to correspond to the patch, and the 28.422 - patch's changes once again become present in the working 28.423 - directory. See below for examples of <command 28.424 - role="hg-ext-mq">qpop</command> and <command 28.425 - role="hg-ext-mq">qpush</command> in action.</para> 28.426 -&interaction.mq.tutorial.qpop; 28.427 - 28.428 - <para id="x_3df">Notice that once we have popped a patch or two patches, 28.429 - the output of <command role="hg-ext-mq">qseries</command> 28.430 - remains the same, while that of <command 28.431 - role="hg-ext-mq">qapplied</command> has changed.</para> 28.432 - 28.433 - 28.434 - </sect2> 28.435 - <sect2> 28.436 - <title>Pushing and popping many patches</title> 28.437 - 28.438 - <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and 28.439 - <command role="hg-ext-mq">qpop</command> each operate on a 28.440 - single patch at a time by default, you can push and pop many 28.441 - patches in one go. The <option 28.442 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to 28.443 - <command role="hg-ext-mq">qpush</command> causes it to push 28.444 - all unapplied patches, while the <option 28.445 - role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command 28.446 - role="hg-ext-mq">qpop</command> causes it to pop all applied 28.447 - patches. (For some more ways to push and pop many patches, 28.448 - see <xref linkend="sec:mq:perf"/> below.)</para> 28.449 - 28.450 -&interaction.mq.tutorial.qpush-a; 28.451 - 28.452 - </sect2> 28.453 - <sect2> 28.454 - <title>Safety checks, and overriding them</title> 28.455 - 28.456 - <para id="x_3e1">Several MQ commands check the working directory before 28.457 - they do anything, and fail if they find any modifications. 28.458 - They do this to ensure that you won't lose any changes that 28.459 - you have made, but not yet incorporated into a patch. The 28.460 - example below illustrates this; the <command 28.461 - role="hg-ext-mq">qnew</command> command will not create a 28.462 - new patch if there are outstanding changes, caused in this 28.463 - case by the <command role="hg-cmd">hg add</command> of 28.464 - <filename>file3</filename>.</para> 28.465 - 28.466 -&interaction.mq.tutorial.add; 28.467 - 28.468 - <para id="x_3e2">Commands that check the working directory all take an 28.469 - <quote>I know what I'm doing</quote> option, which is always 28.470 - named <option>-f</option>. The exact meaning of 28.471 - <option>-f</option> depends on the command. For example, 28.472 - <command role="hg-cmd">hg qnew <option 28.473 - role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command> 28.474 - will incorporate any outstanding changes into the new patch it 28.475 - creates, but <command role="hg-cmd">hg qpop <option 28.476 - role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command> 28.477 - will revert modifications to any files affected by the patch 28.478 - that it is popping. Be sure to read the documentation for a 28.479 - command's <option>-f</option> option before you use it!</para> 28.480 - 28.481 - </sect2> 28.482 - <sect2> 28.483 - <title>Working on several patches at once</title> 28.484 - 28.485 - <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command 28.486 - always refreshes the <emphasis>topmost</emphasis> applied 28.487 - patch. This means that you can suspend work on one patch (by 28.488 - refreshing it), pop or push to make a different patch the top, 28.489 - and work on <emphasis>that</emphasis> patch for a 28.490 - while.</para> 28.491 - 28.492 - <para id="x_3e4">Here's an example that illustrates how you can use this 28.493 - ability. Let's say you're developing a new feature as two 28.494 - patches. The first is a change to the core of your software, 28.495 - and the second&emdash;layered on top of the 28.496 - first&emdash;changes the user interface to use the code you 28.497 - just added to the core. If you notice a bug in the core while 28.498 - you're working on the UI patch, it's easy to fix the core. 28.499 - Simply <command role="hg-ext-mq">qrefresh</command> the UI 28.500 - patch to save your in-progress changes, and <command 28.501 - role="hg-ext-mq">qpop</command> down to the core patch. Fix 28.502 - the core bug, <command role="hg-ext-mq">qrefresh</command> the 28.503 - core patch, and <command role="hg-ext-mq">qpush</command> back 28.504 - to the UI patch to continue where you left off.</para> 28.505 - 28.506 - </sect2> 28.507 - </sect1> 28.508 - <sect1 id="sec:mq:adv-patch"> 28.509 - <title>More about patches</title> 28.510 - 28.511 - <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply 28.512 - patches, so it's helpful to know a few more detailed aspects of 28.513 - how <command>patch</command> works, and about patches 28.514 - themselves.</para> 28.515 - 28.516 - <sect2> 28.517 - <title>The strip count</title> 28.518 - 28.519 - <para id="x_3e6">If you look at the file headers in a patch, you will 28.520 - notice that the pathnames usually have an extra component on 28.521 - the front that isn't present in the actual path name. This is 28.522 - a holdover from the way that people used to generate patches 28.523 - (people still do this, but it's somewhat rare with modern 28.524 - revision control tools).</para> 28.525 - 28.526 - <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide 28.527 - that she wanted to create a patch. So she'd rename her 28.528 - working directory, unpack the tarball again (hence the need 28.529 - for the rename), and use the <option 28.530 - role="cmd-opt-diff">-r</option> and <option 28.531 - role="cmd-opt-diff">-N</option> options to 28.532 - <command>diff</command> to recursively generate a patch 28.533 - between the unmodified directory and the modified one. The 28.534 - result would be that the name of the unmodified directory 28.535 - would be at the front of the left-hand path in every file 28.536 - header, and the name of the modified directory would be at the 28.537 - front of the right-hand path.</para> 28.538 - 28.539 - <para id="x_3e8">Since someone receiving a patch from the Alices of the net 28.540 - would be unlikely to have unmodified and modified directories 28.541 - with exactly the same names, the <command>patch</command> 28.542 - command has a <option role="cmd-opt-patch">-p</option> option 28.543 - that indicates the number of leading path name components to 28.544 - strip when trying to apply a patch. This number is called the 28.545 - <emphasis>strip count</emphasis>.</para> 28.546 - 28.547 - <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means 28.548 - <quote>use a strip count of one</quote>. If 28.549 - <command>patch</command> sees a file name 28.550 - <filename>foo/bar/baz</filename> in a file header, it will 28.551 - strip <filename>foo</filename> and try to patch a file named 28.552 - <filename>bar/baz</filename>. (Strictly speaking, the strip 28.553 - count refers to the number of <emphasis>path 28.554 - separators</emphasis> (and the components that go with them 28.555 - ) to strip. A strip count of one will turn 28.556 - <filename>foo/bar</filename> into <filename>bar</filename>, 28.557 - but <filename>/foo/bar</filename> (notice the extra leading 28.558 - slash) into <filename>foo/bar</filename>.)</para> 28.559 - 28.560 - <para id="x_3ea">The <quote>standard</quote> strip count for patches is 28.561 - one; almost all patches contain one leading path name 28.562 - component that needs to be stripped. Mercurial's <command 28.563 - role="hg-cmd">hg diff</command> command generates path names 28.564 - in this form, and the <command role="hg-cmd">hg 28.565 - import</command> command and MQ expect patches to have a 28.566 - strip count of one.</para> 28.567 - 28.568 - <para id="x_3eb">If you receive a patch from someone that you want to add 28.569 - to your patch queue, and the patch needs a strip count other 28.570 - than one, you cannot just <command 28.571 - role="hg-ext-mq">qimport</command> the patch, because 28.572 - <command role="hg-ext-mq">qimport</command> does not yet have 28.573 - a <literal>-p</literal> option (see <ulink role="hg-bug" 28.574 - url="http://www.selenic.com/mercurial/bts/issue311">issue 28.575 - 311</ulink>). Your best bet is to <command 28.576 - role="hg-ext-mq">qnew</command> a patch of your own, then 28.577 - use <command>patch -pN</command> to apply their patch, 28.578 - followed by <command role="hg-cmd">hg addremove</command> to 28.579 - pick up any files added or removed by the patch, followed by 28.580 - <command role="hg-ext-mq">hg qrefresh</command>. This 28.581 - complexity may become unnecessary; see <ulink role="hg-bug" 28.582 - url="http://www.selenic.com/mercurial/bts/issue311">issue 28.583 - 311</ulink> for details. 28.584 - </para> 28.585 - </sect2> 28.586 - <sect2> 28.587 - <title>Strategies for applying a patch</title> 28.588 - 28.589 - <para id="x_3ec">When <command>patch</command> applies a hunk, it tries a 28.590 - handful of successively less accurate strategies to try to 28.591 - make the hunk apply. This falling-back technique often makes 28.592 - it possible to take a patch that was generated against an old 28.593 - version of a file, and apply it against a newer version of 28.594 - that file.</para> 28.595 - 28.596 - <para id="x_3ed">First, <command>patch</command> tries an exact match, 28.597 - where the line numbers, the context, and the text to be 28.598 - modified must apply exactly. If it cannot make an exact 28.599 - match, it tries to find an exact match for the context, 28.600 - without honouring the line numbering information. If this 28.601 - succeeds, it prints a line of output saying that the hunk was 28.602 - applied, but at some <emphasis>offset</emphasis> from the 28.603 - original line number.</para> 28.604 - 28.605 - <para id="x_3ee">If a context-only match fails, <command>patch</command> 28.606 - removes the first and last lines of the context, and tries a 28.607 - <emphasis>reduced</emphasis> context-only match. If the hunk 28.608 - with reduced context succeeds, it prints a message saying that 28.609 - it applied the hunk with a <emphasis>fuzz factor</emphasis> 28.610 - (the number after the fuzz factor indicates how many lines of 28.611 - context <command>patch</command> had to trim before the patch 28.612 - applied).</para> 28.613 - 28.614 - <para id="x_3ef">When neither of these techniques works, 28.615 - <command>patch</command> prints a message saying that the hunk 28.616 - in question was rejected. It saves rejected hunks (also 28.617 - simply called <quote>rejects</quote>) to a file with the same 28.618 - name, and an added <filename role="special">.rej</filename> 28.619 - extension. It also saves an unmodified copy of the file with 28.620 - a <filename role="special">.orig</filename> extension; the 28.621 - copy of the file without any extensions will contain any 28.622 - changes made by hunks that <emphasis>did</emphasis> apply 28.623 - cleanly. If you have a patch that modifies 28.624 - <filename>foo</filename> with six hunks, and one of them fails 28.625 - to apply, you will have: an unmodified 28.626 - <filename>foo.orig</filename>, a <filename>foo.rej</filename> 28.627 - containing one hunk, and <filename>foo</filename>, containing 28.628 - the changes made by the five successful hunks.</para> 28.629 - 28.630 - </sect2> 28.631 - <sect2> 28.632 - <title>Some quirks of patch representation</title> 28.633 - 28.634 - <para id="x_3f0">There are a few useful things to know about how 28.635 - <command>patch</command> works with files.</para> 28.636 - <itemizedlist> 28.637 - <listitem><para id="x_3f1">This should already be obvious, but 28.638 - <command>patch</command> cannot handle binary 28.639 - files.</para> 28.640 - </listitem> 28.641 - <listitem><para id="x_3f2">Neither does it care about the executable bit; 28.642 - it creates new files as readable, but not 28.643 - executable.</para> 28.644 - </listitem> 28.645 - <listitem><para id="x_3f3"><command>patch</command> treats the removal of 28.646 - a file as a diff between the file to be removed and the 28.647 - empty file. So your idea of <quote>I deleted this 28.648 - file</quote> looks like <quote>every line of this file 28.649 - was deleted</quote> in a patch.</para> 28.650 - </listitem> 28.651 - <listitem><para id="x_3f4">It treats the addition of a file as a diff 28.652 - between the empty file and the file to be added. So in a 28.653 - patch, your idea of <quote>I added this file</quote> looks 28.654 - like <quote>every line of this file was 28.655 - added</quote>.</para> 28.656 - </listitem> 28.657 - <listitem><para id="x_3f5">It treats a renamed file as the removal of the 28.658 - old name, and the addition of the new name. This means 28.659 - that renamed files have a big footprint in patches. (Note 28.660 - also that Mercurial does not currently try to infer when 28.661 - files have been renamed or copied in a patch.)</para> 28.662 - </listitem> 28.663 - <listitem><para id="x_3f6"><command>patch</command> cannot represent 28.664 - empty files, so you cannot use a patch to represent the 28.665 - notion <quote>I added this empty file to the 28.666 - tree</quote>.</para> 28.667 - </listitem></itemizedlist> 28.668 - </sect2> 28.669 - <sect2> 28.670 - <title>Beware the fuzz</title> 28.671 - 28.672 - <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor, 28.673 - will often be completely successful, these inexact techniques 28.674 - naturally leave open the possibility of corrupting the patched 28.675 - file. The most common cases typically involve applying a 28.676 - patch twice, or at an incorrect location in the file. If 28.677 - <command>patch</command> or <command 28.678 - role="hg-ext-mq">qpush</command> ever mentions an offset or 28.679 - fuzz factor, you should make sure that the modified files are 28.680 - correct afterwards.</para> 28.681 - 28.682 - <para id="x_3f8">It's often a good idea to refresh a patch that has applied 28.683 - with an offset or fuzz factor; refreshing the patch generates 28.684 - new context information that will make it apply cleanly. I 28.685 - say <quote>often,</quote> not <quote>always,</quote> because 28.686 - sometimes refreshing a patch will make it fail to apply 28.687 - against a different revision of the underlying files. In some 28.688 - cases, such as when you're maintaining a patch that must sit 28.689 - on top of multiple versions of a source tree, it's acceptable 28.690 - to have a patch apply with some fuzz, provided you've verified 28.691 - the results of the patching process in such cases.</para> 28.692 - 28.693 - </sect2> 28.694 - <sect2> 28.695 - <title>Handling rejection</title> 28.696 - 28.697 - <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to 28.698 - apply a patch, it will print an error message and exit. If it 28.699 - has left <filename role="special">.rej</filename> files 28.700 - behind, it is usually best to fix up the rejected hunks before 28.701 - you push more patches or do any further work.</para> 28.702 - 28.703 - <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly, 28.704 - and no longer does because you've changed the underlying code 28.705 - that your patches are based on, Mercurial Queues can help; see 28.706 - <xref linkend="sec:mq:merge"/> for details.</para> 28.707 - 28.708 - <para id="x_3fb">Unfortunately, there aren't any great techniques for 28.709 - dealing with rejected hunks. Most often, you'll need to view 28.710 - the <filename role="special">.rej</filename> file and edit the 28.711 - target file, applying the rejected hunks by hand.</para> 28.712 - 28.713 - <para id="x_3fc">If you're feeling adventurous, Neil Brown, a Linux kernel 28.714 - hacker, wrote a tool called <command>wiggle</command> 28.715 - <citation>web:wiggle</citation>, which is more vigorous than 28.716 - <command>patch</command> in its attempts to make a patch 28.717 - apply.</para> 28.718 - 28.719 - <para id="x_3fd">Another Linux kernel hacker, Chris Mason (the author of 28.720 - Mercurial Queues), wrote a similar tool called 28.721 - <command>mpatch</command> <citation>web:mpatch</citation>, 28.722 - which takes a simple approach to automating the application of 28.723 - hunks rejected by <command>patch</command>. The 28.724 - <command>mpatch</command> command can help with four common 28.725 - reasons that a hunk may be rejected:</para> 28.726 - 28.727 - <itemizedlist> 28.728 - <listitem><para id="x_3fe">The context in the middle of a hunk has 28.729 - changed.</para> 28.730 - </listitem> 28.731 - <listitem><para id="x_3ff">A hunk is missing some context at the 28.732 - beginning or end.</para> 28.733 - </listitem> 28.734 - <listitem><para id="x_400">A large hunk might apply better&emdash;either 28.735 - entirely or in part&emdash;if it was broken up into 28.736 - smaller hunks.</para> 28.737 - </listitem> 28.738 - <listitem><para id="x_401">A hunk removes lines with slightly different 28.739 - content than those currently present in the file.</para> 28.740 - </listitem></itemizedlist> 28.741 - 28.742 - <para id="x_402">If you use <command>wiggle</command> or 28.743 - <command>mpatch</command>, you should be doubly careful to 28.744 - check your results when you're done. In fact, 28.745 - <command>mpatch</command> enforces this method of 28.746 - double-checking the tool's output, by automatically dropping 28.747 - you into a merge program when it has done its job, so that you 28.748 - can verify its work and finish off any remaining 28.749 - merges.</para> 28.750 - 28.751 - </sect2> 28.752 - </sect1> 28.753 - <sect1 id="sec:mq:perf"> 28.754 - <title>Getting the best performance out of MQ</title> 28.755 - 28.756 - <para id="x_403">MQ is very efficient at handling a large number of patches. 28.757 - I ran some performance experiments in mid-2006 for a talk that I 28.758 - gave at the 2006 EuroPython conference 28.759 - <citation>web:europython</citation>. I used as my data set the 28.760 - Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. 28.761 - I applied these on top of a Linux kernel repository containing 28.762 - all 27,472 revisions between Linux 2.6.12-rc2 and Linux 28.763 - 2.6.17.</para> 28.764 - 28.765 - <para id="x_404">On my old, slow laptop, I was able to <command 28.766 - role="hg-cmd">hg qpush <option 28.767 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all 28.768 - 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop 28.769 - <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 28.770 - them all in 30 seconds. (On a newer laptop, the time to push 28.771 - all patches dropped to two minutes.) I could <command 28.772 - role="hg-ext-mq">qrefresh</command> one of the biggest patches 28.773 - (which made 22,779 lines of changes to 287 files) in 6.6 28.774 - seconds.</para> 28.775 - 28.776 - <para id="x_405">Clearly, MQ is well suited to working in large trees, but 28.777 - there are a few tricks you can use to get the best performance 28.778 - of it.</para> 28.779 - 28.780 - <para id="x_406">First of all, try to <quote>batch</quote> operations 28.781 - together. Every time you run <command 28.782 - role="hg-ext-mq">qpush</command> or <command 28.783 - role="hg-ext-mq">qpop</command>, these commands scan the 28.784 - working directory once to make sure you haven't made some 28.785 - changes and then forgotten to run <command 28.786 - role="hg-ext-mq">qrefresh</command>. On a small tree, the 28.787 - time that this scan takes is unnoticeable. However, on a 28.788 - medium-sized tree (containing tens of thousands of files), it 28.789 - can take a second or more.</para> 28.790 - 28.791 - <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command 28.792 - role="hg-ext-mq">qpop</command> commands allow you to push and 28.793 - pop multiple patches at a time. You can identify the 28.794 - <quote>destination patch</quote> that you want to end up at. 28.795 - When you <command role="hg-ext-mq">qpush</command> with a 28.796 - destination specified, it will push patches until that patch is 28.797 - at the top of the applied stack. When you <command 28.798 - role="hg-ext-mq">qpop</command> to a destination, MQ will pop 28.799 - patches until the destination patch is at the top.</para> 28.800 - 28.801 - <para id="x_408">You can identify a destination patch using either the name 28.802 - of the patch, or by number. If you use numeric addressing, 28.803 - patches are counted from zero; this means that the first patch 28.804 - is zero, the second is one, and so on.</para> 28.805 - 28.806 - </sect1> 28.807 - <sect1 id="sec:mq:merge"> 28.808 - <title>Updating your patches when the underlying code 28.809 - changes</title> 28.810 - 28.811 - <para id="x_409">It's common to have a stack of patches on top of an 28.812 - underlying repository that you don't modify directly. If you're 28.813 - working on changes to third-party code, or on a feature that is 28.814 - taking longer to develop than the rate of change of the code 28.815 - beneath, you will often need to sync up with the underlying 28.816 - code, and fix up any hunks in your patches that no longer apply. 28.817 - This is called <emphasis>rebasing</emphasis> your patch 28.818 - series.</para> 28.819 - 28.820 - <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg 28.821 - qpop <option role="hg-ext-mq-cmd-qpop-opt">hg 28.822 - -a</option></command> your patches, then <command 28.823 - role="hg-cmd">hg pull</command> changes into the underlying 28.824 - repository, and finally <command role="hg-cmd">hg qpush <option 28.825 - role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your 28.826 - patches again. MQ will stop pushing any time it runs across a 28.827 - patch that fails to apply during conflicts, allowing you to fix 28.828 - your conflicts, <command role="hg-ext-mq">qrefresh</command> the 28.829 - affected patch, and continue pushing until you have fixed your 28.830 - entire stack.</para> 28.831 - 28.832 - <para id="x_40b">This approach is easy to use and works well if you don't 28.833 - expect changes to the underlying code to affect how well your 28.834 - patches apply. If your patch stack touches code that is modified 28.835 - frequently or invasively in the underlying repository, however, 28.836 - fixing up rejected hunks by hand quickly becomes 28.837 - tiresome.</para> 28.838 - 28.839 - <para id="x_40c">It's possible to partially automate the rebasing process. 28.840 - If your patches apply cleanly against some revision of the 28.841 - underlying repo, MQ can use this information to help you to 28.842 - resolve conflicts between your patches and a different 28.843 - revision.</para> 28.844 - 28.845 - <para id="x_40d">The process is a little involved.</para> 28.846 - <orderedlist> 28.847 - <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush 28.848 - -a</command> all of your patches on top of the revision 28.849 - where you know that they apply cleanly.</para> 28.850 - </listitem> 28.851 - <listitem><para id="x_40f">Save a backup copy of your patch directory using 28.852 - <command role="hg-cmd">hg qsave <option 28.853 - role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option 28.854 - role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. 28.855 - This prints the name of the directory that it has saved the 28.856 - patches in. It will save the patches to a directory called 28.857 - <filename role="special" 28.858 - class="directory">.hg/patches.N</filename>, where 28.859 - <literal>N</literal> is a small integer. It also commits a 28.860 - <quote>save changeset</quote> on top of your applied 28.861 - patches; this is for internal book-keeping, and records the 28.862 - states of the <filename role="special">series</filename> and 28.863 - <filename role="special">status</filename> files.</para> 28.864 - </listitem> 28.865 - <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to 28.866 - bring new changes into the underlying repository. (Don't 28.867 - run <command role="hg-cmd">hg pull -u</command>; see below 28.868 - for why.)</para> 28.869 - </listitem> 28.870 - <listitem><para id="x_411">Update to the new tip revision, using <command 28.871 - role="hg-cmd">hg update <option 28.872 - role="hg-opt-update">-C</option></command> to override 28.873 - the patches you have pushed.</para> 28.874 - </listitem> 28.875 - <listitem><para id="x_412">Merge all patches using <command>hg qpush -m 28.876 - -a</command>. The <option 28.877 - role="hg-ext-mq-cmd-qpush-opt">-m</option> option to 28.878 - <command role="hg-ext-mq">qpush</command> tells MQ to 28.879 - perform a three-way merge if the patch fails to 28.880 - apply.</para> 28.881 - </listitem></orderedlist> 28.882 - 28.883 - <para id="x_413">During the <command role="hg-cmd">hg qpush <option 28.884 - role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, 28.885 - each patch in the <filename role="special">series</filename> 28.886 - file is applied normally. If a patch applies with fuzz or 28.887 - rejects, MQ looks at the queue you <command 28.888 - role="hg-ext-mq">qsave</command>d, and performs a three-way 28.889 - merge with the corresponding changeset. This merge uses 28.890 - Mercurial's normal merge machinery, so it may pop up a GUI merge 28.891 - tool to help you to resolve problems.</para> 28.892 - 28.893 - <para id="x_414">When you finish resolving the effects of a patch, MQ 28.894 - refreshes your patch based on the result of the merge.</para> 28.895 - 28.896 - <para id="x_415">At the end of this process, your repository will have one 28.897 - extra head from the old patch queue, and a copy of the old patch 28.898 - queue will be in <filename role="special" 28.899 - class="directory">.hg/patches.N</filename>. You can remove the 28.900 - extra head using <command role="hg-cmd">hg qpop -a -n 28.901 - patches.N</command> or <command role="hg-cmd">hg 28.902 - strip</command>. You can delete <filename role="special" 28.903 - class="directory">.hg/patches.N</filename> once you are sure 28.904 - that you no longer need it as a backup.</para> 28.905 - 28.906 - </sect1> 28.907 - <sect1> 28.908 - <title>Identifying patches</title> 28.909 - 28.910 - <para id="x_416">MQ commands that work with patches let you refer to a patch 28.911 - either by using its name or by a number. By name is obvious 28.912 - enough; pass the name <filename>foo.patch</filename> to <command 28.913 - role="hg-ext-mq">qpush</command>, for example, and it will 28.914 - push patches until <filename>foo.patch</filename> is 28.915 - applied.</para> 28.916 - 28.917 - <para id="x_417">As a shortcut, you can refer to a patch using both a name 28.918 - and a numeric offset; <literal>foo.patch-2</literal> means 28.919 - <quote>two patches before <literal>foo.patch</literal></quote>, 28.920 - while <literal>bar.patch+4</literal> means <quote>four patches 28.921 - after <literal>bar.patch</literal></quote>.</para> 28.922 - 28.923 - <para id="x_418">Referring to a patch by index isn't much different. The 28.924 - first patch printed in the output of <command 28.925 - role="hg-ext-mq">qseries</command> is patch zero (yes, it's 28.926 - one of those start-at-zero counting systems); the second is 28.927 - patch one; and so on.</para> 28.928 - 28.929 - <para id="x_419">MQ also makes it easy to work with patches when you are 28.930 - using normal Mercurial commands. Every command that accepts a 28.931 - changeset ID will also accept the name of an applied patch. MQ 28.932 - augments the tags normally in the repository with an eponymous 28.933 - one for each applied patch. In addition, the special tags 28.934 - <literal role="tag">qbase</literal> and 28.935 - <literal role="tag">qtip</literal> identify 28.936 - the <quote>bottom-most</quote> and topmost applied patches, 28.937 - respectively.</para> 28.938 - 28.939 - <para id="x_41a">These additions to Mercurial's normal tagging capabilities 28.940 - make dealing with patches even more of a breeze.</para> 28.941 - <itemizedlist> 28.942 - <listitem><para id="x_41b">Want to patchbomb a mailing list with your 28.943 - latest series of changes?</para> 28.944 - <programlisting>hg email qbase:qtip</programlisting> 28.945 - <para id="x_41c"> (Don't know what <quote>patchbombing</quote> is? See 28.946 - <xref linkend="sec:hgext:patchbomb"/>.)</para> 28.947 - </listitem> 28.948 - <listitem><para id="x_41d">Need to see all of the patches since 28.949 - <literal>foo.patch</literal> that have touched files in a 28.950 - subdirectory of your tree?</para> 28.951 - <programlisting>hg log -r foo.patch:qtip subdir</programlisting> 28.952 - </listitem> 28.953 - </itemizedlist> 28.954 - 28.955 - <para id="x_41e">Because MQ makes the names of patches available to the rest 28.956 - of Mercurial through its normal internal tag machinery, you 28.957 - don't need to type in the entire name of a patch when you want 28.958 - to identify it by name.</para> 28.959 - 28.960 - <para id="x_41f">Another nice consequence of representing patch names as tags 28.961 - is that when you run the <command role="hg-cmd">hg log</command> 28.962 - command, it will display a patch's name as a tag, simply as part 28.963 - of its normal output. This makes it easy to visually 28.964 - distinguish applied patches from underlying 28.965 - <quote>normal</quote> revisions. The following example shows a 28.966 - few normal Mercurial commands in use with applied 28.967 - patches.</para> 28.968 - 28.969 -&interaction.mq.id.output; 28.970 - 28.971 - </sect1> 28.972 - <sect1> 28.973 - <title>Useful things to know about</title> 28.974 - 28.975 - <para id="x_420">There are a number of aspects of MQ usage that don't fit 28.976 - tidily into sections of their own, but that are good to know. 28.977 - Here they are, in one place.</para> 28.978 - 28.979 - <itemizedlist> 28.980 - <listitem><para id="x_421">Normally, when you <command 28.981 - role="hg-ext-mq">qpop</command> a patch and <command 28.982 - role="hg-ext-mq">qpush</command> it again, the changeset 28.983 - that represents the patch after the pop/push will have a 28.984 - <emphasis>different identity</emphasis> than the changeset 28.985 - that represented the hash beforehand. See <xref 28.986 - linkend="sec:mqref:cmd:qpush"/> for 28.987 - information as to why this is.</para> 28.988 - </listitem> 28.989 - <listitem><para id="x_422">It's not a good idea to <command 28.990 - role="hg-cmd">hg merge</command> changes from another 28.991 - branch with a patch changeset, at least if you want to 28.992 - maintain the <quote>patchiness</quote> of that changeset and 28.993 - changesets below it on the patch stack. If you try to do 28.994 - this, it will appear to succeed, but MQ will become 28.995 - confused.</para> 28.996 - </listitem></itemizedlist> 28.997 - 28.998 - </sect1> 28.999 - <sect1 id="sec:mq:repo"> 28.1000 - <title>Managing patches in a repository</title> 28.1001 - 28.1002 - <para id="x_423">Because MQ's <filename role="special" 28.1003 - class="directory">.hg/patches</filename> directory resides 28.1004 - outside a Mercurial repository's working directory, the 28.1005 - <quote>underlying</quote> Mercurial repository knows nothing 28.1006 - about the management or presence of patches.</para> 28.1007 - 28.1008 - <para id="x_424">This presents the interesting possibility of managing the 28.1009 - contents of the patch directory as a Mercurial repository in its 28.1010 - own right. This can be a useful way to work. For example, you 28.1011 - can work on a patch for a while, <command 28.1012 - role="hg-ext-mq">qrefresh</command> it, then <command 28.1013 - role="hg-cmd">hg commit</command> the current state of the 28.1014 - patch. This lets you <quote>roll back</quote> to that version 28.1015 - of the patch later on.</para> 28.1016 - 28.1017 - <para id="x_425">You can then share different versions of the same patch 28.1018 - stack among multiple underlying repositories. I use this when I 28.1019 - am developing a Linux kernel feature. I have a pristine copy of 28.1020 - my kernel sources for each of several CPU architectures, and a 28.1021 - cloned repository under each that contains the patches I am 28.1022 - working on. When I want to test a change on a different 28.1023 - architecture, I push my current patches to the patch repository 28.1024 - associated with that kernel tree, pop and push all of my 28.1025 - patches, and build and test that kernel.</para> 28.1026 - 28.1027 - <para id="x_426">Managing patches in a repository makes it possible for 28.1028 - multiple developers to work on the same patch series without 28.1029 - colliding with each other, all on top of an underlying source 28.1030 - base that they may or may not control.</para> 28.1031 - 28.1032 - <sect2> 28.1033 - <title>MQ support for patch repositories</title> 28.1034 - 28.1035 - <para id="x_427">MQ helps you to work with the <filename role="special" 28.1036 - class="directory">.hg/patches</filename> directory as a 28.1037 - repository; when you prepare a repository for working with 28.1038 - patches using <command role="hg-ext-mq">qinit</command>, you 28.1039 - can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg 28.1040 - -c</option> option to create the <filename role="special" 28.1041 - class="directory">.hg/patches</filename> directory as a 28.1042 - Mercurial repository.</para> 28.1043 - 28.1044 - <note> 28.1045 - <para id="x_428"> If you forget to use the <option 28.1046 - role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you 28.1047 - can simply go into the <filename role="special" 28.1048 - class="directory">.hg/patches</filename> directory at any 28.1049 - time and run <command role="hg-cmd">hg init</command>. 28.1050 - Don't forget to add an entry for the <filename 28.1051 - role="special">status</filename> file to the <filename 28.1052 - role="special">.hgignore</filename> file, though</para> 28.1053 - 28.1054 - <para id="x_429"> (<command role="hg-cmd">hg qinit <option 28.1055 - role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> 28.1056 - does this for you automatically); you 28.1057 - <emphasis>really</emphasis> don't want to manage the 28.1058 - <filename role="special">status</filename> file.</para> 28.1059 - </note> 28.1060 - 28.1061 - <para id="x_42a">As a convenience, if MQ notices that the <filename 28.1062 - class="directory">.hg/patches</filename> directory is a 28.1063 - repository, it will automatically <command role="hg-cmd">hg 28.1064 - add</command> every patch that you create and import.</para> 28.1065 - 28.1066 - <para id="x_42b">MQ provides a shortcut command, <command 28.1067 - role="hg-ext-mq">qcommit</command>, that runs <command 28.1068 - role="hg-cmd">hg commit</command> in the <filename 28.1069 - role="special" class="directory">.hg/patches</filename> 28.1070 - directory. This saves some bothersome typing.</para> 28.1071 - 28.1072 - <para id="x_42c">Finally, as a convenience to manage the patch directory, 28.1073 - you can define the alias <command>mq</command> on Unix 28.1074 - systems. For example, on Linux systems using the 28.1075 - <command>bash</command> shell, you can include the following 28.1076 - snippet in your <filename 28.1077 - role="home">~/.bashrc</filename>.</para> 28.1078 - 28.1079 - <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting> 28.1080 - 28.1081 - <para id="x_42d">You can then issue commands of the form <command>mq 28.1082 - pull</command> from the main repository.</para> 28.1083 - 28.1084 - </sect2> 28.1085 - <sect2> 28.1086 - <title>A few things to watch out for</title> 28.1087 - 28.1088 - <para id="x_42e">MQ's support for working with a repository full of patches 28.1089 - is limited in a few small respects.</para> 28.1090 - 28.1091 - <para id="x_42f">MQ cannot automatically detect changes that you make to 28.1092 - the patch directory. If you <command role="hg-cmd">hg 28.1093 - pull</command>, manually edit, or <command role="hg-cmd">hg 28.1094 - update</command> changes to patches or the <filename 28.1095 - role="special">series</filename> file, you will have to 28.1096 - <command role="hg-cmd">hg qpop <option 28.1097 - role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and 28.1098 - then <command role="hg-cmd">hg qpush <option 28.1099 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in 28.1100 - the underlying repository to see those changes show up there. 28.1101 - If you forget to do this, you can confuse MQ's idea of which 28.1102 - patches are applied.</para> 28.1103 - 28.1104 - </sect2> 28.1105 - </sect1> 28.1106 - <sect1 id="sec:mq:tools"> 28.1107 - <title>Third party tools for working with patches</title> 28.1108 - 28.1109 - <para id="x_430">Once you've been working with patches for a while, you'll 28.1110 - find yourself hungry for tools that will help you to understand 28.1111 - and manipulate the patches you're dealing with.</para> 28.1112 - 28.1113 - <para id="x_431">The <command>diffstat</command> command 28.1114 - <citation>web:diffstat</citation> generates a histogram of the 28.1115 - modifications made to each file in a patch. It provides a good 28.1116 - way to <quote>get a sense of</quote> a patch&emdash;which files 28.1117 - it affects, and how much change it introduces to each file and 28.1118 - as a whole. (I find that it's a good idea to use 28.1119 - <command>diffstat</command>'s <option 28.1120 - role="cmd-opt-diffstat">-p</option> option as a matter of 28.1121 - course, as otherwise it will try to do clever things with 28.1122 - prefixes of file names that inevitably confuse at least 28.1123 - me.)</para> 28.1124 - 28.1125 -&interaction.mq.tools.tools; 28.1126 - 28.1127 - <para id="x_432">The <literal role="package">patchutils</literal> package 28.1128 - <citation>web:patchutils</citation> is invaluable. It provides a 28.1129 - set of small utilities that follow the <quote>Unix 28.1130 - philosophy;</quote> each does one useful thing with a patch. 28.1131 - The <literal role="package">patchutils</literal> command I use 28.1132 - most is <command>filterdiff</command>, which extracts subsets 28.1133 - from a patch file. For example, given a patch that modifies 28.1134 - hundreds of files across dozens of directories, a single 28.1135 - invocation of <command>filterdiff</command> can generate a 28.1136 - smaller patch that only touches files whose names match a 28.1137 - particular glob pattern. See <xref 28.1138 - linkend="mq-collab:tips:interdiff"/> for another 28.1139 - example.</para> 28.1140 - 28.1141 - </sect1> 28.1142 - <sect1> 28.1143 - <title>Good ways to work with patches</title> 28.1144 - 28.1145 - <para id="x_433">Whether you are working on a patch series to submit to a 28.1146 - free software or open source project, or a series that you 28.1147 - intend to treat as a sequence of regular changesets when you're 28.1148 - done, you can use some simple techniques to keep your work well 28.1149 - organized.</para> 28.1150 - 28.1151 - <para id="x_434">Give your patches descriptive names. A good name for a 28.1152 - patch might be <filename>rework-device-alloc.patch</filename>, 28.1153 - because it will immediately give you a hint what the purpose of 28.1154 - the patch is. Long names shouldn't be a problem; you won't be 28.1155 - typing the names often, but you <emphasis>will</emphasis> be 28.1156 - running commands like <command 28.1157 - role="hg-ext-mq">qapplied</command> and <command 28.1158 - role="hg-ext-mq">qtop</command> over and over. Good naming 28.1159 - becomes especially important when you have a number of patches 28.1160 - to work with, or if you are juggling a number of different tasks 28.1161 - and your patches only get a fraction of your attention.</para> 28.1162 - 28.1163 - <para id="x_435">Be aware of what patch you're working on. Use the <command 28.1164 - role="hg-ext-mq">qtop</command> command and skim over the text 28.1165 - of your patches frequently&emdash;for example, using <command 28.1166 - role="hg-cmd">hg tip <option 28.1167 - role="hg-opt-tip">-p</option></command>)&emdash;to be sure 28.1168 - of where you stand. I have several times worked on and <command 28.1169 - role="hg-ext-mq">qrefresh</command>ed a patch other than the 28.1170 - one I intended, and it's often tricky to migrate changes into 28.1171 - the right patch after making them in the wrong one.</para> 28.1172 - 28.1173 - <para id="x_436">For this reason, it is very much worth investing a little 28.1174 - time to learn how to use some of the third-party tools I 28.1175 - described in <xref linkend="sec:mq:tools"/>, 28.1176 - particularly 28.1177 - <command>diffstat</command> and <command>filterdiff</command>. 28.1178 - The former will give you a quick idea of what changes your patch 28.1179 - is making, while the latter makes it easy to splice hunks 28.1180 - selectively out of one patch and into another.</para> 28.1181 - 28.1182 - </sect1> 28.1183 - <sect1> 28.1184 - <title>MQ cookbook</title> 28.1185 - 28.1186 - <sect2> 28.1187 - <title>Manage <quote>trivial</quote> patches</title> 28.1188 - 28.1189 - <para id="x_437">Because the overhead of dropping files into a new 28.1190 - Mercurial repository is so low, it makes a lot of sense to 28.1191 - manage patches this way even if you simply want to make a few 28.1192 - changes to a source tarball that you downloaded.</para> 28.1193 - 28.1194 - <para id="x_438">Begin by downloading and unpacking the source tarball, and 28.1195 - turning it into a Mercurial repository.</para> 28.1196 - 28.1197 - &interaction.mq.tarball.download; 28.1198 - 28.1199 - <para id="x_439">Continue by creating a patch stack and making your 28.1200 - changes.</para> 28.1201 - 28.1202 - &interaction.mq.tarball.qinit; 28.1203 - 28.1204 - <para id="x_43a">Let's say a few weeks or months pass, and your package 28.1205 - author releases a new version. First, bring their changes 28.1206 - into the repository.</para> 28.1207 - 28.1208 - &interaction.mq.tarball.newsource; 28.1209 - 28.1210 - <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg 28.1211 - locate</command> above deletes all files in the working 28.1212 - directory, so that <command role="hg-cmd">hg 28.1213 - commit</command>'s <option 28.1214 - role="hg-opt-commit">--addremove</option> option can 28.1215 - actually tell which files have really been removed in the 28.1216 - newer version of the source.</para> 28.1217 - 28.1218 - <para id="x_43c">Finally, you can apply your patches on top of the new 28.1219 - tree.</para> 28.1220 - 28.1221 - &interaction.mq.tarball.repush; 28.1222 - 28.1223 - </sect2> 28.1224 - <sect2 id="sec:mq:combine"> 28.1225 - <title>Combining entire patches</title> 28.1226 - 28.1227 - <para id="x_43d">MQ provides a command, <command 28.1228 - role="hg-ext-mq">qfold</command> that lets you combine 28.1229 - entire patches. This <quote>folds</quote> the patches you 28.1230 - name, in the order you name them, into the topmost applied 28.1231 - patch, and concatenates their descriptions onto the end of its 28.1232 - description. The patches that you fold must be unapplied 28.1233 - before you fold them.</para> 28.1234 - 28.1235 - <para id="x_43e">The order in which you fold patches matters. If your 28.1236 - topmost applied patch is <literal>foo</literal>, and you 28.1237 - <command role="hg-ext-mq">qfold</command> 28.1238 - <literal>bar</literal> and <literal>quux</literal> into it, 28.1239 - you will end up with a patch that has the same effect as if 28.1240 - you applied first <literal>foo</literal>, then 28.1241 - <literal>bar</literal>, followed by 28.1242 - <literal>quux</literal>.</para> 28.1243 - 28.1244 - </sect2> 28.1245 - <sect2> 28.1246 - <title>Merging part of one patch into another</title> 28.1247 - 28.1248 - <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into 28.1249 - another is more difficult than combining entire 28.1250 - patches.</para> 28.1251 - 28.1252 - <para id="x_440">If you want to move changes to entire files, you can use 28.1253 - <command>filterdiff</command>'s <option 28.1254 - role="cmd-opt-filterdiff">-i</option> and <option 28.1255 - role="cmd-opt-filterdiff">-x</option> options to choose the 28.1256 - modifications to snip out of one patch, concatenating its 28.1257 - output onto the end of the patch you want to merge into. You 28.1258 - usually won't need to modify the patch you've merged the 28.1259 - changes from. Instead, MQ will report some rejected hunks 28.1260 - when you <command role="hg-ext-mq">qpush</command> it (from 28.1261 - the hunks you moved into the other patch), and you can simply 28.1262 - <command role="hg-ext-mq">qrefresh</command> the patch to drop 28.1263 - the duplicate hunks.</para> 28.1264 - 28.1265 - <para id="x_441">If you have a patch that has multiple hunks modifying a 28.1266 - file, and you only want to move a few of those hunks, the job 28.1267 - becomes more messy, but you can still partly automate it. Use 28.1268 - <command>lsdiff -nvv</command> to print some metadata about 28.1269 - the patch.</para> 28.1270 - 28.1271 - &interaction.mq.tools.lsdiff; 28.1272 - 28.1273 - <para id="x_442">This command prints three different kinds of 28.1274 - number:</para> 28.1275 - <itemizedlist> 28.1276 - <listitem><para id="x_443">(in the first column) a <emphasis>file 28.1277 - number</emphasis> to identify each file modified in the 28.1278 - patch;</para> 28.1279 - </listitem> 28.1280 - <listitem><para id="x_444">(on the next line, indented) the line number 28.1281 - within a modified file where a hunk starts; and</para> 28.1282 - </listitem> 28.1283 - <listitem><para id="x_445">(on the same line) a <emphasis>hunk 28.1284 - number</emphasis> to identify that hunk.</para> 28.1285 - </listitem></itemizedlist> 28.1286 - 28.1287 - <para id="x_446">You'll have to use some visual inspection, and reading of 28.1288 - the patch, to identify the file and hunk numbers you'll want, 28.1289 - but you can then pass them to to 28.1290 - <command>filterdiff</command>'s <option 28.1291 - role="cmd-opt-filterdiff">--files</option> and <option 28.1292 - role="cmd-opt-filterdiff">--hunks</option> options, to 28.1293 - select exactly the file and hunk you want to extract.</para> 28.1294 - 28.1295 - <para id="x_447">Once you have this hunk, you can concatenate it onto the 28.1296 - end of your destination patch and continue with the remainder 28.1297 - of <xref linkend="sec:mq:combine"/>.</para> 28.1298 - 28.1299 - </sect2> 28.1300 - </sect1> 28.1301 - <sect1> 28.1302 - <title>Differences between quilt and MQ</title> 28.1303 - 28.1304 - <para id="x_448">If you are already familiar with quilt, MQ provides a 28.1305 - similar command set. There are a few differences in the way 28.1306 - that it works.</para> 28.1307 - 28.1308 - <para id="x_449">You will already have noticed that most quilt commands have 28.1309 - MQ counterparts that simply begin with a 28.1310 - <quote><literal>q</literal></quote>. The exceptions are quilt's 28.1311 - <literal>add</literal> and <literal>remove</literal> commands, 28.1312 - the counterparts for which are the normal Mercurial <command 28.1313 - role="hg-cmd">hg add</command> and <command role="hg-cmd">hg 28.1314 - remove</command> commands. There is no MQ equivalent of the 28.1315 - quilt <literal>edit</literal> command.</para> 28.1316 - 28.1317 - </sect1> 28.1318 -</chapter> 28.1319 - 28.1320 -<!-- 28.1321 -local variables: 28.1322 -sgml-parent-document: ("00book.xml" "book" "chapter") 28.1323 -end: 28.1324 --->
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/en/ch11-template.xml Thu May 21 14:16:17 2009 +0800 29.3 @@ -0,0 +1,685 @@ 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>Customizing 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 customize 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 + </sect2> 29.63 + </sect1> 29.64 + 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 customizable 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 + </sect1> 29.81 + 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 + <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 29.128 + braces and text with the expansion of whatever is inside. To 29.129 + print a literal curly brace, you must escape it, as described in 29.130 + <xref linkend="sec:template:escape"/>.</para> 29.131 + </sect1> 29.132 + 29.133 + <sect1 id="sec:template:keyword"> 29.134 + <title>Common template keywords</title> 29.135 + 29.136 + <para id="x_589">You can start writing simple templates immediately using the 29.137 + keywords below.</para> 29.138 + 29.139 + <itemizedlist> 29.140 + <listitem><para id="x_58a"><literal 29.141 + role="template-keyword">author</literal>: String. The 29.142 + unmodified author of the changeset.</para> 29.143 + </listitem> 29.144 + <listitem><para id="x_58b"><literal 29.145 + role="template-keyword">branches</literal>: String. The 29.146 + name of the branch on which the changeset was committed. 29.147 + Will be empty if the branch name was 29.148 + <literal>default</literal>.</para> 29.149 + </listitem> 29.150 + <listitem><para id="x_58c"><literal role="template-keyword">date</literal>: 29.151 + Date information. The date when the changeset was 29.152 + committed. This is <emphasis>not</emphasis> human-readable; 29.153 + you must pass it through a filter that will render it 29.154 + appropriately. See <xref 29.155 + linkend="sec:template:filter"/> for more information 29.156 + on filters. The date is expressed as a pair of numbers. The 29.157 + first number is a Unix UTC timestamp (seconds since January 29.158 + 1, 1970); the second is the offset of the committer's 29.159 + timezone from UTC, in seconds.</para> 29.160 + </listitem> 29.161 + <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>: 29.162 + String. The text of the changeset description.</para> 29.163 + </listitem> 29.164 + <listitem><para id="x_58e"><literal 29.165 + role="template-keyword">files</literal>: List of strings. 29.166 + All files modified, added, or removed by this 29.167 + changeset.</para> 29.168 + </listitem> 29.169 + <listitem><para id="x_58f"><literal 29.170 + role="template-keyword">file_adds</literal>: List of 29.171 + strings. Files added by this changeset.</para> 29.172 + </listitem> 29.173 + <listitem><para id="x_590"><literal 29.174 + role="template-keyword">file_dels</literal>: List of 29.175 + strings. Files removed by this changeset.</para> 29.176 + </listitem> 29.177 + <listitem><para id="x_591"><literal role="template-keyword">node</literal>: 29.178 + String. The changeset identification hash, as a 29.179 + 40-character hexadecimal string.</para> 29.180 + </listitem> 29.181 + <listitem><para id="x_592"><literal 29.182 + role="template-keyword">parents</literal>: List of 29.183 + strings. The parents of the changeset.</para> 29.184 + </listitem> 29.185 + <listitem><para id="x_593"><literal role="template-keyword">rev</literal>: 29.186 + Integer. The repository-local changeset revision 29.187 + number.</para> 29.188 + </listitem> 29.189 + <listitem><para id="x_594"><literal role="template-keyword">tags</literal>: 29.190 + List of strings. Any tags associated with the 29.191 + changeset.</para> 29.192 + </listitem> 29.193 + </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 <xref linkend="sec:template:filter"/>.</para> 29.204 + 29.205 + &interaction.template.simple.datekeyword; 29.206 + </sect1> 29.207 + 29.208 + <sect1 id="sec:template:escape"> 29.209 + <title>Escape sequences</title> 29.210 + 29.211 + <para id="x_597">Mercurial's templating engine recognises the most commonly 29.212 + used escape sequences in strings. When it sees a backslash 29.213 + (<quote><literal>\</literal></quote>) character, it looks at the 29.214 + following character and substitutes the two characters with a 29.215 + single replacement, as described below.</para> 29.216 + 29.217 + <itemizedlist> 29.218 + <listitem><para id="x_598"><literal>\</literal>: 29.219 + Backslash, <quote><literal>\</literal></quote>, ASCII 29.220 + 134.</para> 29.221 + </listitem> 29.222 + <listitem><para id="x_599"><literal>\n</literal>: Newline, 29.223 + ASCII 12.</para> 29.224 + </listitem> 29.225 + <listitem><para id="x_59a"><literal>\r</literal>: Carriage 29.226 + return, ASCII 15.</para> 29.227 + </listitem> 29.228 + <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII 29.229 + 11.</para> 29.230 + </listitem> 29.231 + <listitem><para id="x_59c"><literal>\v</literal>: Vertical 29.232 + tab, ASCII 13.</para> 29.233 + </listitem> 29.234 + <listitem><para id="x_59d"><literal>\{</literal>: Open curly 29.235 + brace, <quote><literal>{</literal></quote>, ASCII 29.236 + 173.</para> 29.237 + </listitem> 29.238 + <listitem><para id="x_59e"><literal>\}</literal>: Close curly 29.239 + brace, <quote><literal>}</literal></quote>, ASCII 29.240 + 175.</para> 29.241 + </listitem></itemizedlist> 29.242 + 29.243 + <para id="x_59f">As indicated above, if you want the expansion of a template 29.244 + to contain a literal <quote><literal>\</literal></quote>, 29.245 + <quote><literal>{</literal></quote>, or 29.246 + <quote><literal>{</literal></quote> character, you must escape 29.247 + it.</para> 29.248 + </sect1> 29.249 + 29.250 + <sect1 id="sec:template:filter"> 29.251 + <title>Filtering keywords to change their results</title> 29.252 + 29.253 + <para id="x_5a0">Some of the results of template expansion are not 29.254 + immediately easy to use. Mercurial lets you specify an optional 29.255 + chain of <emphasis>filters</emphasis> to modify the result of 29.256 + expanding a keyword. You have already seen a common filter, 29.257 + <literal role="template-kw-filt-date">isodate</literal>, in 29.258 + action above, to make a date readable.</para> 29.259 + 29.260 + <para id="x_5a1">Below is a list of the most commonly used filters that 29.261 + Mercurial supports. While some filters can be applied to any 29.262 + text, others can only be used in specific circumstances. The 29.263 + name of each filter is followed first by an indication of where 29.264 + it can be used, then a description of its effect.</para> 29.265 + 29.266 + <itemizedlist> 29.267 + <listitem><para id="x_5a2"><literal 29.268 + role="template-filter">addbreaks</literal>: Any text. Add 29.269 + an XHTML <quote><literal><br/></literal></quote> tag 29.270 + before the end of every line except the last. For example, 29.271 + <quote><literal>foo\nbar</literal></quote> becomes 29.272 + <quote><literal>foo<br/>\nbar</literal></quote>.</para> 29.273 + </listitem> 29.274 + <listitem><para id="x_5a3"><literal 29.275 + role="template-kw-filt-date">age</literal>: <literal 29.276 + role="template-keyword">date</literal> keyword. Render 29.277 + the age of the date, relative to the current time. Yields a 29.278 + string like <quote><literal>10 29.279 + minutes</literal></quote>.</para> 29.280 + </listitem> 29.281 + <listitem><para id="x_5a4"><literal 29.282 + role="template-filter">basename</literal>: Any text, but 29.283 + most useful for the <literal 29.284 + role="template-keyword">files</literal> keyword and its 29.285 + relatives. Treat the text as a path, and return the 29.286 + basename. For example, 29.287 + <quote><literal>foo/bar/baz</literal></quote> becomes 29.288 + <quote><literal>baz</literal></quote>.</para> 29.289 + </listitem> 29.290 + <listitem><para id="x_5a5"><literal 29.291 + role="template-kw-filt-date">date</literal>: <literal 29.292 + role="template-keyword">date</literal> keyword. Render a 29.293 + date in a similar format to the Unix <literal 29.294 + role="template-keyword">date</literal> command, but with 29.295 + timezone included. Yields a string like <quote><literal>Mon 29.296 + Sep 04 15:13:13 2006 -0700</literal></quote>.</para> 29.297 + </listitem> 29.298 + <listitem><para id="x_5a6"><literal 29.299 + role="template-kw-filt-author">domain</literal>: Any text, 29.300 + but most useful for the <literal 29.301 + role="template-keyword">author</literal> keyword. Finds 29.302 + the first string that looks like an email address, and 29.303 + extract just the domain component. For example, 29.304 + <quote><literal>Bryan O'Sullivan 29.305 + <bos@serpentine.com></literal></quote> becomes 29.306 + <quote><literal>serpentine.com</literal></quote>.</para> 29.307 + </listitem> 29.308 + <listitem><para id="x_5a7"><literal 29.309 + role="template-kw-filt-author">email</literal>: Any text, 29.310 + but most useful for the <literal 29.311 + role="template-keyword">author</literal> keyword. Extract 29.312 + the first string that looks like an email address. For 29.313 + example, <quote><literal>Bryan O'Sullivan 29.314 + <bos@serpentine.com></literal></quote> becomes 29.315 + <quote><literal>bos@serpentine.com</literal></quote>.</para> 29.316 + </listitem> 29.317 + <listitem><para id="x_5a8"><literal 29.318 + role="template-filter">escape</literal>: Any text. 29.319 + Replace the special XML/XHTML characters 29.320 + <quote><literal>&</literal></quote>, 29.321 + <quote><literal><</literal></quote> and 29.322 + <quote><literal>></literal></quote> with XML 29.323 + entities.</para> 29.324 + </listitem> 29.325 + <listitem><para id="x_5a9"><literal 29.326 + role="template-filter">fill68</literal>: Any text. Wrap 29.327 + the text to fit in 68 columns. This is useful before you 29.328 + pass text through the <literal 29.329 + role="template-filter">tabindent</literal> filter, and 29.330 + still want it to fit in an 80-column fixed-font 29.331 + window.</para> 29.332 + </listitem> 29.333 + <listitem><para id="x_5aa"><literal 29.334 + role="template-filter">fill76</literal>: Any text. Wrap 29.335 + the text to fit in 76 columns.</para> 29.336 + </listitem> 29.337 + <listitem><para id="x_5ab"><literal 29.338 + role="template-filter">firstline</literal>: Any text. 29.339 + Yield the first line of text, without any trailing 29.340 + newlines.</para> 29.341 + </listitem> 29.342 + <listitem><para id="x_5ac"><literal 29.343 + role="template-kw-filt-date">hgdate</literal>: <literal 29.344 + role="template-keyword">date</literal> keyword. Render 29.345 + the date as a pair of readable numbers. Yields a string 29.346 + like <quote><literal>1157407993 29.347 + 25200</literal></quote>.</para> 29.348 + </listitem> 29.349 + <listitem><para id="x_5ad"><literal 29.350 + role="template-kw-filt-date">isodate</literal>: <literal 29.351 + role="template-keyword">date</literal> keyword. Render 29.352 + the date as a text string in ISO 8601 format. Yields a 29.353 + string like <quote><literal>2006-09-04 15:13:13 29.354 + -0700</literal></quote>.</para> 29.355 + </listitem> 29.356 + <listitem><para id="x_5ae"><literal 29.357 + role="template-filter">obfuscate</literal>: Any text, but 29.358 + most useful for the <literal 29.359 + role="template-keyword">author</literal> keyword. Yield 29.360 + the input text rendered as a sequence of XML entities. This 29.361 + helps to defeat some particularly stupid screen-scraping 29.362 + email harvesting spambots.</para> 29.363 + </listitem> 29.364 + <listitem><para id="x_5af"><literal 29.365 + role="template-kw-filt-author">person</literal>: Any text, 29.366 + but most useful for the <literal 29.367 + role="template-keyword">author</literal> keyword. Yield 29.368 + the text before an email address. For example, 29.369 + <quote><literal>Bryan O'Sullivan 29.370 + <bos@serpentine.com></literal></quote> becomes 29.371 + <quote><literal>Bryan O'Sullivan</literal></quote>.</para> 29.372 + </listitem> 29.373 + <listitem><para id="x_5b0"><literal 29.374 + role="template-kw-filt-date">rfc822date</literal>: 29.375 + <literal role="template-keyword">date</literal> keyword. 29.376 + Render a date using the same format used in email headers. 29.377 + Yields a string like <quote><literal>Mon, 04 Sep 2006 29.378 + 15:13:13 -0700</literal></quote>.</para> 29.379 + </listitem> 29.380 + <listitem><para id="x_5b1"><literal 29.381 + role="template-kw-filt-node">short</literal>: Changeset 29.382 + hash. Yield the short form of a changeset hash, i.e. a 29.383 + 12-character hexadecimal string.</para> 29.384 + </listitem> 29.385 + <listitem><para id="x_5b2"><literal 29.386 + role="template-kw-filt-date">shortdate</literal>: <literal 29.387 + role="template-keyword">date</literal> keyword. Render 29.388 + the year, month, and day of the date. Yields a string like 29.389 + <quote><literal>2006-09-04</literal></quote>.</para> 29.390 + </listitem> 29.391 + <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>: 29.392 + Any text. Strip all leading and trailing whitespace from 29.393 + the string.</para> 29.394 + </listitem> 29.395 + <listitem><para id="x_5b4"><literal 29.396 + role="template-filter">tabindent</literal>: Any text. 29.397 + Yield the text, with every line except the first starting 29.398 + with a tab character.</para> 29.399 + </listitem> 29.400 + <listitem><para id="x_5b5"><literal 29.401 + role="template-filter">urlescape</literal>: Any text. 29.402 + Escape all characters that are considered 29.403 + <quote>special</quote> by URL parsers. For example, 29.404 + <literal>foo bar</literal> becomes 29.405 + <literal>foo%20bar</literal>.</para> 29.406 + </listitem> 29.407 + <listitem><para id="x_5b6"><literal 29.408 + role="template-kw-filt-author">user</literal>: Any text, 29.409 + but most useful for the <literal 29.410 + role="template-keyword">author</literal> keyword. Return 29.411 + the <quote>user</quote> portion of an email address. For 29.412 + example, <quote><literal>Bryan O'Sullivan 29.413 + <bos@serpentine.com></literal></quote> becomes 29.414 + <quote><literal>bos</literal></quote>.</para> 29.415 + </listitem> 29.416 + </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 + </sect2> 29.454 + </sect1> 29.455 + 29.456 + <sect1> 29.457 + <title>From templates to styles</title> 29.458 + 29.459 + <para id="x_5bb">A command line template provides a quick and simple way to 29.460 + format some output. Templates can become verbose, though, and 29.461 + it's useful to be able to give a template a name. A style file 29.462 + is a template with a name, stored in a file.</para> 29.463 + 29.464 + <para id="x_5bc">More than that, using a style file unlocks the power of 29.465 + Mercurial's templating engine in ways that are not possible 29.466 + using the command line <option 29.467 + role="hg-opt-log">--template</option> option.</para> 29.468 + 29.469 + <sect2> 29.470 + <title>The simplest of style files</title> 29.471 + 29.472 + <para id="x_5bd">Our simple style file contains just one line:</para> 29.473 + 29.474 + &interaction.template.simple.rev; 29.475 + 29.476 + <para id="x_5be">This tells Mercurial, <quote>if you're printing a 29.477 + changeset, use the text on the right as the 29.478 + template</quote>.</para> 29.479 + </sect2> 29.480 + 29.481 + <sect2> 29.482 + <title>Style file syntax</title> 29.483 + 29.484 + <para id="x_5bf">The syntax rules for a style file are simple.</para> 29.485 + 29.486 + <itemizedlist> 29.487 + <listitem><para id="x_5c0">The file is processed one line at a 29.488 + time.</para> 29.489 + </listitem> 29.490 + <listitem><para id="x_5c1">Leading and trailing white space are 29.491 + ignored.</para> 29.492 + </listitem> 29.493 + <listitem><para id="x_5c2">Empty lines are skipped.</para> 29.494 + </listitem> 29.495 + <listitem><para id="x_5c3">If a line starts with either of the characters 29.496 + <quote><literal>#</literal></quote> or 29.497 + <quote><literal>;</literal></quote>, the entire line is 29.498 + treated as a comment, and skipped as if empty.</para> 29.499 + </listitem> 29.500 + <listitem><para id="x_5c4">A line starts with a keyword. This must start 29.501 + with an alphabetic character or underscore, and can 29.502 + subsequently contain any alphanumeric character or 29.503 + underscore. (In regexp notation, a keyword must match 29.504 + <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para> 29.505 + </listitem> 29.506 + <listitem><para id="x_5c5">The next element must be an 29.507 + <quote><literal>=</literal></quote> character, which can 29.508 + be preceded or followed by an arbitrary amount of white 29.509 + space.</para> 29.510 + </listitem> 29.511 + <listitem><para id="x_5c6">If the rest of the line starts and ends with 29.512 + matching quote characters (either single or double quote), 29.513 + it is treated as a template body.</para> 29.514 + </listitem> 29.515 + <listitem><para id="x_5c7">If the rest of the line <emphasis>does 29.516 + not</emphasis> start with a quote character, it is 29.517 + treated as the name of a file; the contents of this file 29.518 + will be read and used as a template body.</para> 29.519 + </listitem></itemizedlist> 29.520 + </sect2> 29.521 + </sect1> 29.522 + 29.523 + <sect1> 29.524 + <title>Style files by example</title> 29.525 + 29.526 + <para id="x_5c8">To illustrate how to write a style file, we will construct a 29.527 + few by example. Rather than provide a complete style file and 29.528 + walk through it, we'll mirror the usual process of developing a 29.529 + style file by starting with something very simple, and walking 29.530 + through a series of successively more complete examples.</para> 29.531 + 29.532 + <sect2> 29.533 + <title>Identifying mistakes in style files</title> 29.534 + 29.535 + <para id="x_5c9">If Mercurial encounters a problem in a style file you are 29.536 + working on, it prints a terse error message that, once you 29.537 + figure out what it means, is actually quite useful.</para> 29.538 + 29.539 +&interaction.template.svnstyle.syntax.input; 29.540 + 29.541 + <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to 29.542 + define a <literal>changeset</literal> keyword, but forgets to 29.543 + give any content for it. When instructed to use this style 29.544 + file, Mercurial promptly complains.</para> 29.545 + 29.546 + &interaction.template.svnstyle.syntax.error; 29.547 + 29.548 + <para id="x_5cb">This error message looks intimidating, but it is not too 29.549 + hard to follow.</para> 29.550 + 29.551 + <itemizedlist> 29.552 + <listitem><para id="x_5cc">The first component is simply Mercurial's way 29.553 + of saying <quote>I am giving up</quote>.</para> 29.554 + <programlisting>___abort___: broken.style:1: parse error</programlisting> 29.555 + </listitem> 29.556 + <listitem><para id="x_5cd">Next comes the name of the style file that 29.557 + contains the error.</para> 29.558 + <programlisting>abort: ___broken.style___:1: parse error</programlisting> 29.559 + </listitem> 29.560 + <listitem><para id="x_5ce">Following the file name is the line number 29.561 + where the error was encountered.</para> 29.562 + <programlisting>abort: broken.style:___1___: parse error</programlisting> 29.563 + </listitem> 29.564 + <listitem><para id="x_5cf">Finally, a description of what went 29.565 + wrong.</para> 29.566 + <programlisting>abort: broken.style:1: ___parse error___</programlisting> 29.567 + </listitem> 29.568 + <listitem><para id="x_5d0">The description of the problem is not always 29.569 + clear (as in this case), but even when it is cryptic, it 29.570 + is almost always trivial to visually inspect the offending 29.571 + line in the style file and see what is wrong.</para> 29.572 + </listitem> 29.573 + </itemizedlist> 29.574 + </sect2> 29.575 + 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 likely to be unique, and so it is 29.587 + useful in many cases. There are a few caveats.</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> 29.610 + </itemizedlist> 29.611 + </sect2> 29.612 + 29.613 + <sect2> 29.614 + <title>Listing files on multiple lines</title> 29.615 + 29.616 + <para id="x_714">Suppose we want to list the files changed by a changeset, 29.617 + one per line, with a little indentation before each file 29.618 + name.</para> 29.619 + 29.620 + &interaction.ch10-multiline.go; 29.621 + </sect2> 29.622 + 29.623 + <sect2> 29.624 + <title>Mimicking Subversion's output</title> 29.625 + 29.626 + <para id="x_5d8">Let's try to emulate the default output format used by 29.627 + another revision control tool, Subversion.</para> 29.628 + 29.629 + &interaction.template.svnstyle.short; 29.630 + 29.631 + <para id="x_5d9">Since Subversion's output style is fairly simple, it is 29.632 + easy to copy-and-paste a hunk of its output into a file, and 29.633 + replace the text produced above by Subversion with the 29.634 + template values we'd like to see expanded.</para> 29.635 + 29.636 + &interaction.template.svnstyle.template; 29.637 + 29.638 + <para id="x_5da">There are a few small ways in which this template deviates 29.639 + from the output produced by Subversion.</para> 29.640 + <itemizedlist> 29.641 + <listitem><para id="x_5db">Subversion prints a <quote>readable</quote> 29.642 + date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the 29.643 + example output above) in parentheses. Mercurial's 29.644 + templating engine does not provide a way to display a date 29.645 + in this format without also printing the time and time 29.646 + zone.</para> 29.647 + </listitem> 29.648 + <listitem><para id="x_5dc">We emulate Subversion's printing of 29.649 + <quote>separator</quote> lines full of 29.650 + <quote><literal>-</literal></quote> characters by ending 29.651 + the template with such a line. We use the templating 29.652 + engine's <literal role="template-keyword">header</literal> 29.653 + keyword to print a separator line as the first line of 29.654 + output (see below), thus achieving similar output to 29.655 + Subversion.</para> 29.656 + </listitem> 29.657 + <listitem><para id="x_5dd">Subversion's output includes a count in the 29.658 + header of the number of lines in the commit message. We 29.659 + cannot replicate this in Mercurial; the templating engine 29.660 + does not currently provide a filter that counts the number 29.661 + of lines the template generates.</para> 29.662 + </listitem></itemizedlist> 29.663 + <para id="x_5de">It took me no more than a minute or two of work to replace 29.664 + literal text from an example of Subversion's output with some 29.665 + keywords and filters to give the template above. The style 29.666 + file simply refers to the template.</para> 29.667 + 29.668 + &interaction.template.svnstyle.style; 29.669 + 29.670 + <para id="x_5df">We could have included the text of the template file 29.671 + directly in the style file by enclosing it in quotes and 29.672 + replacing the newlines with 29.673 + <quote><literal>\n</literal></quote> sequences, but it would 29.674 + have made the style file too difficult to read. Readability 29.675 + is a good guide when you're trying to decide whether some text 29.676 + belongs in a style file, or in a template file that the style 29.677 + file points to. If the style file will look too big or 29.678 + cluttered if you insert a literal piece of text, drop it into 29.679 + a template instead.</para> 29.680 + </sect2> 29.681 + </sect1> 29.682 +</chapter> 29.683 + 29.684 +<!-- 29.685 +local variables: 29.686 +sgml-parent-document: ("00book.xml" "book" "chapter") 29.687 +end: 29.688 +-->
30.1 --- a/en/ch12-mq-collab.xml Sat Apr 18 11:52:33 2009 +0800 30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 30.3 @@ -1,518 +0,0 @@ 30.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 30.5 - 30.6 -<chapter id="chap:mq-collab"> 30.7 - <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?> 30.8 - <title>Advanced uses of Mercurial Queues</title> 30.9 - 30.10 - <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial 30.11 - Queues, use of a little discipline and some of MQ's less 30.12 - frequently used capabilities makes it possible to work in 30.13 - complicated development environments.</para> 30.14 - 30.15 - <para id="x_15e">In this chapter, I will use as an example a technique I have 30.16 - used to manage the development of an Infiniband device driver for 30.17 - the Linux kernel. The driver in question is large (at least as 30.18 - drivers go), with 25,000 lines of code spread across 35 source 30.19 - files. It is maintained by a small team of developers.</para> 30.20 - 30.21 - <para id="x_15f">While much of the material in this chapter is specific to 30.22 - Linux, the same principles apply to any code base for which you're 30.23 - not the primary owner, and upon which you need to do a lot of 30.24 - development.</para> 30.25 - 30.26 - <sect1> 30.27 - <title>The problem of many targets</title> 30.28 - 30.29 - <para id="x_160">The Linux kernel changes rapidly, and has never been 30.30 - internally stable; developers frequently make drastic changes 30.31 - between releases. This means that a version of the driver that 30.32 - works well with a particular released version of the kernel will 30.33 - not even <emphasis>compile</emphasis> correctly against, 30.34 - typically, any other version.</para> 30.35 - 30.36 - <para id="x_161">To maintain a driver, we have to keep a number of distinct 30.37 - versions of Linux in mind.</para> 30.38 - <itemizedlist> 30.39 - <listitem><para id="x_162">One target is the main Linux kernel development 30.40 - tree. Maintenance of the code is in this case partly shared 30.41 - by other developers in the kernel community, who make 30.42 - <quote>drive-by</quote> modifications to the driver as they 30.43 - develop and refine kernel subsystems.</para> 30.44 - </listitem> 30.45 - <listitem><para id="x_163">We also maintain a number of 30.46 - <quote>backports</quote> to older versions of the Linux 30.47 - kernel, to support the needs of customers who are running 30.48 - older Linux distributions that do not incorporate our 30.49 - drivers. (To <emphasis>backport</emphasis> a piece of code 30.50 - is to modify it to work in an older version of its target 30.51 - environment than the version it was developed for.)</para> 30.52 - </listitem> 30.53 - <listitem><para id="x_164">Finally, we make software releases on a schedule 30.54 - that is necessarily not aligned with those used by Linux 30.55 - distributors and kernel developers, so that we can deliver 30.56 - new features to customers without forcing them to upgrade 30.57 - their entire kernels or distributions.</para> 30.58 - </listitem></itemizedlist> 30.59 - 30.60 - <sect2> 30.61 - <title>Tempting approaches that don't work well</title> 30.62 - 30.63 - <para id="x_165">There are two <quote>standard</quote> ways to maintain a 30.64 - piece of software that has to target many different 30.65 - environments.</para> 30.66 - 30.67 - <para id="x_166">The first is to maintain a number of branches, each 30.68 - intended for a single target. The trouble with this approach 30.69 - is that you must maintain iron discipline in the flow of 30.70 - changes between repositories. A new feature or bug fix must 30.71 - start life in a <quote>pristine</quote> repository, then 30.72 - percolate out to every backport repository. Backport changes 30.73 - are more limited in the branches they should propagate to; a 30.74 - backport change that is applied to a branch where it doesn't 30.75 - belong will probably stop the driver from compiling.</para> 30.76 - 30.77 - <para id="x_167">The second is to maintain a single source tree filled with 30.78 - conditional statements that turn chunks of code on or off 30.79 - depending on the intended target. Because these 30.80 - <quote>ifdefs</quote> are not allowed in the Linux kernel 30.81 - tree, a manual or automatic process must be followed to strip 30.82 - them out and yield a clean tree. A code base maintained in 30.83 - this fashion rapidly becomes a rat's nest of conditional 30.84 - blocks that are difficult to understand and maintain.</para> 30.85 - 30.86 - <para id="x_168">Neither of these approaches is well suited to a situation 30.87 - where you don't <quote>own</quote> the canonical copy of a 30.88 - source tree. In the case of a Linux driver that is 30.89 - distributed with the standard kernel, Linus's tree contains 30.90 - the copy of the code that will be treated by the world as 30.91 - canonical. The upstream version of <quote>my</quote> driver 30.92 - can be modified by people I don't know, without me even 30.93 - finding out about it until after the changes show up in 30.94 - Linus's tree.</para> 30.95 - 30.96 - <para id="x_169">These approaches have the added weakness of making it 30.97 - difficult to generate well-formed patches to submit 30.98 - upstream.</para> 30.99 - 30.100 - <para id="x_16a">In principle, Mercurial Queues seems like a good candidate 30.101 - to manage a development scenario such as the above. While 30.102 - this is indeed the case, MQ contains a few added features that 30.103 - make the job more pleasant.</para> 30.104 - 30.105 - </sect2> 30.106 - </sect1> 30.107 - <sect1> 30.108 - <title>Conditionally applying patches with guards</title> 30.109 - 30.110 - <para id="x_16b">Perhaps the best way to maintain sanity with so many targets 30.111 - is to be able to choose specific patches to apply for a given 30.112 - situation. MQ provides a feature called <quote>guards</quote> 30.113 - (which originates with quilt's <literal>guards</literal> 30.114 - command) that does just this. To start off, let's create a 30.115 - simple repository for experimenting in.</para> 30.116 - 30.117 - &interaction.mq.guards.init; 30.118 - 30.119 - <para id="x_16c">This gives us a tiny repository that contains two patches 30.120 - that don't have any dependencies on each other, because they 30.121 - touch different files.</para> 30.122 - 30.123 - <para id="x_16d">The idea behind conditional application is that you can 30.124 - <quote>tag</quote> a patch with a <emphasis>guard</emphasis>, 30.125 - which is simply a text string of your choosing, then tell MQ to 30.126 - select specific guards to use when applying patches. MQ will 30.127 - then either apply, or skip over, a guarded patch, depending on 30.128 - the guards that you have selected.</para> 30.129 - 30.130 - <para id="x_16e">A patch can have an arbitrary number of guards; each one is 30.131 - <emphasis>positive</emphasis> (<quote>apply this patch if this 30.132 - guard is selected</quote>) or <emphasis>negative</emphasis> 30.133 - (<quote>skip this patch if this guard is selected</quote>). A 30.134 - patch with no guards is always applied.</para> 30.135 - 30.136 - </sect1> 30.137 - <sect1> 30.138 - <title>Controlling the guards on a patch</title> 30.139 - 30.140 - <para id="x_16f">The <command role="hg-ext-mq">qguard</command> command lets 30.141 - you determine which guards should apply to a patch, or display 30.142 - the guards that are already in effect. Without any arguments, it 30.143 - displays the guards on the current topmost patch.</para> 30.144 - 30.145 - &interaction.mq.guards.qguard; 30.146 - 30.147 - <para id="x_170">To set a positive guard on a patch, prefix the name of the 30.148 - guard with a <quote><literal>+</literal></quote>.</para> 30.149 - 30.150 - &interaction.mq.guards.qguard.pos; 30.151 - 30.152 - <para id="x_171">To set a negative guard 30.153 - on a patch, prefix the name of the guard with a 30.154 - <quote><literal>-</literal></quote>.</para> 30.155 - 30.156 - &interaction.mq.guards.qguard.neg; 30.157 - 30.158 - <note> 30.159 - <para id="x_172"> The <command role="hg-ext-mq">qguard</command> command 30.160 - <emphasis>sets</emphasis> the guards on a patch; it doesn't 30.161 - <emphasis>modify</emphasis> them. What this means is that if 30.162 - you run <command role="hg-cmd">hg qguard +a +b</command> on a 30.163 - patch, then <command role="hg-cmd">hg qguard +c</command> on 30.164 - the same patch, the <emphasis>only</emphasis> guard that will 30.165 - be set on it afterwards is <literal>+c</literal>.</para> 30.166 - </note> 30.167 - 30.168 - <para id="x_173">Mercurial stores guards in the <filename 30.169 - role="special">series</filename> file; the form in which they 30.170 - are stored is easy both to understand and to edit by hand. (In 30.171 - other words, you don't have to use the <command 30.172 - role="hg-ext-mq">qguard</command> command if you don't want 30.173 - to; it's okay to simply edit the <filename 30.174 - role="special">series</filename> file.)</para> 30.175 - 30.176 - &interaction.mq.guards.series; 30.177 - 30.178 - </sect1> 30.179 - <sect1> 30.180 - <title>Selecting the guards to use</title> 30.181 - 30.182 - <para id="x_174">The <command role="hg-ext-mq">qselect</command> command 30.183 - determines which guards are active at a given time. The effect 30.184 - of this is to determine which patches MQ will apply the next 30.185 - time you run <command role="hg-ext-mq">qpush</command>. It has 30.186 - no other effect; in particular, it doesn't do anything to 30.187 - patches that are already applied.</para> 30.188 - 30.189 - <para id="x_175">With no arguments, the <command 30.190 - role="hg-ext-mq">qselect</command> command lists the guards 30.191 - currently in effect, one per line of output. Each argument is 30.192 - treated as the name of a guard to apply.</para> 30.193 - 30.194 - &interaction.mq.guards.qselect.foo; 30.195 - 30.196 - <para id="x_176">In case you're interested, the currently selected guards are 30.197 - stored in the <filename role="special">guards</filename> file.</para> 30.198 - 30.199 - &interaction.mq.guards.qselect.cat; 30.200 - 30.201 - <para id="x_177">We can see the effect the selected guards have when we run 30.202 - <command role="hg-ext-mq">qpush</command>.</para> 30.203 - 30.204 - &interaction.mq.guards.qselect.qpush; 30.205 - 30.206 - <para id="x_178">A guard cannot start with a 30.207 - <quote><literal>+</literal></quote> or 30.208 - <quote><literal>-</literal></quote> character. The name of a 30.209 - guard must not contain white space, but most other characters 30.210 - are acceptable. If you try to use a guard with an invalid name, 30.211 - MQ will complain:</para> 30.212 - 30.213 - &interaction.mq.guards.qselect.error; 30.214 - 30.215 - <para id="x_179">Changing the selected guards changes the patches that are 30.216 - applied.</para> 30.217 - 30.218 - &interaction.mq.guards.qselect.quux; 30.219 - 30.220 - <para id="x_17a">You can see in the example below that negative guards take 30.221 - precedence over positive guards.</para> 30.222 - 30.223 - &interaction.mq.guards.qselect.foobar; 30.224 - 30.225 - </sect1> 30.226 - <sect1> 30.227 - <title>MQ's rules for applying patches</title> 30.228 - 30.229 - <para id="x_17b">The rules that MQ uses when deciding whether to apply a 30.230 - patch are as follows.</para> 30.231 - <itemizedlist> 30.232 - <listitem><para id="x_17c">A patch that has no guards is always 30.233 - applied.</para> 30.234 - </listitem> 30.235 - <listitem><para id="x_17d">If the patch has any negative guard that matches 30.236 - any currently selected guard, the patch is skipped.</para> 30.237 - </listitem> 30.238 - <listitem><para id="x_17e">If the patch has any positive guard that matches 30.239 - any currently selected guard, the patch is applied.</para> 30.240 - </listitem> 30.241 - <listitem><para id="x_17f">If the patch has positive or negative guards, 30.242 - but none matches any currently selected guard, the patch is 30.243 - skipped.</para> 30.244 - </listitem></itemizedlist> 30.245 - 30.246 - </sect1> 30.247 - <sect1> 30.248 - <title>Trimming the work environment</title> 30.249 - 30.250 - <para id="x_180">In working on the device driver I mentioned earlier, I don't 30.251 - apply the patches to a normal Linux kernel tree. Instead, I use 30.252 - a repository that contains only a snapshot of the source files 30.253 - and headers that are relevant to Infiniband development. This 30.254 - repository is 1% the size of a kernel repository, so it's easier 30.255 - to work with.</para> 30.256 - 30.257 - <para id="x_181">I then choose a <quote>base</quote> version on top of which 30.258 - the patches are applied. This is a snapshot of the Linux kernel 30.259 - tree as of a revision of my choosing. When I take the snapshot, 30.260 - I record the changeset ID from the kernel repository in the 30.261 - commit message. Since the snapshot preserves the 30.262 - <quote>shape</quote> and content of the relevant parts of the 30.263 - kernel tree, I can apply my patches on top of either my tiny 30.264 - repository or a normal kernel tree.</para> 30.265 - 30.266 - <para id="x_182">Normally, the base tree atop which the patches apply should 30.267 - be a snapshot of a very recent upstream tree. This best 30.268 - facilitates the development of patches that can easily be 30.269 - submitted upstream with few or no modifications.</para> 30.270 - 30.271 - </sect1> 30.272 - <sect1> 30.273 - <title>Dividing up the <filename role="special">series</filename> 30.274 - file</title> 30.275 - 30.276 - <para id="x_183">I categorise the patches in the <filename 30.277 - role="special">series</filename> file into a number of logical 30.278 - groups. Each section of like patches begins with a block of 30.279 - comments that describes the purpose of the patches that 30.280 - follow.</para> 30.281 - 30.282 - <para id="x_184">The sequence of patch groups that I maintain follows. The 30.283 - ordering of these groups is important; I'll describe why after I 30.284 - introduce the groups.</para> 30.285 - <itemizedlist> 30.286 - <listitem><para id="x_185">The <quote>accepted</quote> group. Patches that 30.287 - the development team has submitted to the maintainer of the 30.288 - Infiniband subsystem, and which he has accepted, but which 30.289 - are not present in the snapshot that the tiny repository is 30.290 - based on. These are <quote>read only</quote> patches, 30.291 - present only to transform the tree into a similar state as 30.292 - it is in the upstream maintainer's repository.</para> 30.293 - </listitem> 30.294 - <listitem><para id="x_186">The <quote>rework</quote> group. Patches that I 30.295 - have submitted, but that the upstream maintainer has 30.296 - requested modifications to before he will accept 30.297 - them.</para> 30.298 - </listitem> 30.299 - <listitem><para id="x_187">The <quote>pending</quote> group. Patches that 30.300 - I have not yet submitted to the upstream maintainer, but 30.301 - which we have finished working on. These will be <quote>read 30.302 - only</quote> for a while. If the upstream maintainer 30.303 - accepts them upon submission, I'll move them to the end of 30.304 - the <quote>accepted</quote> group. If he requests that I 30.305 - modify any, I'll move them to the beginning of the 30.306 - <quote>rework</quote> group.</para> 30.307 - </listitem> 30.308 - <listitem><para id="x_188">The <quote>in progress</quote> group. Patches 30.309 - that are actively being developed, and should not be 30.310 - submitted anywhere yet.</para> 30.311 - </listitem> 30.312 - <listitem><para id="x_189">The <quote>backport</quote> group. Patches that 30.313 - adapt the source tree to older versions of the kernel 30.314 - tree.</para> 30.315 - </listitem> 30.316 - <listitem><para id="x_18a">The <quote>do not ship</quote> group. Patches 30.317 - that for some reason should never be submitted upstream. 30.318 - For example, one such patch might change embedded driver 30.319 - identification strings to make it easier to distinguish, in 30.320 - the field, between an out-of-tree version of the driver and 30.321 - a version shipped by a distribution vendor.</para> 30.322 - </listitem></itemizedlist> 30.323 - 30.324 - <para id="x_18b">Now to return to the reasons for ordering groups of patches 30.325 - in this way. We would like the lowest patches in the stack to 30.326 - be as stable as possible, so that we will not need to rework 30.327 - higher patches due to changes in context. Putting patches that 30.328 - will never be changed first in the <filename 30.329 - role="special">series</filename> file serves this 30.330 - purpose.</para> 30.331 - 30.332 - <para id="x_18c">We would also like the patches that we know we'll need to 30.333 - modify to be applied on top of a source tree that resembles the 30.334 - upstream tree as closely as possible. This is why we keep 30.335 - accepted patches around for a while.</para> 30.336 - 30.337 - <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote> 30.338 - patches float at the end of the <filename 30.339 - role="special">series</filename> file. The backport patches 30.340 - must be applied on top of all other patches, and the <quote>do 30.341 - not ship</quote> patches might as well stay out of harm's 30.342 - way.</para> 30.343 - 30.344 - </sect1> 30.345 - <sect1> 30.346 - <title>Maintaining the patch series</title> 30.347 - 30.348 - <para id="x_18e">In my work, I use a number of guards to control which 30.349 - patches are to be applied.</para> 30.350 - 30.351 - <itemizedlist> 30.352 - <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with 30.353 - <literal>accepted</literal>. I enable this guard most of 30.354 - the time. When I'm applying the patches on top of a tree 30.355 - where the patches are already present, I can turn this patch 30.356 - off, and the patches that follow it will apply 30.357 - cleanly.</para> 30.358 - </listitem> 30.359 - <listitem><para id="x_190">Patches that are <quote>finished</quote>, but 30.360 - not yet submitted, have no guards. If I'm applying the 30.361 - patch stack to a copy of the upstream tree, I don't need to 30.362 - enable any guards in order to get a reasonably safe source 30.363 - tree.</para> 30.364 - </listitem> 30.365 - <listitem><para id="x_191">Those patches that need reworking before being 30.366 - resubmitted are guarded with 30.367 - <literal>rework</literal>.</para> 30.368 - </listitem> 30.369 - <listitem><para id="x_192">For those patches that are still under 30.370 - development, I use <literal>devel</literal>.</para> 30.371 - </listitem> 30.372 - <listitem><para id="x_193">A backport patch may have several guards, one 30.373 - for each version of the kernel to which it applies. For 30.374 - example, a patch that backports a piece of code to 2.6.9 30.375 - will have a <literal>2.6.9</literal> guard.</para> 30.376 - </listitem></itemizedlist> 30.377 - <para id="x_194">This variety of guards gives me considerable flexibility in 30.378 - determining what kind of source tree I want to end up with. For 30.379 - most situations, the selection of appropriate guards is 30.380 - automated during the build process, but I can manually tune the 30.381 - guards to use for less common circumstances.</para> 30.382 - 30.383 - <sect2> 30.384 - <title>The art of writing backport patches</title> 30.385 - 30.386 - <para id="x_195">Using MQ, writing a backport patch is a simple process. 30.387 - All such a patch has to do is modify a piece of code that uses 30.388 - a kernel feature not present in the older version of the 30.389 - kernel, so that the driver continues to work correctly under 30.390 - that older version.</para> 30.391 - 30.392 - <para id="x_196">A useful goal when writing a good backport patch is to 30.393 - make your code look as if it was written for the older version 30.394 - of the kernel you're targeting. The less obtrusive the patch, 30.395 - the easier it will be to understand and maintain. If you're 30.396 - writing a collection of backport patches to avoid the 30.397 - <quote>rat's nest</quote> effect of lots of 30.398 - <literal>#ifdef</literal>s (hunks of source code that are only 30.399 - used conditionally) in your code, don't introduce 30.400 - version-dependent <literal>#ifdef</literal>s into the patches. 30.401 - Instead, write several patches, each of which makes 30.402 - unconditional changes, and control their application using 30.403 - guards.</para> 30.404 - 30.405 - <para id="x_197">There are two reasons to divide backport patches into a 30.406 - distinct group, away from the <quote>regular</quote> patches 30.407 - whose effects they modify. The first is that intermingling the 30.408 - two makes it more difficult to use a tool like the <literal 30.409 - role="hg-ext">patchbomb</literal> extension to automate the 30.410 - process of submitting the patches to an upstream maintainer. 30.411 - The second is that a backport patch could perturb the context 30.412 - in which a subsequent regular patch is applied, making it 30.413 - impossible to apply the regular patch cleanly 30.414 - <emphasis>without</emphasis> the earlier backport patch 30.415 - already being applied.</para> 30.416 - 30.417 - </sect2> 30.418 - </sect1> 30.419 - <sect1> 30.420 - <title>Useful tips for developing with MQ</title> 30.421 - 30.422 - <sect2> 30.423 - <title>Organising patches in directories</title> 30.424 - 30.425 - <para id="x_198">If you're working on a substantial project with MQ, it's 30.426 - not difficult to accumulate a large number of patches. For 30.427 - example, I have one patch repository that contains over 250 30.428 - patches.</para> 30.429 - 30.430 - <para id="x_199">If you can group these patches into separate logical 30.431 - categories, you can if you like store them in different 30.432 - directories; MQ has no problems with patch names that contain 30.433 - path separators.</para> 30.434 - 30.435 - </sect2> 30.436 - <sect2 id="mq-collab:tips:interdiff"> 30.437 - <title>Viewing the history of a patch</title> 30.438 - 30.439 - <para id="x_19a">If you're developing a set of patches over a long time, 30.440 - it's a good idea to maintain them in a repository, as 30.441 - discussed in <xref linkend="sec:mq:repo"/>. If you do 30.442 - so, you'll quickly 30.443 - discover that using the <command role="hg-cmd">hg 30.444 - diff</command> command to look at the history of changes to 30.445 - a patch is unworkable. This is in part because you're looking 30.446 - at the second derivative of the real code (a diff of a diff), 30.447 - but also because MQ adds noise to the process by modifying 30.448 - time stamps and directory names when it updates a 30.449 - patch.</para> 30.450 - 30.451 - <para id="x_19b">However, you can use the <literal 30.452 - role="hg-ext">extdiff</literal> extension, which is bundled 30.453 - with Mercurial, to turn a diff of two versions of a patch into 30.454 - something readable. To do this, you will need a third-party 30.455 - package called <literal role="package">patchutils</literal> 30.456 - <citation>web:patchutils</citation>. This provides a command 30.457 - named <command>interdiff</command>, which shows the 30.458 - differences between two diffs as a diff. Used on two versions 30.459 - of the same diff, it generates a diff that represents the diff 30.460 - from the first to the second version.</para> 30.461 - 30.462 - <para id="x_19c">You can enable the <literal 30.463 - role="hg-ext">extdiff</literal> extension in the usual way, 30.464 - by adding a line to the <literal 30.465 - role="rc-extensions">extensions</literal> section of your 30.466 - <filename role="special">~/.hgrc</filename>.</para> 30.467 - <programlisting>[extensions] 30.468 -extdiff =</programlisting> 30.469 - <para id="x_19d">The <command>interdiff</command> command expects to be 30.470 - passed the names of two files, but the <literal 30.471 - role="hg-ext">extdiff</literal> extension passes the program 30.472 - it runs a pair of directories, each of which can contain an 30.473 - arbitrary number of files. We thus need a small program that 30.474 - will run <command>interdiff</command> on each pair of files in 30.475 - these two directories. This program is available as <filename 30.476 - role="special">hg-interdiff</filename> in the <filename 30.477 - class="directory">examples</filename> directory of the 30.478 - source code repository that accompanies this book. <!-- 30.479 - &example.hg-interdiff; --></para> 30.480 - 30.481 - <para id="x_19e">With the <filename role="special">hg-interdiff</filename> 30.482 - program in your shell's search path, you can run it as 30.483 - follows, from inside an MQ patch directory:</para> 30.484 - <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting> 30.485 - <para id="x_19f">Since you'll probably want to use this long-winded command 30.486 - a lot, you can get <literal role="hg-ext">hgext</literal> to 30.487 - make it available as a normal Mercurial command, again by 30.488 - editing your <filename 30.489 - role="special">~/.hgrc</filename>.</para> 30.490 - <programlisting>[extdiff] 30.491 -cmd.interdiff = hg-interdiff</programlisting> 30.492 - <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to 30.493 - make an <literal>interdiff</literal> command available, so you 30.494 - can now shorten the previous invocation of <command 30.495 - role="hg-ext-extdiff">extdiff</command> to something a 30.496 - little more wieldy.</para> 30.497 - <programlisting>hg interdiff -r A:B my-change.patch</programlisting> 30.498 - 30.499 - <note> 30.500 - <para id="x_1a1"> The <command>interdiff</command> command works well 30.501 - only if the underlying files against which versions of a 30.502 - patch are generated remain the same. If you create a patch, 30.503 - modify the underlying files, and then regenerate the patch, 30.504 - <command>interdiff</command> may not produce useful 30.505 - output.</para> 30.506 - </note> 30.507 - 30.508 - <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is 30.509 - useful for more than merely improving the presentation of MQ 30.510 - patches. To read more about it, go to <xref 30.511 - linkend="sec:hgext:extdiff"/>.</para> 30.512 - 30.513 - </sect2> 30.514 - </sect1> 30.515 -</chapter> 30.516 - 30.517 -<!-- 30.518 -local variables: 30.519 -sgml-parent-document: ("00book.xml" "book" "chapter") 30.520 -end: 30.521 --->
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/en/ch12-mq.xml Thu May 21 14:16:17 2009 +0800 31.3 @@ -0,0 +1,1368 @@ 31.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 31.5 + 31.6 +<chapter id="chap:mq"> 31.7 + <?dbhtml filename="managing-change-with-mercurial-queues.html"?> 31.8 + <title>Managing change with Mercurial Queues</title> 31.9 + 31.10 + <sect1 id="sec:mq:patch-mgmt"> 31.11 + <title>The patch management problem</title> 31.12 + 31.13 + <para id="x_3ac">Here is a common scenario: you need to install a software 31.14 + package from source, but you find a bug that you must fix in the 31.15 + source before you can start using the package. You make your 31.16 + changes, forget about the package for a while, and a few months 31.17 + later you need to upgrade to a newer version of the package. If 31.18 + the newer version of the package still has the bug, you must 31.19 + extract your fix from the older source tree and apply it against 31.20 + the newer version. This is a tedious task, and it's easy to 31.21 + make mistakes.</para> 31.22 + 31.23 + <para id="x_3ad">This is a simple case of the <quote>patch management</quote> 31.24 + problem. You have an <quote>upstream</quote> source tree that 31.25 + you can't change; you need to make some local changes on top of 31.26 + the upstream tree; and you'd like to be able to keep those 31.27 + changes separate, so that you can apply them to newer versions 31.28 + of the upstream source.</para> 31.29 + 31.30 + <para id="x_3ae">The patch management problem arises in many situations. 31.31 + Probably the most visible is that a user of an open source 31.32 + software project will contribute a bug fix or new feature to the 31.33 + project's maintainers in the form of a patch.</para> 31.34 + 31.35 + <para id="x_3af">Distributors of operating systems that include open source 31.36 + software often need to make changes to the packages they 31.37 + distribute so that they will build properly in their 31.38 + environments.</para> 31.39 + 31.40 + <para id="x_3b0">When you have few changes to maintain, it is easy to manage 31.41 + a single patch using the standard <command>diff</command> and 31.42 + <command>patch</command> programs (see <xref 31.43 + linkend="sec:mq:patch"/> for a discussion of these 31.44 + tools). Once the number of changes grows, it starts to make 31.45 + sense to maintain patches as discrete <quote>chunks of 31.46 + work,</quote> so that for example a single patch will contain 31.47 + only one bug fix (the patch might modify several files, but it's 31.48 + doing <quote>only one thing</quote>), and you may have a number 31.49 + of such patches for different bugs you need fixed and local 31.50 + changes you require. In this situation, if you submit a bug fix 31.51 + patch to the upstream maintainers of a package and they include 31.52 + your fix in a subsequent release, you can simply drop that 31.53 + single patch when you're updating to the newer release.</para> 31.54 + 31.55 + <para id="x_3b1">Maintaining a single patch against an upstream tree is a 31.56 + little tedious and error-prone, but not difficult. However, the 31.57 + complexity of the problem grows rapidly as the number of patches 31.58 + you have to maintain increases. With more than a tiny number of 31.59 + patches in hand, understanding which ones you have applied and 31.60 + maintaining them moves from messy to overwhelming.</para> 31.61 + 31.62 + <para id="x_3b2">Fortunately, Mercurial includes a powerful extension, 31.63 + Mercurial Queues (or simply <quote>MQ</quote>), that massively 31.64 + simplifies the patch management problem.</para> 31.65 + 31.66 + </sect1> 31.67 + <sect1 id="sec:mq:history"> 31.68 + <title>The prehistory of Mercurial Queues</title> 31.69 + 31.70 + <para id="x_3b3">During the late 1990s, several Linux kernel developers 31.71 + started to maintain <quote>patch series</quote> that modified 31.72 + the behavior of the Linux kernel. Some of these series were 31.73 + focused on stability, some on feature coverage, and others were 31.74 + more speculative.</para> 31.75 + 31.76 + <para id="x_3b4">The sizes of these patch series grew rapidly. In 2002, 31.77 + Andrew Morton published some shell scripts he had been using to 31.78 + automate the task of managing his patch queues. Andrew was 31.79 + successfully using these scripts to manage hundreds (sometimes 31.80 + thousands) of patches on top of the Linux kernel.</para> 31.81 + 31.82 + <sect2 id="sec:mq:quilt"> 31.83 + <title>A patchwork quilt</title> 31.84 + 31.85 + <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson 31.86 + borrowed the approach of Andrew's scripts and published a tool 31.87 + called <quote>patchwork quilt</quote> 31.88 + <citation>web:quilt</citation>, or simply <quote>quilt</quote> 31.89 + (see <citation>gruenbacher:2005</citation> for a paper 31.90 + describing it). Because quilt substantially automated patch 31.91 + management, it rapidly gained a large following among open 31.92 + source software developers.</para> 31.93 + 31.94 + <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on 31.95 + top of a directory tree. To begin, you tell quilt to manage a 31.96 + directory tree, and tell it which files you want to manage; it 31.97 + stores away the names and contents of those files. To fix a 31.98 + bug, you create a new patch (using a single command), edit the 31.99 + files you need to fix, then <quote>refresh</quote> the 31.100 + patch.</para> 31.101 + 31.102 + <para id="x_3b7">The refresh step causes quilt to scan the directory tree; 31.103 + it updates the patch with all of the changes you have made. 31.104 + You can create another patch on top of the first, which will 31.105 + track the changes required to modify the tree from <quote>tree 31.106 + with one patch applied</quote> to <quote>tree with two 31.107 + patches applied</quote>.</para> 31.108 + 31.109 + <para id="x_3b8">You can <emphasis>change</emphasis> which patches are 31.110 + applied to the tree. If you <quote>pop</quote> a patch, the 31.111 + changes made by that patch will vanish from the directory 31.112 + tree. Quilt remembers which patches you have popped, though, 31.113 + so you can <quote>push</quote> a popped patch again, and the 31.114 + directory tree will be restored to contain the modifications 31.115 + in the patch. Most importantly, you can run the 31.116 + <quote>refresh</quote> command at any time, and the topmost 31.117 + applied patch will be updated. This means that you can, at 31.118 + any time, change both which patches are applied and what 31.119 + modifications those patches make.</para> 31.120 + 31.121 + <para id="x_3b9">Quilt knows nothing about revision control tools, so it 31.122 + works equally well on top of an unpacked tarball or a 31.123 + Subversion working copy.</para> 31.124 + </sect2> 31.125 + 31.126 + <sect2 id="sec:mq:quilt-mq"> 31.127 + <title>From patchwork quilt to Mercurial Queues</title> 31.128 + 31.129 + <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and 31.130 + wrote an extension that he called Mercurial Queues, which 31.131 + added quilt-like behavior to Mercurial.</para> 31.132 + 31.133 + <para id="x_3bb">The key difference between quilt and MQ is that quilt 31.134 + knows nothing about revision control systems, while MQ is 31.135 + <emphasis>integrated</emphasis> into Mercurial. Each patch 31.136 + that you push is represented as a Mercurial changeset. Pop a 31.137 + patch, and the changeset goes away.</para> 31.138 + 31.139 + <para id="x_3bc">Because quilt does not care about revision control tools, 31.140 + it is still a tremendously useful piece of software to know 31.141 + about for situations where you cannot use Mercurial and 31.142 + MQ.</para> 31.143 + 31.144 + </sect2> 31.145 + </sect1> 31.146 + <sect1> 31.147 + <title>The huge advantage of MQ</title> 31.148 + 31.149 + <para id="x_3bd">I cannot overstate the value that MQ offers through the 31.150 + unification of patches and revision control.</para> 31.151 + 31.152 + <para id="x_3be">A major reason that patches have persisted in the free 31.153 + software and open source world&emdash;in spite of the 31.154 + availability of increasingly capable revision control tools over 31.155 + the years&emdash;is the <emphasis>agility</emphasis> they 31.156 + offer.</para> 31.157 + 31.158 + <para id="x_3bf">Traditional revision control tools make a permanent, 31.159 + irreversible record of everything that you do. While this has 31.160 + great value, it's also somewhat stifling. If you want to 31.161 + perform a wild-eyed experiment, you have to be careful in how 31.162 + you go about it, or you risk leaving unneeded&emdash;or worse, 31.163 + misleading or destabilising&emdash;traces of your missteps and 31.164 + errors in the permanent revision record.</para> 31.165 + 31.166 + <para id="x_3c0">By contrast, MQ's marriage of distributed revision control 31.167 + with patches makes it much easier to isolate your work. Your 31.168 + patches live on top of normal revision history, and you can make 31.169 + them disappear or reappear at will. If you don't like a patch, 31.170 + you can drop it. If a patch isn't quite as you want it to be, 31.171 + simply fix it&emdash;as many times as you need to, until you 31.172 + have refined it into the form you desire.</para> 31.173 + 31.174 + <para id="x_3c1">As an example, the integration of patches with revision 31.175 + control makes understanding patches and debugging their 31.176 + effects&emdash;and their interplay with the code they're based 31.177 + on&emdash;<emphasis>enormously</emphasis> easier. Since every 31.178 + applied patch has an associated changeset, you can give <command 31.179 + role="hg-cmd">hg log</command> a file name to see which 31.180 + changesets and patches affected the file. You can use the 31.181 + <command role="hg-cmd">hg bisect</command> command to 31.182 + binary-search through all changesets and applied patches to see 31.183 + where a bug got introduced or fixed. You can use the <command 31.184 + role="hg-cmd">hg annotate</command> command to see which 31.185 + changeset or patch modified a particular line of a source file. 31.186 + And so on.</para> 31.187 + </sect1> 31.188 + 31.189 + <sect1 id="sec:mq:patch"> 31.190 + <title>Understanding patches</title> 31.191 + 31.192 + <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is 31.193 + helpful to understand what patches are, and a little about the 31.194 + tools that work with them.</para> 31.195 + 31.196 + <para id="x_3c3">The traditional Unix <command>diff</command> command 31.197 + compares two files, and prints a list of differences between 31.198 + them. The <command>patch</command> command understands these 31.199 + differences as <emphasis>modifications</emphasis> to make to a 31.200 + file. Take a look below for a simple example of these commands 31.201 + in action.</para> 31.202 + 31.203 + &interaction.mq.dodiff.diff; 31.204 + 31.205 + <para id="x_3c4">The type of file that <command>diff</command> generates (and 31.206 + <command>patch</command> takes as input) is called a 31.207 + <quote>patch</quote> or a <quote>diff</quote>; there is no 31.208 + difference between a patch and a diff. (We'll use the term 31.209 + <quote>patch</quote>, since it's more commonly used.)</para> 31.210 + 31.211 + <para id="x_3c5">A patch file can start with arbitrary text; the 31.212 + <command>patch</command> command ignores this text, but MQ uses 31.213 + it as the commit message when creating changesets. To find the 31.214 + beginning of the patch content, <command>patch</command> 31.215 + searches for the first line that starts with the string 31.216 + <quote><literal>diff -</literal></quote>.</para> 31.217 + 31.218 + <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs 31.219 + (<command>patch</command> can accept several other diff formats, 31.220 + but MQ doesn't). A unified diff contains two kinds of header. 31.221 + The <emphasis>file header</emphasis> describes the file being 31.222 + modified; it contains the name of the file to modify. When 31.223 + <command>patch</command> sees a new file header, it looks for a 31.224 + file with that name to start modifying.</para> 31.225 + 31.226 + <para id="x_3c7">After the file header comes a series of 31.227 + <emphasis>hunks</emphasis>. Each hunk starts with a header; 31.228 + this identifies the range of line numbers within the file that 31.229 + the hunk should modify. Following the header, a hunk starts and 31.230 + ends with a few (usually three) lines of text from the 31.231 + unmodified file; these are called the 31.232 + <emphasis>context</emphasis> for the hunk. If there's only a 31.233 + small amount of context between successive hunks, 31.234 + <command>diff</command> doesn't print a new hunk header; it just 31.235 + runs the hunks together, with a few lines of context between 31.236 + modifications.</para> 31.237 + 31.238 + <para id="x_3c8">Each line of context begins with a space character. Within 31.239 + the hunk, a line that begins with 31.240 + <quote><literal>-</literal></quote> means <quote>remove this 31.241 + line,</quote> while a line that begins with 31.242 + <quote><literal>+</literal></quote> means <quote>insert this 31.243 + line.</quote> For example, a line that is modified is 31.244 + represented by one deletion and one insertion.</para> 31.245 + 31.246 + <para id="x_3c9">We will return to some of the more subtle aspects of patches 31.247 + later (in <xref linkend="sec:mq:adv-patch"/>), but you 31.248 + should have 31.249 + enough information now to use MQ.</para> 31.250 + </sect1> 31.251 + 31.252 + <sect1 id="sec:mq:start"> 31.253 + <title>Getting started with Mercurial Queues</title> 31.254 + 31.255 + <para id="x_3ca">Because MQ is implemented as an extension, you must 31.256 + explicitly enable before you can use it. (You don't need to 31.257 + download anything; MQ ships with the standard Mercurial 31.258 + distribution.) To enable MQ, edit your <filename 31.259 + role="home">~/.hgrc</filename> file, and add the lines 31.260 + below.</para> 31.261 + 31.262 + <programlisting>[extensions] 31.263 +hgext.mq =</programlisting> 31.264 + 31.265 + <para id="x_3cb">Once the extension is enabled, it will make a number of new 31.266 + commands available. To verify that the extension is working, 31.267 + you can use <command role="hg-cmd">hg help</command> to see if 31.268 + the <command role="hg-ext-mq">qinit</command> command is now 31.269 + available.</para> 31.270 + 31.271 + &interaction.mq.qinit-help.help; 31.272 + 31.273 + <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial 31.274 + repository, and its commands only operate within that 31.275 + repository. To get started, simply prepare the repository using 31.276 + the <command role="hg-ext-mq">qinit</command> command.</para> 31.277 + 31.278 + &interaction.mq.tutorial.qinit; 31.279 + 31.280 + <para id="x_3cd">This command creates an empty directory called <filename 31.281 + role="special" class="directory">.hg/patches</filename>, where 31.282 + MQ will keep its metadata. As with many Mercurial commands, the 31.283 + <command role="hg-ext-mq">qinit</command> command prints nothing 31.284 + if it succeeds.</para> 31.285 + 31.286 + <sect2> 31.287 + <title>Creating a new patch</title> 31.288 + 31.289 + <para id="x_3ce">To begin work on a new patch, use the <command 31.290 + role="hg-ext-mq">qnew</command> command. This command takes 31.291 + one argument, the name of the patch to create.</para> 31.292 + 31.293 + <para id="x_3cf">MQ will use this as the name of an actual file in the 31.294 + <filename role="special" 31.295 + class="directory">.hg/patches</filename> directory, as you 31.296 + can see below.</para> 31.297 + 31.298 + &interaction.mq.tutorial.qnew; 31.299 + 31.300 + <para id="x_3d0">Also newly present in the <filename role="special" 31.301 + class="directory">.hg/patches</filename> directory are two 31.302 + other files, <filename role="special">series</filename> and 31.303 + <filename role="special">status</filename>. The <filename 31.304 + role="special">series</filename> file lists all of the 31.305 + patches that MQ knows about for this repository, with one 31.306 + patch per line. Mercurial uses the <filename 31.307 + role="special">status</filename> file for internal 31.308 + book-keeping; it tracks all of the patches that MQ has 31.309 + <emphasis>applied</emphasis> in this repository.</para> 31.310 + 31.311 + <note> 31.312 + <para id="x_3d1"> You may sometimes want to edit the <filename 31.313 + role="special">series</filename> file by hand; for 31.314 + example, to change the sequence in which some patches are 31.315 + applied. However, manually editing the <filename 31.316 + role="special">status</filename> file is almost always a 31.317 + bad idea, as it's easy to corrupt MQ's idea of what is 31.318 + happening.</para> 31.319 + </note> 31.320 + 31.321 + <para id="x_3d2">Once you have created your new patch, you can edit files 31.322 + in the working directory as you usually would. All of the 31.323 + normal Mercurial commands, such as <command role="hg-cmd">hg 31.324 + diff</command> and <command role="hg-cmd">hg 31.325 + annotate</command>, work exactly as they did before.</para> 31.326 + </sect2> 31.327 + 31.328 + <sect2> 31.329 + <title>Refreshing a patch</title> 31.330 + 31.331 + <para id="x_3d3">When you reach a point where you want to save your work, 31.332 + use the <command role="hg-ext-mq">qrefresh</command> command 31.333 + to update the patch you are working on.</para> 31.334 + 31.335 + &interaction.mq.tutorial.qrefresh; 31.336 + 31.337 + <para id="x_3d4">This command folds the changes you have made in the 31.338 + working directory into your patch, and updates its 31.339 + corresponding changeset to contain those changes.</para> 31.340 + 31.341 + <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command> 31.342 + as often as you like, so it's a good way to 31.343 + <quote>checkpoint</quote> your work. Refresh your patch at an 31.344 + opportune time; try an experiment; and if the experiment 31.345 + doesn't work out, <command role="hg-cmd">hg revert</command> 31.346 + your modifications back to the last time you refreshed.</para> 31.347 + 31.348 + &interaction.mq.tutorial.qrefresh2; 31.349 + </sect2> 31.350 + 31.351 + <sect2> 31.352 + <title>Stacking and tracking patches</title> 31.353 + 31.354 + <para id="x_3d6">Once you have finished working on a patch, or need to work 31.355 + on another, you can use the <command 31.356 + role="hg-ext-mq">qnew</command> command again to create a 31.357 + new patch. Mercurial will apply this patch on top of your 31.358 + existing patch.</para> 31.359 + 31.360 + &interaction.mq.tutorial.qnew2; 31.361 + 31.362 + <para id="x_3d7">Notice that the patch contains the changes in our prior 31.363 + patch as part of its context (you can see this more clearly in 31.364 + the output of <command role="hg-cmd">hg 31.365 + annotate</command>).</para> 31.366 + 31.367 + <para id="x_3d8">So far, with the exception of <command 31.368 + role="hg-ext-mq">qnew</command> and <command 31.369 + role="hg-ext-mq">qrefresh</command>, we've been careful to 31.370 + only use regular Mercurial commands. However, MQ provides 31.371 + many commands that are easier to use when you are thinking 31.372 + about patches, as illustrated below.</para> 31.373 + 31.374 + &interaction.mq.tutorial.qseries; 31.375 + 31.376 + <itemizedlist> 31.377 + <listitem><para id="x_3d9">The <command 31.378 + role="hg-ext-mq">qseries</command> command lists every 31.379 + patch that MQ knows about in this repository, from oldest 31.380 + to newest (most recently 31.381 + <emphasis>created</emphasis>).</para> 31.382 + </listitem> 31.383 + <listitem><para id="x_3da">The <command 31.384 + role="hg-ext-mq">qapplied</command> command lists every 31.385 + patch that MQ has <emphasis>applied</emphasis> in this 31.386 + repository, again from oldest to newest (most recently 31.387 + applied).</para> 31.388 + </listitem></itemizedlist> 31.389 + </sect2> 31.390 + 31.391 + <sect2> 31.392 + <title>Manipulating the patch stack</title> 31.393 + 31.394 + <para id="x_3db">The previous discussion implied that there must be a 31.395 + difference between <quote>known</quote> and 31.396 + <quote>applied</quote> patches, and there is. MQ can manage a 31.397 + patch without it being applied in the repository.</para> 31.398 + 31.399 + <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding 31.400 + changeset in the repository, and the effects of the patch and 31.401 + changeset are visible in the working directory. You can undo 31.402 + the application of a patch using the <command 31.403 + role="hg-ext-mq">qpop</command> command. MQ still 31.404 + <emphasis>knows about</emphasis>, or manages, a popped patch, 31.405 + but the patch no longer has a corresponding changeset in the 31.406 + repository, and the working directory does not contain the 31.407 + changes made by the patch. <xref 31.408 + linkend="fig:mq:stack"/> illustrates 31.409 + the difference between applied and tracked patches.</para> 31.410 + 31.411 + <figure id="fig:mq:stack"> 31.412 + <title>Applied and unapplied patches in the MQ patch 31.413 + stack</title> 31.414 + <mediaobject> 31.415 + <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject> 31.416 + <textobject><phrase>XXX add text</phrase></textobject> 31.417 + </mediaobject> 31.418 + </figure> 31.419 + 31.420 + <para id="x_3de">You can reapply an unapplied, or popped, patch using the 31.421 + <command role="hg-ext-mq">qpush</command> command. This 31.422 + creates a new changeset to correspond to the patch, and the 31.423 + patch's changes once again become present in the working 31.424 + directory. See below for examples of <command 31.425 + role="hg-ext-mq">qpop</command> and <command 31.426 + role="hg-ext-mq">qpush</command> in action.</para> 31.427 + 31.428 + &interaction.mq.tutorial.qpop; 31.429 + 31.430 + <para id="x_3df">Notice that once we have popped a patch or two patches, 31.431 + the output of <command role="hg-ext-mq">qseries</command> 31.432 + remains the same, while that of <command 31.433 + role="hg-ext-mq">qapplied</command> has changed.</para> 31.434 + 31.435 + </sect2> 31.436 + 31.437 + <sect2> 31.438 + <title>Pushing and popping many patches</title> 31.439 + 31.440 + <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and 31.441 + <command role="hg-ext-mq">qpop</command> each operate on a 31.442 + single patch at a time by default, you can push and pop many 31.443 + patches in one go. The <option 31.444 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to 31.445 + <command role="hg-ext-mq">qpush</command> causes it to push 31.446 + all unapplied patches, while the <option 31.447 + role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command 31.448 + role="hg-ext-mq">qpop</command> causes it to pop all applied 31.449 + patches. (For some more ways to push and pop many patches, 31.450 + see <xref linkend="sec:mq:perf"/> below.)</para> 31.451 + 31.452 + &interaction.mq.tutorial.qpush-a; 31.453 + </sect2> 31.454 + 31.455 + <sect2> 31.456 + <title>Safety checks, and overriding them</title> 31.457 + 31.458 + <para id="x_3e1">Several MQ commands check the working directory before 31.459 + they do anything, and fail if they find any modifications. 31.460 + They do this to ensure that you won't lose any changes that 31.461 + you have made, but not yet incorporated into a patch. The 31.462 + example below illustrates this; the <command 31.463 + role="hg-ext-mq">qnew</command> command will not create a 31.464 + new patch if there are outstanding changes, caused in this 31.465 + case by the <command role="hg-cmd">hg add</command> of 31.466 + <filename>file3</filename>.</para> 31.467 + 31.468 + &interaction.mq.tutorial.add; 31.469 + 31.470 + <para id="x_3e2">Commands that check the working directory all take an 31.471 + <quote>I know what I'm doing</quote> option, which is always 31.472 + named <option>-f</option>. The exact meaning of 31.473 + <option>-f</option> depends on the command. For example, 31.474 + <command role="hg-cmd">hg qnew <option 31.475 + role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command> 31.476 + will incorporate any outstanding changes into the new patch it 31.477 + creates, but <command role="hg-cmd">hg qpop <option 31.478 + role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command> 31.479 + will revert modifications to any files affected by the patch 31.480 + that it is popping. Be sure to read the documentation for a 31.481 + command's <option>-f</option> option before you use it!</para> 31.482 + </sect2> 31.483 + 31.484 + <sect2> 31.485 + <title>Working on several patches at once</title> 31.486 + 31.487 + <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command 31.488 + always refreshes the <emphasis>topmost</emphasis> applied 31.489 + patch. This means that you can suspend work on one patch (by 31.490 + refreshing it), pop or push to make a different patch the top, 31.491 + and work on <emphasis>that</emphasis> patch for a 31.492 + while.</para> 31.493 + 31.494 + <para id="x_3e4">Here's an example that illustrates how you can use this 31.495 + ability. Let's say you're developing a new feature as two 31.496 + patches. The first is a change to the core of your software, 31.497 + and the second&emdash;layered on top of the 31.498 + first&emdash;changes the user interface to use the code you 31.499 + just added to the core. If you notice a bug in the core while 31.500 + you're working on the UI patch, it's easy to fix the core. 31.501 + Simply <command role="hg-ext-mq">qrefresh</command> the UI 31.502 + patch to save your in-progress changes, and <command 31.503 + role="hg-ext-mq">qpop</command> down to the core patch. Fix 31.504 + the core bug, <command role="hg-ext-mq">qrefresh</command> the 31.505 + core patch, and <command role="hg-ext-mq">qpush</command> back 31.506 + to the UI patch to continue where you left off.</para> 31.507 + </sect2> 31.508 + </sect1> 31.509 + 31.510 + <sect1 id="sec:mq:adv-patch"> 31.511 + <title>More about patches</title> 31.512 + 31.513 + <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply 31.514 + patches, so it's helpful to know a few more detailed aspects of 31.515 + how <command>patch</command> works, and about patches 31.516 + themselves.</para> 31.517 + 31.518 + <sect2> 31.519 + <title>The strip count</title> 31.520 + 31.521 + <para id="x_3e6">If you look at the file headers in a patch, you will 31.522 + notice that the pathnames usually have an extra component on 31.523 + the front that isn't present in the actual path name. This is 31.524 + a holdover from the way that people used to generate patches 31.525 + (people still do this, but it's somewhat rare with modern 31.526 + revision control tools).</para> 31.527 + 31.528 + <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide 31.529 + that she wanted to create a patch. So she'd rename her 31.530 + working directory, unpack the tarball again (hence the need 31.531 + for the rename), and use the <option 31.532 + role="cmd-opt-diff">-r</option> and <option 31.533 + role="cmd-opt-diff">-N</option> options to 31.534 + <command>diff</command> to recursively generate a patch 31.535 + between the unmodified directory and the modified one. The 31.536 + result would be that the name of the unmodified directory 31.537 + would be at the front of the left-hand path in every file 31.538 + header, and the name of the modified directory would be at the 31.539 + front of the right-hand path.</para> 31.540 + 31.541 + <para id="x_3e8">Since someone receiving a patch from the Alices of the net 31.542 + would be unlikely to have unmodified and modified directories 31.543 + with exactly the same names, the <command>patch</command> 31.544 + command has a <option role="cmd-opt-patch">-p</option> option 31.545 + that indicates the number of leading path name components to 31.546 + strip when trying to apply a patch. This number is called the 31.547 + <emphasis>strip count</emphasis>.</para> 31.548 + 31.549 + <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means 31.550 + <quote>use a strip count of one</quote>. If 31.551 + <command>patch</command> sees a file name 31.552 + <filename>foo/bar/baz</filename> in a file header, it will 31.553 + strip <filename>foo</filename> and try to patch a file named 31.554 + <filename>bar/baz</filename>. (Strictly speaking, the strip 31.555 + count refers to the number of <emphasis>path 31.556 + separators</emphasis> (and the components that go with them 31.557 + ) to strip. A strip count of one will turn 31.558 + <filename>foo/bar</filename> into <filename>bar</filename>, 31.559 + but <filename>/foo/bar</filename> (notice the extra leading 31.560 + slash) into <filename>foo/bar</filename>.)</para> 31.561 + 31.562 + <para id="x_3ea">The <quote>standard</quote> strip count for patches is 31.563 + one; almost all patches contain one leading path name 31.564 + component that needs to be stripped. Mercurial's <command 31.565 + role="hg-cmd">hg diff</command> command generates path names 31.566 + in this form, and the <command role="hg-cmd">hg 31.567 + import</command> command and MQ expect patches to have a 31.568 + strip count of one.</para> 31.569 + 31.570 + <para id="x_3eb">If you receive a patch from someone that you want to add 31.571 + to your patch queue, and the patch needs a strip count other 31.572 + than one, you cannot just <command 31.573 + role="hg-ext-mq">qimport</command> the patch, because 31.574 + <command role="hg-ext-mq">qimport</command> does not yet have 31.575 + a <literal>-p</literal> option (see <ulink role="hg-bug" 31.576 + url="http://www.selenic.com/mercurial/bts/issue311">issue 31.577 + 311</ulink>). Your best bet is to <command 31.578 + role="hg-ext-mq">qnew</command> a patch of your own, then 31.579 + use <command>patch -pN</command> to apply their patch, 31.580 + followed by <command role="hg-cmd">hg addremove</command> to 31.581 + pick up any files added or removed by the patch, followed by 31.582 + <command role="hg-ext-mq">hg qrefresh</command>. This 31.583 + complexity may become unnecessary; see <ulink role="hg-bug" 31.584 + url="http://www.selenic.com/mercurial/bts/issue311">issue 31.585 + 311</ulink> for details. 31.586 + </para> 31.587 + </sect2> 31.588 + 31.589 + <sect2> 31.590 + <title>Strategies for applying a patch</title> 31.591 + 31.592 + <para id="x_3ec">When <command>patch</command> applies a hunk, it tries a 31.593 + handful of successively less accurate strategies to try to 31.594 + make the hunk apply. This falling-back technique often makes 31.595 + it possible to take a patch that was generated against an old 31.596 + version of a file, and apply it against a newer version of 31.597 + that file.</para> 31.598 + 31.599 + <para id="x_3ed">First, <command>patch</command> tries an exact match, 31.600 + where the line numbers, the context, and the text to be 31.601 + modified must apply exactly. If it cannot make an exact 31.602 + match, it tries to find an exact match for the context, 31.603 + without honouring the line numbering information. If this 31.604 + succeeds, it prints a line of output saying that the hunk was 31.605 + applied, but at some <emphasis>offset</emphasis> from the 31.606 + original line number.</para> 31.607 + 31.608 + <para id="x_3ee">If a context-only match fails, <command>patch</command> 31.609 + removes the first and last lines of the context, and tries a 31.610 + <emphasis>reduced</emphasis> context-only match. If the hunk 31.611 + with reduced context succeeds, it prints a message saying that 31.612 + it applied the hunk with a <emphasis>fuzz factor</emphasis> 31.613 + (the number after the fuzz factor indicates how many lines of 31.614 + context <command>patch</command> had to trim before the patch 31.615 + applied).</para> 31.616 + 31.617 + <para id="x_3ef">When neither of these techniques works, 31.618 + <command>patch</command> prints a message saying that the hunk 31.619 + in question was rejected. It saves rejected hunks (also 31.620 + simply called <quote>rejects</quote>) to a file with the same 31.621 + name, and an added <filename role="special">.rej</filename> 31.622 + extension. It also saves an unmodified copy of the file with 31.623 + a <filename role="special">.orig</filename> extension; the 31.624 + copy of the file without any extensions will contain any 31.625 + changes made by hunks that <emphasis>did</emphasis> apply 31.626 + cleanly. If you have a patch that modifies 31.627 + <filename>foo</filename> with six hunks, and one of them fails 31.628 + to apply, you will have: an unmodified 31.629 + <filename>foo.orig</filename>, a <filename>foo.rej</filename> 31.630 + containing one hunk, and <filename>foo</filename>, containing 31.631 + the changes made by the five successful hunks.</para> 31.632 + </sect2> 31.633 + 31.634 + <sect2> 31.635 + <title>Some quirks of patch representation</title> 31.636 + 31.637 + <para id="x_3f0">There are a few useful things to know about how 31.638 + <command>patch</command> works with files.</para> 31.639 + <itemizedlist> 31.640 + <listitem><para id="x_3f1">This should already be obvious, but 31.641 + <command>patch</command> cannot handle binary 31.642 + files.</para> 31.643 + </listitem> 31.644 + <listitem><para id="x_3f2">Neither does it care about the executable bit; 31.645 + it creates new files as readable, but not 31.646 + executable.</para> 31.647 + </listitem> 31.648 + <listitem><para id="x_3f3"><command>patch</command> treats the removal of 31.649 + a file as a diff between the file to be removed and the 31.650 + empty file. So your idea of <quote>I deleted this 31.651 + file</quote> looks like <quote>every line of this file 31.652 + was deleted</quote> in a patch.</para> 31.653 + </listitem> 31.654 + <listitem><para id="x_3f4">It treats the addition of a file as a diff 31.655 + between the empty file and the file to be added. So in a 31.656 + patch, your idea of <quote>I added this file</quote> looks 31.657 + like <quote>every line of this file was 31.658 + added</quote>.</para> 31.659 + </listitem> 31.660 + <listitem><para id="x_3f5">It treats a renamed file as the removal of the 31.661 + old name, and the addition of the new name. This means 31.662 + that renamed files have a big footprint in patches. (Note 31.663 + also that Mercurial does not currently try to infer when 31.664 + files have been renamed or copied in a patch.)</para> 31.665 + </listitem> 31.666 + <listitem><para id="x_3f6"><command>patch</command> cannot represent 31.667 + empty files, so you cannot use a patch to represent the 31.668 + notion <quote>I added this empty file to the 31.669 + tree</quote>.</para> 31.670 + </listitem></itemizedlist> 31.671 + </sect2> 31.672 + 31.673 + <sect2> 31.674 + <title>Beware the fuzz</title> 31.675 + 31.676 + <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor, 31.677 + will often be completely successful, these inexact techniques 31.678 + naturally leave open the possibility of corrupting the patched 31.679 + file. The most common cases typically involve applying a 31.680 + patch twice, or at an incorrect location in the file. If 31.681 + <command>patch</command> or <command 31.682 + role="hg-ext-mq">qpush</command> ever mentions an offset or 31.683 + fuzz factor, you should make sure that the modified files are 31.684 + correct afterwards.</para> 31.685 + 31.686 + <para id="x_3f8">It's often a good idea to refresh a patch that has applied 31.687 + with an offset or fuzz factor; refreshing the patch generates 31.688 + new context information that will make it apply cleanly. I 31.689 + say <quote>often,</quote> not <quote>always,</quote> because 31.690 + sometimes refreshing a patch will make it fail to apply 31.691 + against a different revision of the underlying files. In some 31.692 + cases, such as when you're maintaining a patch that must sit 31.693 + on top of multiple versions of a source tree, it's acceptable 31.694 + to have a patch apply with some fuzz, provided you've verified 31.695 + the results of the patching process in such cases.</para> 31.696 + </sect2> 31.697 + 31.698 + <sect2> 31.699 + <title>Handling rejection</title> 31.700 + 31.701 + <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to 31.702 + apply a patch, it will print an error message and exit. If it 31.703 + has left <filename role="special">.rej</filename> files 31.704 + behind, it is usually best to fix up the rejected hunks before 31.705 + you push more patches or do any further work.</para> 31.706 + 31.707 + <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly, 31.708 + and no longer does because you've changed the underlying code 31.709 + that your patches are based on, Mercurial Queues can help; see 31.710 + <xref linkend="sec:mq:merge"/> for details.</para> 31.711 + 31.712 + <para id="x_3fb">Unfortunately, there aren't any great techniques for 31.713 + dealing with rejected hunks. Most often, you'll need to view 31.714 + the <filename role="special">.rej</filename> file and edit the 31.715 + target file, applying the rejected hunks by hand.</para> 31.716 + 31.717 + <para id="x_3fd">A Linux kernel hacker, Chris Mason (the author 31.718 + of Mercurial Queues), wrote a tool called 31.719 + <command>mpatch</command> (<ulink 31.720 + url="http://oss.oracle.com/~mason/mpatch/">http://oss.oracle.com/~mason/mpatch/</ulink>), 31.721 + which takes a simple approach to automating the application of 31.722 + hunks rejected by <command>patch</command>. The 31.723 + <command>mpatch</command> command can help with four common 31.724 + reasons that a hunk may be rejected:</para> 31.725 + 31.726 + <itemizedlist> 31.727 + <listitem><para id="x_3fe">The context in the middle of a hunk has 31.728 + changed.</para> 31.729 + </listitem> 31.730 + <listitem><para id="x_3ff">A hunk is missing some context at the 31.731 + beginning or end.</para> 31.732 + </listitem> 31.733 + <listitem><para id="x_400">A large hunk might apply better&emdash;either 31.734 + entirely or in part&emdash;if it was broken up into 31.735 + smaller hunks.</para> 31.736 + </listitem> 31.737 + <listitem><para id="x_401">A hunk removes lines with slightly different 31.738 + content than those currently present in the file.</para> 31.739 + </listitem></itemizedlist> 31.740 + 31.741 + <para id="x_402">If you use <command>mpatch</command>, you 31.742 + should be doubly careful to check your results when you're 31.743 + done. In fact, <command>mpatch</command> enforces this method 31.744 + of double-checking the tool's output, by automatically 31.745 + dropping you into a merge program when it has done its job, so 31.746 + that you can verify its work and finish off any remaining 31.747 + merges.</para> 31.748 + </sect2> 31.749 + </sect1> 31.750 + 31.751 + <sect1> 31.752 + <title>More on patch management</title> 31.753 + 31.754 + <para id="x_6db">As you grow familiar with MQ, you will find yourself wanting 31.755 + to perform other kinds of patch management operations.</para> 31.756 + 31.757 + <sect2> 31.758 + <title>Deleting unwanted patches</title> 31.759 + 31.760 + <para id="x_6dc">If you want to get rid of a patch, use the <command 31.761 + role="hg-ext-mq">hg qdelete</command> command to delete the 31.762 + patch file and remove its entry from the patch series. If you 31.763 + try to delete a patch that is still applied, <command 31.764 + role="hg-ext-mq">hg qdelete</command> will refuse.</para> 31.765 + 31.766 + &interaction.ch11-qdelete.go; 31.767 + </sect2> 31.768 + 31.769 + <sect2> 31.770 + <title>Converting to and from permanent revisions</title> 31.771 + 31.772 + <para id="x_6dd">Once you're done working on a patch and want to 31.773 + turn it into a permanent changeset, use the <command 31.774 + role="hg-ext-mq">hg qfinish</command> command. Pass a revision 31.775 + to the command to identify the patch that you want to turn into 31.776 + a regular changeset; this patch must already be applied.</para> 31.777 + 31.778 + &interaction.ch11-qdelete.convert; 31.779 + 31.780 + <para id="x_6e0">The <command role="hg-ext-mq">hg qfinish</command> command 31.781 + accepts an <option>--all</option> or <option>-a</option> 31.782 + option, which turns all applied patches into regular 31.783 + changesets.</para> 31.784 + 31.785 + <para id="x_6de">It is also possible to turn an existing changeset into a 31.786 + patch, by passing the <option>-r</option> option to <command 31.787 + role="hg-ext-mq">hg qimport</command>.</para> 31.788 + 31.789 + &interaction.ch11-qdelete.import; 31.790 + 31.791 + <para id="x_6df">Note that it only makes sense to convert a changeset into 31.792 + a patch if you have not propagated that changeset into any 31.793 + other repositories. The imported changeset's ID will change 31.794 + every time you refresh the patch, which will make Mercurial 31.795 + treat it as unrelated to the original changeset if you have 31.796 + pushed it somewhere else.</para> 31.797 + </sect2> 31.798 + </sect1> 31.799 + 31.800 + <sect1 id="sec:mq:perf"> 31.801 + <title>Getting the best performance out of MQ</title> 31.802 + 31.803 + <para id="x_403">MQ is very efficient at handling a large number 31.804 + of patches. I ran some performance experiments in mid-2006 for a 31.805 + talk that I gave at the 2006 EuroPython conference (on modern 31.806 + hardware, you should expect better performance than you'll see 31.807 + below). I used as my data set the Linux 2.6.17-mm1 patch 31.808 + series, which consists of 1,738 patches. I applied these on top 31.809 + of a Linux kernel repository containing all 27,472 revisions 31.810 + between Linux 2.6.12-rc2 and Linux 2.6.17.</para> 31.811 + 31.812 + <para id="x_404">On my old, slow laptop, I was able to <command 31.813 + role="hg-cmd">hg qpush <option 31.814 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all 31.815 + 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop 31.816 + <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 31.817 + them all in 30 seconds. (On a newer laptop, the time to push 31.818 + all patches dropped to two minutes.) I could <command 31.819 + role="hg-ext-mq">qrefresh</command> one of the biggest patches 31.820 + (which made 22,779 lines of changes to 287 files) in 6.6 31.821 + seconds.</para> 31.822 + 31.823 + <para id="x_405">Clearly, MQ is well suited to working in large trees, but 31.824 + there are a few tricks you can use to get the best performance 31.825 + of it.</para> 31.826 + 31.827 + <para id="x_406">First of all, try to <quote>batch</quote> operations 31.828 + together. Every time you run <command 31.829 + role="hg-ext-mq">qpush</command> or <command 31.830 + role="hg-ext-mq">qpop</command>, these commands scan the 31.831 + working directory once to make sure you haven't made some 31.832 + changes and then forgotten to run <command 31.833 + role="hg-ext-mq">qrefresh</command>. On a small tree, the 31.834 + time that this scan takes is unnoticeable. However, on a 31.835 + medium-sized tree (containing tens of thousands of files), it 31.836 + can take a second or more.</para> 31.837 + 31.838 + <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command 31.839 + role="hg-ext-mq">qpop</command> commands allow you to push and 31.840 + pop multiple patches at a time. You can identify the 31.841 + <quote>destination patch</quote> that you want to end up at. 31.842 + When you <command role="hg-ext-mq">qpush</command> with a 31.843 + destination specified, it will push patches until that patch is 31.844 + at the top of the applied stack. When you <command 31.845 + role="hg-ext-mq">qpop</command> to a destination, MQ will pop 31.846 + patches until the destination patch is at the top.</para> 31.847 + 31.848 + <para id="x_408">You can identify a destination patch using either the name 31.849 + of the patch, or by number. If you use numeric addressing, 31.850 + patches are counted from zero; this means that the first patch 31.851 + is zero, the second is one, and so on.</para> 31.852 + </sect1> 31.853 + 31.854 + <sect1 id="sec:mq:merge"> 31.855 + <title>Updating your patches when the underlying code 31.856 + changes</title> 31.857 + 31.858 + <para id="x_409">It's common to have a stack of patches on top of an 31.859 + underlying repository that you don't modify directly. If you're 31.860 + working on changes to third-party code, or on a feature that is 31.861 + taking longer to develop than the rate of change of the code 31.862 + beneath, you will often need to sync up with the underlying 31.863 + code, and fix up any hunks in your patches that no longer apply. 31.864 + This is called <emphasis>rebasing</emphasis> your patch 31.865 + series.</para> 31.866 + 31.867 + <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg 31.868 + qpop <option role="hg-ext-mq-cmd-qpop-opt">hg 31.869 + -a</option></command> your patches, then <command 31.870 + role="hg-cmd">hg pull</command> changes into the underlying 31.871 + repository, and finally <command role="hg-cmd">hg qpush <option 31.872 + role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your 31.873 + patches again. MQ will stop pushing any time it runs across a 31.874 + patch that fails to apply during conflicts, allowing you to fix 31.875 + your conflicts, <command role="hg-ext-mq">qrefresh</command> the 31.876 + affected patch, and continue pushing until you have fixed your 31.877 + entire stack.</para> 31.878 + 31.879 + <para id="x_40b">This approach is easy to use and works well if you don't 31.880 + expect changes to the underlying code to affect how well your 31.881 + patches apply. If your patch stack touches code that is modified 31.882 + frequently or invasively in the underlying repository, however, 31.883 + fixing up rejected hunks by hand quickly becomes 31.884 + tiresome.</para> 31.885 + 31.886 + <para id="x_40c">It's possible to partially automate the rebasing process. 31.887 + If your patches apply cleanly against some revision of the 31.888 + underlying repo, MQ can use this information to help you to 31.889 + resolve conflicts between your patches and a different 31.890 + revision.</para> 31.891 + 31.892 + <para id="x_40d">The process is a little involved.</para> 31.893 + <orderedlist> 31.894 + <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush 31.895 + -a</command> all of your patches on top of the revision 31.896 + where you know that they apply cleanly.</para> 31.897 + </listitem> 31.898 + <listitem><para id="x_40f">Save a backup copy of your patch directory using 31.899 + <command role="hg-cmd">hg qsave <option 31.900 + role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option 31.901 + role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. 31.902 + This prints the name of the directory that it has saved the 31.903 + patches in. It will save the patches to a directory called 31.904 + <filename role="special" 31.905 + class="directory">.hg/patches.N</filename>, where 31.906 + <literal>N</literal> is a small integer. It also commits a 31.907 + <quote>save changeset</quote> on top of your applied 31.908 + patches; this is for internal book-keeping, and records the 31.909 + states of the <filename role="special">series</filename> and 31.910 + <filename role="special">status</filename> files.</para> 31.911 + </listitem> 31.912 + <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to 31.913 + bring new changes into the underlying repository. (Don't 31.914 + run <command role="hg-cmd">hg pull -u</command>; see below 31.915 + for why.)</para> 31.916 + </listitem> 31.917 + <listitem><para id="x_411">Update to the new tip revision, using <command 31.918 + role="hg-cmd">hg update <option 31.919 + role="hg-opt-update">-C</option></command> to override 31.920 + the patches you have pushed.</para> 31.921 + </listitem> 31.922 + <listitem><para id="x_412">Merge all patches using <command>hg qpush -m 31.923 + -a</command>. The <option 31.924 + role="hg-ext-mq-cmd-qpush-opt">-m</option> option to 31.925 + <command role="hg-ext-mq">qpush</command> tells MQ to 31.926 + perform a three-way merge if the patch fails to 31.927 + apply.</para> 31.928 + </listitem></orderedlist> 31.929 + 31.930 + <para id="x_413">During the <command role="hg-cmd">hg qpush <option 31.931 + role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, 31.932 + each patch in the <filename role="special">series</filename> 31.933 + file is applied normally. If a patch applies with fuzz or 31.934 + rejects, MQ looks at the queue you <command 31.935 + role="hg-ext-mq">qsave</command>d, and performs a three-way 31.936 + merge with the corresponding changeset. This merge uses 31.937 + Mercurial's normal merge machinery, so it may pop up a GUI merge 31.938 + tool to help you to resolve problems.</para> 31.939 + 31.940 + <para id="x_414">When you finish resolving the effects of a patch, MQ 31.941 + refreshes your patch based on the result of the merge.</para> 31.942 + 31.943 + <para id="x_415">At the end of this process, your repository will have one 31.944 + extra head from the old patch queue, and a copy of the old patch 31.945 + queue will be in <filename role="special" 31.946 + class="directory">.hg/patches.N</filename>. You can remove the 31.947 + extra head using <command role="hg-cmd">hg qpop -a -n 31.948 + patches.N</command> or <command role="hg-cmd">hg 31.949 + strip</command>. You can delete <filename role="special" 31.950 + class="directory">.hg/patches.N</filename> once you are sure 31.951 + that you no longer need it as a backup.</para> 31.952 + </sect1> 31.953 + 31.954 + <sect1> 31.955 + <title>Identifying patches</title> 31.956 + 31.957 + <para id="x_416">MQ commands that work with patches let you refer to a patch 31.958 + either by using its name or by a number. By name is obvious 31.959 + enough; pass the name <filename>foo.patch</filename> to <command 31.960 + role="hg-ext-mq">qpush</command>, for example, and it will 31.961 + push patches until <filename>foo.patch</filename> is 31.962 + applied.</para> 31.963 + 31.964 + <para id="x_417">As a shortcut, you can refer to a patch using both a name 31.965 + and a numeric offset; <literal>foo.patch-2</literal> means 31.966 + <quote>two patches before <literal>foo.patch</literal></quote>, 31.967 + while <literal>bar.patch+4</literal> means <quote>four patches 31.968 + after <literal>bar.patch</literal></quote>.</para> 31.969 + 31.970 + <para id="x_418">Referring to a patch by index isn't much different. The 31.971 + first patch printed in the output of <command 31.972 + role="hg-ext-mq">qseries</command> is patch zero (yes, it's 31.973 + one of those start-at-zero counting systems); the second is 31.974 + patch one; and so on.</para> 31.975 + 31.976 + <para id="x_419">MQ also makes it easy to work with patches when you are 31.977 + using normal Mercurial commands. Every command that accepts a 31.978 + changeset ID will also accept the name of an applied patch. MQ 31.979 + augments the tags normally in the repository with an eponymous 31.980 + one for each applied patch. In addition, the special tags 31.981 + <literal role="tag">qbase</literal> and 31.982 + <literal role="tag">qtip</literal> identify 31.983 + the <quote>bottom-most</quote> and topmost applied patches, 31.984 + respectively.</para> 31.985 + 31.986 + <para id="x_41a">These additions to Mercurial's normal tagging capabilities 31.987 + make dealing with patches even more of a breeze.</para> 31.988 + <itemizedlist> 31.989 + <listitem><para id="x_41b">Want to patchbomb a mailing list with your 31.990 + latest series of changes?</para> 31.991 + <programlisting>hg email qbase:qtip</programlisting> 31.992 + <para id="x_41c"> (Don't know what <quote>patchbombing</quote> is? See 31.993 + <xref linkend="sec:hgext:patchbomb"/>.)</para> 31.994 + </listitem> 31.995 + <listitem><para id="x_41d">Need to see all of the patches since 31.996 + <literal>foo.patch</literal> that have touched files in a 31.997 + subdirectory of your tree?</para> 31.998 + <programlisting>hg log -r foo.patch:qtip subdir</programlisting> 31.999 + </listitem> 31.1000 + </itemizedlist> 31.1001 + 31.1002 + <para id="x_41e">Because MQ makes the names of patches available to the rest 31.1003 + of Mercurial through its normal internal tag machinery, you 31.1004 + don't need to type in the entire name of a patch when you want 31.1005 + to identify it by name.</para> 31.1006 + 31.1007 + <para id="x_41f">Another nice consequence of representing patch names as tags 31.1008 + is that when you run the <command role="hg-cmd">hg log</command> 31.1009 + command, it will display a patch's name as a tag, simply as part 31.1010 + of its normal output. This makes it easy to visually 31.1011 + distinguish applied patches from underlying 31.1012 + <quote>normal</quote> revisions. The following example shows a 31.1013 + few normal Mercurial commands in use with applied 31.1014 + patches.</para> 31.1015 + 31.1016 + &interaction.mq.id.output; 31.1017 + </sect1> 31.1018 + 31.1019 + <sect1> 31.1020 + <title>Useful things to know about</title> 31.1021 + 31.1022 + <para id="x_420">There are a number of aspects of MQ usage that don't fit 31.1023 + tidily into sections of their own, but that are good to know. 31.1024 + Here they are, in one place.</para> 31.1025 + 31.1026 + <itemizedlist> 31.1027 + <listitem><para id="x_421">Normally, when you <command 31.1028 + role="hg-ext-mq">qpop</command> a patch and <command 31.1029 + role="hg-ext-mq">qpush</command> it again, the changeset 31.1030 + that represents the patch after the pop/push will have a 31.1031 + <emphasis>different identity</emphasis> than the changeset 31.1032 + that represented the hash beforehand. See <xref 31.1033 + linkend="sec:mqref:cmd:qpush"/> for 31.1034 + information as to why this is.</para> 31.1035 + </listitem> 31.1036 + <listitem><para id="x_422">It's not a good idea to <command 31.1037 + role="hg-cmd">hg merge</command> changes from another 31.1038 + branch with a patch changeset, at least if you want to 31.1039 + maintain the <quote>patchiness</quote> of that changeset and 31.1040 + changesets below it on the patch stack. If you try to do 31.1041 + this, it will appear to succeed, but MQ will become 31.1042 + confused.</para> 31.1043 + </listitem></itemizedlist> 31.1044 + </sect1> 31.1045 + 31.1046 + <sect1 id="sec:mq:repo"> 31.1047 + <title>Managing patches in a repository</title> 31.1048 + 31.1049 + <para id="x_423">Because MQ's <filename role="special" 31.1050 + class="directory">.hg/patches</filename> directory resides 31.1051 + outside a Mercurial repository's working directory, the 31.1052 + <quote>underlying</quote> Mercurial repository knows nothing 31.1053 + about the management or presence of patches.</para> 31.1054 + 31.1055 + <para id="x_424">This presents the interesting possibility of managing the 31.1056 + contents of the patch directory as a Mercurial repository in its 31.1057 + own right. This can be a useful way to work. For example, you 31.1058 + can work on a patch for a while, <command 31.1059 + role="hg-ext-mq">qrefresh</command> it, then <command 31.1060 + role="hg-cmd">hg commit</command> the current state of the 31.1061 + patch. This lets you <quote>roll back</quote> to that version 31.1062 + of the patch later on.</para> 31.1063 + 31.1064 + <para id="x_425">You can then share different versions of the same patch 31.1065 + stack among multiple underlying repositories. I use this when I 31.1066 + am developing a Linux kernel feature. I have a pristine copy of 31.1067 + my kernel sources for each of several CPU architectures, and a 31.1068 + cloned repository under each that contains the patches I am 31.1069 + working on. When I want to test a change on a different 31.1070 + architecture, I push my current patches to the patch repository 31.1071 + associated with that kernel tree, pop and push all of my 31.1072 + patches, and build and test that kernel.</para> 31.1073 + 31.1074 + <para id="x_426">Managing patches in a repository makes it possible for 31.1075 + multiple developers to work on the same patch series without 31.1076 + colliding with each other, all on top of an underlying source 31.1077 + base that they may or may not control.</para> 31.1078 + 31.1079 + <sect2> 31.1080 + <title>MQ support for patch repositories</title> 31.1081 + 31.1082 + <para id="x_427">MQ helps you to work with the <filename role="special" 31.1083 + class="directory">.hg/patches</filename> directory as a 31.1084 + repository; when you prepare a repository for working with 31.1085 + patches using <command role="hg-ext-mq">qinit</command>, you 31.1086 + can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg 31.1087 + -c</option> option to create the <filename role="special" 31.1088 + class="directory">.hg/patches</filename> directory as a 31.1089 + Mercurial repository.</para> 31.1090 + 31.1091 + <note> 31.1092 + <para id="x_428"> If you forget to use the <option 31.1093 + role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you 31.1094 + can simply go into the <filename role="special" 31.1095 + class="directory">.hg/patches</filename> directory at any 31.1096 + time and run <command role="hg-cmd">hg init</command>. 31.1097 + Don't forget to add an entry for the <filename 31.1098 + role="special">status</filename> file to the <filename 31.1099 + role="special">.hgignore</filename> file, though</para> 31.1100 + 31.1101 + <para id="x_429"> (<command role="hg-cmd">hg qinit <option 31.1102 + role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> 31.1103 + does this for you automatically); you 31.1104 + <emphasis>really</emphasis> don't want to manage the 31.1105 + <filename role="special">status</filename> file.</para> 31.1106 + </note> 31.1107 + 31.1108 + <para id="x_42a">As a convenience, if MQ notices that the <filename 31.1109 + class="directory">.hg/patches</filename> directory is a 31.1110 + repository, it will automatically <command role="hg-cmd">hg 31.1111 + add</command> every patch that you create and import.</para> 31.1112 + 31.1113 + <para id="x_42b">MQ provides a shortcut command, <command 31.1114 + role="hg-ext-mq">qcommit</command>, that runs <command 31.1115 + role="hg-cmd">hg commit</command> in the <filename 31.1116 + role="special" class="directory">.hg/patches</filename> 31.1117 + directory. This saves some bothersome typing.</para> 31.1118 + 31.1119 + <para id="x_42c">Finally, as a convenience to manage the patch directory, 31.1120 + you can define the alias <command>mq</command> on Unix 31.1121 + systems. For example, on Linux systems using the 31.1122 + <command>bash</command> shell, you can include the following 31.1123 + snippet in your <filename 31.1124 + role="home">~/.bashrc</filename>.</para> 31.1125 + 31.1126 + <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting> 31.1127 + 31.1128 + <para id="x_42d">You can then issue commands of the form <command>mq 31.1129 + pull</command> from the main repository.</para> 31.1130 + </sect2> 31.1131 + 31.1132 + <sect2> 31.1133 + <title>A few things to watch out for</title> 31.1134 + 31.1135 + <para id="x_42e">MQ's support for working with a repository full of patches 31.1136 + is limited in a few small respects.</para> 31.1137 + 31.1138 + <para id="x_42f">MQ cannot automatically detect changes that you make to 31.1139 + the patch directory. If you <command role="hg-cmd">hg 31.1140 + pull</command>, manually edit, or <command role="hg-cmd">hg 31.1141 + update</command> changes to patches or the <filename 31.1142 + role="special">series</filename> file, you will have to 31.1143 + <command role="hg-cmd">hg qpop <option 31.1144 + role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and 31.1145 + then <command role="hg-cmd">hg qpush <option 31.1146 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in 31.1147 + the underlying repository to see those changes show up there. 31.1148 + If you forget to do this, you can confuse MQ's idea of which 31.1149 + patches are applied.</para> 31.1150 + 31.1151 + </sect2> 31.1152 + </sect1> 31.1153 + <sect1 id="sec:mq:tools"> 31.1154 + <title>Third party tools for working with patches</title> 31.1155 + 31.1156 + <para id="x_430">Once you've been working with patches for a while, you'll 31.1157 + find yourself hungry for tools that will help you to understand 31.1158 + and manipulate the patches you're dealing with.</para> 31.1159 + 31.1160 + <para id="x_431">The <command>diffstat</command> command 31.1161 + <citation>web:diffstat</citation> generates a histogram of the 31.1162 + modifications made to each file in a patch. It provides a good 31.1163 + way to <quote>get a sense of</quote> a patch&emdash;which files 31.1164 + it affects, and how much change it introduces to each file and 31.1165 + as a whole. (I find that it's a good idea to use 31.1166 + <command>diffstat</command>'s <option 31.1167 + role="cmd-opt-diffstat">-p</option> option as a matter of 31.1168 + course, as otherwise it will try to do clever things with 31.1169 + prefixes of file names that inevitably confuse at least 31.1170 + me.)</para> 31.1171 + 31.1172 +&interaction.mq.tools.tools; 31.1173 + 31.1174 + <para id="x_432">The <literal role="package">patchutils</literal> package 31.1175 + <citation>web:patchutils</citation> is invaluable. It provides a 31.1176 + set of small utilities that follow the <quote>Unix 31.1177 + philosophy;</quote> each does one useful thing with a patch. 31.1178 + The <literal role="package">patchutils</literal> command I use 31.1179 + most is <command>filterdiff</command>, which extracts subsets 31.1180 + from a patch file. For example, given a patch that modifies 31.1181 + hundreds of files across dozens of directories, a single 31.1182 + invocation of <command>filterdiff</command> can generate a 31.1183 + smaller patch that only touches files whose names match a 31.1184 + particular glob pattern. See <xref 31.1185 + linkend="mq-collab:tips:interdiff"/> for another 31.1186 + example.</para> 31.1187 + 31.1188 + </sect1> 31.1189 + <sect1> 31.1190 + <title>Good ways to work with patches</title> 31.1191 + 31.1192 + <para id="x_433">Whether you are working on a patch series to submit to a 31.1193 + free software or open source project, or a series that you 31.1194 + intend to treat as a sequence of regular changesets when you're 31.1195 + done, you can use some simple techniques to keep your work well 31.1196 + organized.</para> 31.1197 + 31.1198 + <para id="x_434">Give your patches descriptive names. A good name for a 31.1199 + patch might be <filename>rework-device-alloc.patch</filename>, 31.1200 + because it will immediately give you a hint what the purpose of 31.1201 + the patch is. Long names shouldn't be a problem; you won't be 31.1202 + typing the names often, but you <emphasis>will</emphasis> be 31.1203 + running commands like <command 31.1204 + role="hg-ext-mq">qapplied</command> and <command 31.1205 + role="hg-ext-mq">qtop</command> over and over. Good naming 31.1206 + becomes especially important when you have a number of patches 31.1207 + to work with, or if you are juggling a number of different tasks 31.1208 + and your patches only get a fraction of your attention.</para> 31.1209 + 31.1210 + <para id="x_435">Be aware of what patch you're working on. Use the <command 31.1211 + role="hg-ext-mq">qtop</command> command and skim over the text 31.1212 + of your patches frequently&emdash;for example, using <command 31.1213 + role="hg-cmd">hg tip <option 31.1214 + role="hg-opt-tip">-p</option></command>)&emdash;to be sure 31.1215 + of where you stand. I have several times worked on and <command 31.1216 + role="hg-ext-mq">qrefresh</command>ed a patch other than the 31.1217 + one I intended, and it's often tricky to migrate changes into 31.1218 + the right patch after making them in the wrong one.</para> 31.1219 + 31.1220 + <para id="x_436">For this reason, it is very much worth investing a little 31.1221 + time to learn how to use some of the third-party tools I 31.1222 + described in <xref linkend="sec:mq:tools"/>, 31.1223 + particularly 31.1224 + <command>diffstat</command> and <command>filterdiff</command>. 31.1225 + The former will give you a quick idea of what changes your patch 31.1226 + is making, while the latter makes it easy to splice hunks 31.1227 + selectively out of one patch and into another.</para> 31.1228 + 31.1229 + </sect1> 31.1230 + <sect1> 31.1231 + <title>MQ cookbook</title> 31.1232 + 31.1233 + <sect2> 31.1234 + <title>Manage <quote>trivial</quote> patches</title> 31.1235 + 31.1236 + <para id="x_437">Because the overhead of dropping files into a new 31.1237 + Mercurial repository is so low, it makes a lot of sense to 31.1238 + manage patches this way even if you simply want to make a few 31.1239 + changes to a source tarball that you downloaded.</para> 31.1240 + 31.1241 + <para id="x_438">Begin by downloading and unpacking the source tarball, and 31.1242 + turning it into a Mercurial repository.</para> 31.1243 + 31.1244 + &interaction.mq.tarball.download; 31.1245 + 31.1246 + <para id="x_439">Continue by creating a patch stack and making your 31.1247 + changes.</para> 31.1248 + 31.1249 + &interaction.mq.tarball.qinit; 31.1250 + 31.1251 + <para id="x_43a">Let's say a few weeks or months pass, and your package 31.1252 + author releases a new version. First, bring their changes 31.1253 + into the repository.</para> 31.1254 + 31.1255 + &interaction.mq.tarball.newsource; 31.1256 + 31.1257 + <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg 31.1258 + locate</command> above deletes all files in the working 31.1259 + directory, so that <command role="hg-cmd">hg 31.1260 + commit</command>'s <option 31.1261 + role="hg-opt-commit">--addremove</option> option can 31.1262 + actually tell which files have really been removed in the 31.1263 + newer version of the source.</para> 31.1264 + 31.1265 + <para id="x_43c">Finally, you can apply your patches on top of the new 31.1266 + tree.</para> 31.1267 + 31.1268 + &interaction.mq.tarball.repush; 31.1269 + </sect2> 31.1270 + 31.1271 + <sect2 id="sec:mq:combine"> 31.1272 + <title>Combining entire patches</title> 31.1273 + 31.1274 + <para id="x_43d">MQ provides a command, <command 31.1275 + role="hg-ext-mq">qfold</command> that lets you combine 31.1276 + entire patches. This <quote>folds</quote> the patches you 31.1277 + name, in the order you name them, into the topmost applied 31.1278 + patch, and concatenates their descriptions onto the end of its 31.1279 + description. The patches that you fold must be unapplied 31.1280 + before you fold them.</para> 31.1281 + 31.1282 + <para id="x_43e">The order in which you fold patches matters. If your 31.1283 + topmost applied patch is <literal>foo</literal>, and you 31.1284 + <command role="hg-ext-mq">qfold</command> 31.1285 + <literal>bar</literal> and <literal>quux</literal> into it, 31.1286 + you will end up with a patch that has the same effect as if 31.1287 + you applied first <literal>foo</literal>, then 31.1288 + <literal>bar</literal>, followed by 31.1289 + <literal>quux</literal>.</para> 31.1290 + </sect2> 31.1291 + 31.1292 + <sect2> 31.1293 + <title>Merging part of one patch into another</title> 31.1294 + 31.1295 + <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into 31.1296 + another is more difficult than combining entire 31.1297 + patches.</para> 31.1298 + 31.1299 + <para id="x_440">If you want to move changes to entire files, you can use 31.1300 + <command>filterdiff</command>'s <option 31.1301 + role="cmd-opt-filterdiff">-i</option> and <option 31.1302 + role="cmd-opt-filterdiff">-x</option> options to choose the 31.1303 + modifications to snip out of one patch, concatenating its 31.1304 + output onto the end of the patch you want to merge into. You 31.1305 + usually won't need to modify the patch you've merged the 31.1306 + changes from. Instead, MQ will report some rejected hunks 31.1307 + when you <command role="hg-ext-mq">qpush</command> it (from 31.1308 + the hunks you moved into the other patch), and you can simply 31.1309 + <command role="hg-ext-mq">qrefresh</command> the patch to drop 31.1310 + the duplicate hunks.</para> 31.1311 + 31.1312 + <para id="x_441">If you have a patch that has multiple hunks modifying a 31.1313 + file, and you only want to move a few of those hunks, the job 31.1314 + becomes more messy, but you can still partly automate it. Use 31.1315 + <command>lsdiff -nvv</command> to print some metadata about 31.1316 + the patch.</para> 31.1317 + 31.1318 + &interaction.mq.tools.lsdiff; 31.1319 + 31.1320 + <para id="x_442">This command prints three different kinds of 31.1321 + number:</para> 31.1322 + <itemizedlist> 31.1323 + <listitem><para id="x_443">(in the first column) a <emphasis>file 31.1324 + number</emphasis> to identify each file modified in the 31.1325 + patch;</para> 31.1326 + </listitem> 31.1327 + <listitem><para id="x_444">(on the next line, indented) the line number 31.1328 + within a modified file where a hunk starts; and</para> 31.1329 + </listitem> 31.1330 + <listitem><para id="x_445">(on the same line) a <emphasis>hunk 31.1331 + number</emphasis> to identify that hunk.</para> 31.1332 + </listitem></itemizedlist> 31.1333 + 31.1334 + <para id="x_446">You'll have to use some visual inspection, and reading of 31.1335 + the patch, to identify the file and hunk numbers you'll want, 31.1336 + but you can then pass them to to 31.1337 + <command>filterdiff</command>'s <option 31.1338 + role="cmd-opt-filterdiff">--files</option> and <option 31.1339 + role="cmd-opt-filterdiff">--hunks</option> options, to 31.1340 + select exactly the file and hunk you want to extract.</para> 31.1341 + 31.1342 + <para id="x_447">Once you have this hunk, you can concatenate it onto the 31.1343 + end of your destination patch and continue with the remainder 31.1344 + of <xref linkend="sec:mq:combine"/>.</para> 31.1345 + 31.1346 + </sect2> 31.1347 + </sect1> 31.1348 + <sect1> 31.1349 + <title>Differences between quilt and MQ</title> 31.1350 + 31.1351 + <para id="x_448">If you are already familiar with quilt, MQ provides a 31.1352 + similar command set. There are a few differences in the way 31.1353 + that it works.</para> 31.1354 + 31.1355 + <para id="x_449">You will already have noticed that most quilt commands have 31.1356 + MQ counterparts that simply begin with a 31.1357 + <quote><literal>q</literal></quote>. The exceptions are quilt's 31.1358 + <literal>add</literal> and <literal>remove</literal> commands, 31.1359 + the counterparts for which are the normal Mercurial <command 31.1360 + role="hg-cmd">hg add</command> and <command role="hg-cmd">hg 31.1361 + remove</command> commands. There is no MQ equivalent of the 31.1362 + quilt <literal>edit</literal> command.</para> 31.1363 + 31.1364 + </sect1> 31.1365 +</chapter> 31.1366 + 31.1367 +<!-- 31.1368 +local variables: 31.1369 +sgml-parent-document: ("00book.xml" "book" "chapter") 31.1370 +end: 31.1371 +-->
32.1 --- a/en/ch13-hgext.xml Sat Apr 18 11:52:33 2009 +0800 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,554 +0,0 @@ 32.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 32.5 - 32.6 -<chapter id="chap:hgext"> 32.7 - <?dbhtml filename="adding-functionality-with-extensions.html"?> 32.8 - <title>Adding functionality with extensions</title> 32.9 - 32.10 - <para id="x_4fe">While the core of Mercurial is quite complete from a 32.11 - functionality standpoint, it's deliberately shorn of fancy 32.12 - features. This approach of preserving simplicity keeps the 32.13 - software easy to deal with for both maintainers and users.</para> 32.14 - 32.15 - <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible 32.16 - command set: you can add features to it as 32.17 - <emphasis>extensions</emphasis> (sometimes known as 32.18 - <emphasis>plugins</emphasis>). We've already discussed a few of 32.19 - these extensions in earlier chapters.</para> 32.20 - <itemizedlist> 32.21 - <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/> 32.22 - covers the <literal role="hg-ext">fetch</literal> extension; 32.23 - this combines pulling new changes and merging them with local 32.24 - changes into a single command, <command 32.25 - role="hg-ext-fetch">fetch</command>.</para> 32.26 - </listitem> 32.27 - <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered 32.28 - several extensions that are useful for hook-related 32.29 - functionality: <literal role="hg-ext">acl</literal> adds 32.30 - access control lists; <literal 32.31 - role="hg-ext">bugzilla</literal> adds integration with the 32.32 - Bugzilla bug tracking system; and <literal 32.33 - role="hg-ext">notify</literal> sends notification emails on 32.34 - new changes.</para> 32.35 - </listitem> 32.36 - <listitem><para id="x_502">The Mercurial Queues patch management extension is 32.37 - so invaluable that it merits two chapters and an appendix all 32.38 - to itself. <xref linkend="chap:mq"/> covers the 32.39 - basics; <xref 32.40 - linkend="chap:mq-collab"/> discusses advanced topics; 32.41 - and <xref linkend="chap:mqref"/> goes into detail on 32.42 - each 32.43 - command.</para> 32.44 - </listitem></itemizedlist> 32.45 - 32.46 - <para id="x_503">In this chapter, we'll cover some of the other extensions that 32.47 - are available for Mercurial, and briefly touch on some of the 32.48 - machinery you'll need to know about if you want to write an 32.49 - extension of your own.</para> 32.50 - <itemizedlist> 32.51 - <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>, 32.52 - we'll discuss the possibility of <emphasis>huge</emphasis> 32.53 - performance improvements using the <literal 32.54 - role="hg-ext">inotify</literal> extension.</para> 32.55 - </listitem></itemizedlist> 32.56 - 32.57 - <sect1 id="sec:hgext:inotify"> 32.58 - <title>Improve performance with the <literal 32.59 - role="hg-ext">inotify</literal> extension</title> 32.60 - 32.61 - <para id="x_505">Are you interested in having some of the most common 32.62 - Mercurial operations run as much as a hundred times faster? 32.63 - Read on!</para> 32.64 - 32.65 - <para id="x_506">Mercurial has great performance under normal circumstances. 32.66 - For example, when you run the <command role="hg-cmd">hg 32.67 - status</command> command, Mercurial has to scan almost every 32.68 - directory and file in your repository so that it can display 32.69 - file status. Many other Mercurial commands need to do the same 32.70 - work behind the scenes; for example, the <command 32.71 - role="hg-cmd">hg diff</command> command uses the status 32.72 - machinery to avoid doing an expensive comparison operation on 32.73 - files that obviously haven't changed.</para> 32.74 - 32.75 - <para id="x_507">Because obtaining file status is crucial to good 32.76 - performance, the authors of Mercurial have optimised this code 32.77 - to within an inch of its life. However, there's no avoiding the 32.78 - fact that when you run <command role="hg-cmd">hg 32.79 - status</command>, Mercurial is going to have to perform at 32.80 - least one expensive system call for each managed file to 32.81 - determine whether it's changed since the last time Mercurial 32.82 - checked. For a sufficiently large repository, this can take a 32.83 - long time.</para> 32.84 - 32.85 - <para id="x_508">To put a number on the magnitude of this effect, I created a 32.86 - repository containing 150,000 managed files. I timed <command 32.87 - role="hg-cmd">hg status</command> as taking ten seconds to 32.88 - run, even when <emphasis>none</emphasis> of those files had been 32.89 - modified.</para> 32.90 - 32.91 - <para id="x_509">Many modern operating systems contain a file notification 32.92 - facility. If a program signs up to an appropriate service, the 32.93 - operating system will notify it every time a file of interest is 32.94 - created, modified, or deleted. On Linux systems, the kernel 32.95 - component that does this is called 32.96 - <literal>inotify</literal>.</para> 32.97 - 32.98 - <para id="x_50a">Mercurial's <literal role="hg-ext">inotify</literal> 32.99 - extension talks to the kernel's <literal>inotify</literal> 32.100 - component to optimise <command role="hg-cmd">hg status</command> 32.101 - commands. The extension has two components. A daemon sits in 32.102 - the background and receives notifications from the 32.103 - <literal>inotify</literal> subsystem. It also listens for 32.104 - connections from a regular Mercurial command. The extension 32.105 - modifies Mercurial's behavior so that instead of scanning the 32.106 - filesystem, it queries the daemon. Since the daemon has perfect 32.107 - information about the state of the repository, it can respond 32.108 - with a result instantaneously, avoiding the need to scan every 32.109 - directory and file in the repository.</para> 32.110 - 32.111 - <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as 32.112 - taking to run <command role="hg-cmd">hg status</command> on a 32.113 - 150,000 file repository. With the <literal 32.114 - role="hg-ext">inotify</literal> extension enabled, the time 32.115 - dropped to 0.1 seconds, a factor of <emphasis>one 32.116 - hundred</emphasis> faster.</para> 32.117 - 32.118 - <para id="x_50c">Before we continue, please pay attention to some 32.119 - caveats.</para> 32.120 - <itemizedlist> 32.121 - <listitem><para id="x_50d">The <literal role="hg-ext">inotify</literal> 32.122 - extension is Linux-specific. Because it interfaces directly 32.123 - to the Linux kernel's <literal>inotify</literal> subsystem, 32.124 - it does not work on other operating systems.</para> 32.125 - </listitem> 32.126 - <listitem><para id="x_50e">It should work on any Linux distribution that 32.127 - was released after early 2005. Older distributions are 32.128 - likely to have a kernel that lacks 32.129 - <literal>inotify</literal>, or a version of 32.130 - <literal>glibc</literal> that does not have the necessary 32.131 - interfacing support.</para> 32.132 - </listitem> 32.133 - <listitem><para id="x_50f">Not all filesystems are suitable for use with 32.134 - the <literal role="hg-ext">inotify</literal> extension. 32.135 - Network filesystems such as NFS are a non-starter, for 32.136 - example, particularly if you're running Mercurial on several 32.137 - systems, all mounting the same network filesystem. The 32.138 - kernel's <literal>inotify</literal> system has no way of 32.139 - knowing about changes made on another system. Most local 32.140 - filesystems (e.g. ext3, XFS, ReiserFS) should work 32.141 - fine.</para> 32.142 - </listitem></itemizedlist> 32.143 - 32.144 - <para id="x_510">The <literal role="hg-ext">inotify</literal> extension is 32.145 - not yet shipped with Mercurial as of May 2007, so it's a little 32.146 - more involved to set up than other extensions. But the 32.147 - performance improvement is worth it!</para> 32.148 - 32.149 - <para id="x_511">The extension currently comes in two parts: a set of patches 32.150 - to the Mercurial source code, and a library of Python bindings 32.151 - to the <literal>inotify</literal> subsystem.</para> 32.152 - <note> 32.153 - <para id="x_512"> There are <emphasis>two</emphasis> Python 32.154 - <literal>inotify</literal> binding libraries. One of them is 32.155 - called <literal>pyinotify</literal>, and is packaged by some 32.156 - Linux distributions as <literal>python-inotify</literal>. 32.157 - This is <emphasis>not</emphasis> the one you'll need, as it is 32.158 - too buggy and inefficient to be practical.</para> 32.159 - </note> 32.160 - <para id="x_513">To get going, it's best to already have a functioning copy 32.161 - of Mercurial installed.</para> 32.162 - <note> 32.163 - <para id="x_514"> If you follow the instructions below, you'll be 32.164 - <emphasis>replacing</emphasis> and overwriting any existing 32.165 - installation of Mercurial that you might already have, using 32.166 - the latest <quote>bleeding edge</quote> Mercurial code. Don't 32.167 - say you weren't warned!</para> 32.168 - </note> 32.169 - <orderedlist> 32.170 - <listitem><para id="x_515">Clone the Python <literal>inotify</literal> 32.171 - binding repository. Build and install it.</para> 32.172 - <programlisting>hg clone http://hg.kublai.com/python/inotify 32.173 -cd inotify 32.174 -python setup.py build --force 32.175 -sudo python setup.py install --skip-build</programlisting> 32.176 - </listitem> 32.177 - <listitem><para id="x_516">Clone the <filename 32.178 - class="directory">crew</filename> Mercurial repository. 32.179 - Clone the <literal role="hg-ext">inotify</literal> patch 32.180 - repository so that Mercurial Queues will be able to apply 32.181 - patches to your cope of the <filename 32.182 - class="directory">crew</filename> repository.</para> 32.183 - <programlisting>hg clone http://hg.intevation.org/mercurial/crew 32.184 -hg clone crew inotify 32.185 -hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting> 32.186 - </listitem> 32.187 - <listitem><para id="x_517">Make sure that you have the Mercurial Queues 32.188 - extension, <literal role="hg-ext">mq</literal>, enabled. If 32.189 - you've never used MQ, read <xref 32.190 - linkend="sec:mq:start"/> to get started 32.191 - quickly.</para> 32.192 - </listitem> 32.193 - <listitem><para id="x_518">Go into the <filename 32.194 - class="directory">inotify</filename> repo, and apply all 32.195 - of the <literal role="hg-ext">inotify</literal> patches 32.196 - using the <option role="hg-ext-mq-cmd-qpush-opt">hg 32.197 - -a</option> option to the <command 32.198 - role="hg-ext-mq">qpush</command> command.</para> 32.199 - <programlisting>cd inotify 32.200 -hg qpush -a</programlisting> 32.201 - </listitem> 32.202 - <listitem><para id="x_519"> If you get an error message from <command 32.203 - role="hg-ext-mq">qpush</command>, you should not continue. 32.204 - Instead, ask for help.</para> 32.205 - </listitem> 32.206 - <listitem><para id="x_51a">Build and install the patched version of 32.207 - Mercurial.</para> 32.208 - <programlisting>python setup.py build --force 32.209 -sudo python setup.py install --skip-build</programlisting> 32.210 - </listitem> 32.211 - </orderedlist> 32.212 - <para id="x_51b">Once you've build a suitably patched version of Mercurial, 32.213 - all you need to do to enable the <literal 32.214 - role="hg-ext">inotify</literal> extension is add an entry to 32.215 - your <filename role="special">~/.hgrc</filename>.</para> 32.216 - <programlisting>[extensions] inotify =</programlisting> 32.217 - <para id="x_51c">When the <literal role="hg-ext">inotify</literal> extension 32.218 - is enabled, Mercurial will automatically and transparently start 32.219 - the status daemon the first time you run a command that needs 32.220 - status in a repository. It runs one status daemon per 32.221 - repository.</para> 32.222 - 32.223 - <para id="x_51d">The status daemon is started silently, and runs in the 32.224 - background. If you look at a list of running processes after 32.225 - you've enabled the <literal role="hg-ext">inotify</literal> 32.226 - extension and run a few commands in different repositories, 32.227 - you'll thus see a few <literal>hg</literal> processes sitting 32.228 - around, waiting for updates from the kernel and queries from 32.229 - Mercurial.</para> 32.230 - 32.231 - <para id="x_51e">The first time you run a Mercurial command in a repository 32.232 - when you have the <literal role="hg-ext">inotify</literal> 32.233 - extension enabled, it will run with about the same performance 32.234 - as a normal Mercurial command. This is because the status 32.235 - daemon needs to perform a normal status scan so that it has a 32.236 - baseline against which to apply later updates from the kernel. 32.237 - However, <emphasis>every</emphasis> subsequent command that does 32.238 - any kind of status check should be noticeably faster on 32.239 - repositories of even fairly modest size. Better yet, the bigger 32.240 - your repository is, the greater a performance advantage you'll 32.241 - see. The <literal role="hg-ext">inotify</literal> daemon makes 32.242 - status operations almost instantaneous on repositories of all 32.243 - sizes!</para> 32.244 - 32.245 - <para id="x_51f">If you like, you can manually start a status daemon using 32.246 - the <command role="hg-ext-inotify">inserve</command> command. 32.247 - This gives you slightly finer control over how the daemon ought 32.248 - to run. This command will of course only be available when the 32.249 - <literal role="hg-ext">inotify</literal> extension is 32.250 - enabled.</para> 32.251 - 32.252 - <para id="x_520">When you're using the <literal 32.253 - role="hg-ext">inotify</literal> extension, you should notice 32.254 - <emphasis>no difference at all</emphasis> in Mercurial's 32.255 - behavior, with the sole exception of status-related commands 32.256 - running a whole lot faster than they used to. You should 32.257 - specifically expect that commands will not print different 32.258 - output; neither should they give different results. If either of 32.259 - these situations occurs, please report a bug.</para> 32.260 - 32.261 - </sect1> 32.262 - <sect1 id="sec:hgext:extdiff"> 32.263 - <title>Flexible diff support with the <literal 32.264 - role="hg-ext">extdiff</literal> extension</title> 32.265 - 32.266 - <para id="x_521">Mercurial's built-in <command role="hg-cmd">hg 32.267 - diff</command> command outputs plaintext unified diffs.</para> 32.268 - 32.269 - &interaction.extdiff.diff; 32.270 - 32.271 - <para id="x_522">If you would like to use an external tool to display 32.272 - modifications, you'll want to use the <literal 32.273 - role="hg-ext">extdiff</literal> extension. This will let you 32.274 - use, for example, a graphical diff tool.</para> 32.275 - 32.276 - <para id="x_523">The <literal role="hg-ext">extdiff</literal> extension is 32.277 - bundled with Mercurial, so it's easy to set up. In the <literal 32.278 - role="rc-extensions">extensions</literal> section of your 32.279 - <filename role="special">~/.hgrc</filename>, simply add a 32.280 - one-line entry to enable the extension.</para> 32.281 - <programlisting>[extensions] 32.282 -extdiff =</programlisting> 32.283 - <para id="x_524">This introduces a command named <command 32.284 - role="hg-ext-extdiff">extdiff</command>, which by default uses 32.285 - your system's <command>diff</command> command to generate a 32.286 - unified diff in the same form as the built-in <command 32.287 - role="hg-cmd">hg diff</command> command.</para> 32.288 - 32.289 - &interaction.extdiff.extdiff; 32.290 - 32.291 - <para id="x_525">The result won't be exactly the same as with the built-in 32.292 - <command role="hg-cmd">hg diff</command> variations, because the 32.293 - output of <command>diff</command> varies from one system to 32.294 - another, even when passed the same options.</para> 32.295 - 32.296 - <para id="x_526">As the <quote><literal>making snapshot</literal></quote> 32.297 - lines of output above imply, the <command 32.298 - role="hg-ext-extdiff">extdiff</command> command works by 32.299 - creating two snapshots of your source tree. The first snapshot 32.300 - is of the source revision; the second, of the target revision or 32.301 - working directory. The <command 32.302 - role="hg-ext-extdiff">extdiff</command> command generates 32.303 - these snapshots in a temporary directory, passes the name of 32.304 - each directory to an external diff viewer, then deletes the 32.305 - temporary directory. For efficiency, it only snapshots the 32.306 - directories and files that have changed between the two 32.307 - revisions.</para> 32.308 - 32.309 - <para id="x_527">Snapshot directory names have the same base name as your 32.310 - repository. If your repository path is <filename 32.311 - class="directory">/quux/bar/foo</filename>, then <filename 32.312 - class="directory">foo</filename> will be the name of each 32.313 - snapshot directory. Each snapshot directory name has its 32.314 - changeset ID appended, if appropriate. If a snapshot is of 32.315 - revision <literal>a631aca1083f</literal>, the directory will be 32.316 - named <filename class="directory">foo.a631aca1083f</filename>. 32.317 - A snapshot of the working directory won't have a changeset ID 32.318 - appended, so it would just be <filename 32.319 - class="directory">foo</filename> in this example. To see what 32.320 - this looks like in practice, look again at the <command 32.321 - role="hg-ext-extdiff">extdiff</command> example above. Notice 32.322 - that the diff has the snapshot directory names embedded in its 32.323 - header.</para> 32.324 - 32.325 - <para id="x_528">The <command role="hg-ext-extdiff">extdiff</command> command 32.326 - accepts two important options. The <option 32.327 - role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option 32.328 - lets you choose a program to view differences with, instead of 32.329 - <command>diff</command>. With the <option 32.330 - role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option, 32.331 - you can change the options that <command 32.332 - role="hg-ext-extdiff">extdiff</command> passes to the program 32.333 - (by default, these options are 32.334 - <quote><literal>-Npru</literal></quote>, which only make sense 32.335 - if you're running <command>diff</command>). In other respects, 32.336 - the <command role="hg-ext-extdiff">extdiff</command> command 32.337 - acts similarly to the built-in <command role="hg-cmd">hg 32.338 - diff</command> command: you use the same option names, syntax, 32.339 - and arguments to specify the revisions you want, the files you 32.340 - want, and so on.</para> 32.341 - 32.342 - <para id="x_529">As an example, here's how to run the normal system 32.343 - <command>diff</command> command, getting it to generate context 32.344 - diffs (using the <option role="cmd-opt-diff">-c</option> option) 32.345 - instead of unified diffs, and five lines of context instead of 32.346 - the default three (passing <literal>5</literal> as the argument 32.347 - to the <option role="cmd-opt-diff">-C</option> option).</para> 32.348 - 32.349 - &interaction.extdiff.extdiff-ctx; 32.350 - 32.351 - <para id="x_52a">Launching a visual diff tool is just as easy. Here's how to 32.352 - launch the <command>kdiff3</command> viewer.</para> 32.353 - <programlisting>hg extdiff -p kdiff3 -o</programlisting> 32.354 - 32.355 - <para id="x_52b">If your diff viewing command can't deal with directories, 32.356 - you can easily work around this with a little scripting. For an 32.357 - example of such scripting in action with the <literal 32.358 - role="hg-ext">mq</literal> extension and the 32.359 - <command>interdiff</command> command, see <xref 32.360 - linkend="mq-collab:tips:interdiff"/>.</para> 32.361 - 32.362 - <sect2> 32.363 - <title>Defining command aliases</title> 32.364 - 32.365 - <para id="x_52c">It can be cumbersome to remember the options to both the 32.366 - <command role="hg-ext-extdiff">extdiff</command> command and 32.367 - the diff viewer you want to use, so the <literal 32.368 - role="hg-ext">extdiff</literal> extension lets you define 32.369 - <emphasis>new</emphasis> commands that will invoke your diff 32.370 - viewer with exactly the right options.</para> 32.371 - 32.372 - <para id="x_52d">All you need to do is edit your <filename 32.373 - role="special">~/.hgrc</filename>, and add a section named 32.374 - <literal role="rc-extdiff">extdiff</literal>. Inside this 32.375 - section, you can define multiple commands. Here's how to add 32.376 - a <literal>kdiff3</literal> command. Once you've defined 32.377 - this, you can type <quote><literal>hg kdiff3</literal></quote> 32.378 - and the <literal role="hg-ext">extdiff</literal> extension 32.379 - will run <command>kdiff3</command> for you.</para> 32.380 - <programlisting>[extdiff] 32.381 -cmd.kdiff3 =</programlisting> 32.382 - <para id="x_52e">If you leave the right hand side of the definition empty, 32.383 - as above, the <literal role="hg-ext">extdiff</literal> 32.384 - extension uses the name of the command you defined as the name 32.385 - of the external program to run. But these names don't have to 32.386 - be the same. Here, we define a command named 32.387 - <quote><literal>hg wibble</literal></quote>, which runs 32.388 - <command>kdiff3</command>.</para> 32.389 - <programlisting>[extdiff] 32.390 - cmd.wibble = kdiff3</programlisting> 32.391 - 32.392 - <para id="x_52f">You can also specify the default options that you want to 32.393 - invoke your diff viewing program with. The prefix to use is 32.394 - <quote><literal>opts.</literal></quote>, followed by the name 32.395 - of the command to which the options apply. This example 32.396 - defines a <quote><literal>hg vimdiff</literal></quote> command 32.397 - that runs the <command>vim</command> editor's 32.398 - <literal>DirDiff</literal> extension.</para> 32.399 - <programlisting>[extdiff] 32.400 - cmd.vimdiff = vim 32.401 -opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting> 32.402 - 32.403 - </sect2> 32.404 - </sect1> 32.405 - <sect1 id="sec:hgext:transplant"> 32.406 - <title>Cherrypicking changes with the <literal 32.407 - role="hg-ext">transplant</literal> extension</title> 32.408 - 32.409 - <para id="x_530">Need to have a long chat with Brendan about this.</para> 32.410 - 32.411 - </sect1> 32.412 - <sect1 id="sec:hgext:patchbomb"> 32.413 - <title>Send changes via email with the <literal 32.414 - role="hg-ext">patchbomb</literal> extension</title> 32.415 - 32.416 - <para id="x_531">Many projects have a culture of <quote>change 32.417 - review</quote>, in which people send their modifications to a 32.418 - mailing list for others to read and comment on before they 32.419 - commit the final version to a shared repository. Some projects 32.420 - have people who act as gatekeepers; they apply changes from 32.421 - other people to a repository to which those others don't have 32.422 - access.</para> 32.423 - 32.424 - <para id="x_532">Mercurial makes it easy to send changes over email for 32.425 - review or application, via its <literal 32.426 - role="hg-ext">patchbomb</literal> extension. The extension is 32.427 - so named because changes are formatted as patches, and it's usual 32.428 - to send one changeset per email message. Sending a long series 32.429 - of changes by email is thus much like <quote>bombing</quote> the 32.430 - recipient's inbox, hence <quote>patchbomb</quote>.</para> 32.431 - 32.432 - <para id="x_533">As usual, the basic configuration of the <literal 32.433 - role="hg-ext">patchbomb</literal> extension takes just one or 32.434 - two lines in your <filename role="special"> 32.435 - /.hgrc</filename>.</para> 32.436 - <programlisting>[extensions] 32.437 -patchbomb =</programlisting> 32.438 - <para id="x_534">Once you've enabled the extension, you will have a new 32.439 - command available, named <command 32.440 - role="hg-ext-patchbomb">email</command>.</para> 32.441 - 32.442 - <para id="x_535">The safest and best way to invoke the <command 32.443 - role="hg-ext-patchbomb">email</command> command is to 32.444 - <emphasis>always</emphasis> run it first with the <option 32.445 - role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option. 32.446 - This will show you what the command <emphasis>would</emphasis> 32.447 - send, without actually sending anything. Once you've had a 32.448 - quick glance over the changes and verified that you are sending 32.449 - the right ones, you can rerun the same command, with the <option 32.450 - role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option 32.451 - removed.</para> 32.452 - 32.453 - <para id="x_536">The <command role="hg-ext-patchbomb">email</command> command 32.454 - accepts the same kind of revision syntax as every other 32.455 - Mercurial command. For example, this command will send every 32.456 - revision between 7 and <literal>tip</literal>, inclusive.</para> 32.457 - <programlisting>hg email -n 7:tip</programlisting> 32.458 - <para id="x_537">You can also specify a <emphasis>repository</emphasis> to 32.459 - compare with. If you provide a repository but no revisions, the 32.460 - <command role="hg-ext-patchbomb">email</command> command will 32.461 - send all revisions in the local repository that are not present 32.462 - in the remote repository. If you additionally specify revisions 32.463 - or a branch name (the latter using the <option 32.464 - role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option), 32.465 - this will constrain the revisions sent.</para> 32.466 - 32.467 - <para id="x_538">It's perfectly safe to run the <command 32.468 - role="hg-ext-patchbomb">email</command> command without the 32.469 - names of the people you want to send to: if you do this, it will 32.470 - just prompt you for those values interactively. (If you're 32.471 - using a Linux or Unix-like system, you should have enhanced 32.472 - <literal>readline</literal>-style editing capabilities when 32.473 - entering those headers, too, which is useful.)</para> 32.474 - 32.475 - <para id="x_539">When you are sending just one revision, the <command 32.476 - role="hg-ext-patchbomb">email</command> command will by 32.477 - default use the first line of the changeset description as the 32.478 - subject of the single email message it sends.</para> 32.479 - 32.480 - <para id="x_53a">If you send multiple revisions, the <command 32.481 - role="hg-ext-patchbomb">email</command> command will usually 32.482 - send one message per changeset. It will preface the series with 32.483 - an introductory message, in which you should describe the 32.484 - purpose of the series of changes you're sending.</para> 32.485 - 32.486 - <sect2> 32.487 - <title>Changing the behavior of patchbombs</title> 32.488 - 32.489 - <para id="x_53b">Not every project has exactly the same conventions for 32.490 - sending changes in email; the <literal 32.491 - role="hg-ext">patchbomb</literal> extension tries to 32.492 - accommodate a number of variations through command line 32.493 - options.</para> 32.494 - <itemizedlist> 32.495 - <listitem><para id="x_53c">You can write a subject for the introductory 32.496 - message on the command line using the <option 32.497 - role="hg-ext-patchbomb-cmd-email-opt">hg -s</option> 32.498 - option. This takes one argument, the text of the subject 32.499 - to use.</para> 32.500 - </listitem> 32.501 - <listitem><para id="x_53d">To change the email address from which the 32.502 - messages originate, use the <option 32.503 - role="hg-ext-patchbomb-cmd-email-opt">hg -f</option> 32.504 - option. This takes one argument, the email address to 32.505 - use.</para> 32.506 - </listitem> 32.507 - <listitem><para id="x_53e">The default behavior is to send unified diffs 32.508 - (see <xref linkend="sec:mq:patch"/> for a 32.509 - description of the 32.510 - format), one per message. You can send a binary bundle 32.511 - instead with the <option 32.512 - role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> 32.513 - option.</para> 32.514 - </listitem> 32.515 - <listitem><para id="x_53f">Unified diffs are normally prefaced with a 32.516 - metadata header. You can omit this, and send unadorned 32.517 - diffs, with the <option 32.518 - role="hg-ext-patchbomb-cmd-email-opt">hg 32.519 - --plain</option> option.</para> 32.520 - </listitem> 32.521 - <listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>, 32.522 - in the same body part as the description of a patch. This 32.523 - makes it easiest for the largest number of readers to 32.524 - quote and respond to parts of a diff, as some mail clients 32.525 - will only quote the first MIME body part in a message. If 32.526 - you'd prefer to send the description and the diff in 32.527 - separate body parts, use the <option 32.528 - role="hg-ext-patchbomb-cmd-email-opt">hg -a</option> 32.529 - option.</para> 32.530 - </listitem> 32.531 - <listitem><para id="x_541">Instead of sending mail messages, you can 32.532 - write them to an <literal>mbox</literal>-format mail 32.533 - folder using the <option 32.534 - role="hg-ext-patchbomb-cmd-email-opt">hg -m</option> 32.535 - option. That option takes one argument, the name of the 32.536 - file to write to.</para> 32.537 - </listitem> 32.538 - <listitem><para id="x_542">If you would like to add a 32.539 - <command>diffstat</command>-format summary to each patch, 32.540 - and one to the introductory message, use the <option 32.541 - role="hg-ext-patchbomb-cmd-email-opt">hg -d</option> 32.542 - option. The <command>diffstat</command> command displays 32.543 - a table containing the name of each file patched, the 32.544 - number of lines affected, and a histogram showing how much 32.545 - each file is modified. This gives readers a qualitative 32.546 - glance at how complex a patch is.</para> 32.547 - </listitem></itemizedlist> 32.548 - 32.549 - </sect2> 32.550 - </sect1> 32.551 -</chapter> 32.552 - 32.553 -<!-- 32.554 -local variables: 32.555 -sgml-parent-document: ("00book.xml" "book" "chapter") 32.556 -end: 32.557 --->
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/en/ch13-mq-collab.xml Thu May 21 14:16:17 2009 +0800 33.3 @@ -0,0 +1,525 @@ 33.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 33.5 + 33.6 +<chapter id="chap:mq-collab"> 33.7 + <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?> 33.8 + <title>Advanced uses of Mercurial Queues</title> 33.9 + 33.10 + <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial 33.11 + Queues, use of a little discipline and some of MQ's less 33.12 + frequently used capabilities makes it possible to work in 33.13 + complicated development environments.</para> 33.14 + 33.15 + <para id="x_15e">In this chapter, I will use as an example a technique I have 33.16 + used to manage the development of an Infiniband device driver for 33.17 + the Linux kernel. The driver in question is large (at least as 33.18 + drivers go), with 25,000 lines of code spread across 35 source 33.19 + files. It is maintained by a small team of developers.</para> 33.20 + 33.21 + <para id="x_15f">While much of the material in this chapter is specific to 33.22 + Linux, the same principles apply to any code base for which you're 33.23 + not the primary owner, and upon which you need to do a lot of 33.24 + development.</para> 33.25 + 33.26 + <sect1> 33.27 + <title>The problem of many targets</title> 33.28 + 33.29 + <para id="x_160">The Linux kernel changes rapidly, and has never been 33.30 + internally stable; developers frequently make drastic changes 33.31 + between releases. This means that a version of the driver that 33.32 + works well with a particular released version of the kernel will 33.33 + not even <emphasis>compile</emphasis> correctly against, 33.34 + typically, any other version.</para> 33.35 + 33.36 + <para id="x_161">To maintain a driver, we have to keep a number of distinct 33.37 + versions of Linux in mind.</para> 33.38 + <itemizedlist> 33.39 + <listitem><para id="x_162">One target is the main Linux kernel development 33.40 + tree. Maintenance of the code is in this case partly shared 33.41 + by other developers in the kernel community, who make 33.42 + <quote>drive-by</quote> modifications to the driver as they 33.43 + develop and refine kernel subsystems.</para> 33.44 + </listitem> 33.45 + <listitem><para id="x_163">We also maintain a number of 33.46 + <quote>backports</quote> to older versions of the Linux 33.47 + kernel, to support the needs of customers who are running 33.48 + older Linux distributions that do not incorporate our 33.49 + drivers. (To <emphasis>backport</emphasis> a piece of code 33.50 + is to modify it to work in an older version of its target 33.51 + environment than the version it was developed for.)</para> 33.52 + </listitem> 33.53 + <listitem><para id="x_164">Finally, we make software releases on a schedule 33.54 + that is necessarily not aligned with those used by Linux 33.55 + distributors and kernel developers, so that we can deliver 33.56 + new features to customers without forcing them to upgrade 33.57 + their entire kernels or distributions.</para> 33.58 + </listitem></itemizedlist> 33.59 + 33.60 + <sect2> 33.61 + <title>Tempting approaches that don't work well</title> 33.62 + 33.63 + <para id="x_165">There are two <quote>standard</quote> ways to maintain a 33.64 + piece of software that has to target many different 33.65 + environments.</para> 33.66 + 33.67 + <para id="x_166">The first is to maintain a number of branches, each 33.68 + intended for a single target. The trouble with this approach 33.69 + is that you must maintain iron discipline in the flow of 33.70 + changes between repositories. A new feature or bug fix must 33.71 + start life in a <quote>pristine</quote> repository, then 33.72 + percolate out to every backport repository. Backport changes 33.73 + are more limited in the branches they should propagate to; a 33.74 + backport change that is applied to a branch where it doesn't 33.75 + belong will probably stop the driver from compiling.</para> 33.76 + 33.77 + <para id="x_167">The second is to maintain a single source tree filled with 33.78 + conditional statements that turn chunks of code on or off 33.79 + depending on the intended target. Because these 33.80 + <quote>ifdefs</quote> are not allowed in the Linux kernel 33.81 + tree, a manual or automatic process must be followed to strip 33.82 + them out and yield a clean tree. A code base maintained in 33.83 + this fashion rapidly becomes a rat's nest of conditional 33.84 + blocks that are difficult to understand and maintain.</para> 33.85 + 33.86 + <para id="x_168">Neither of these approaches is well suited to a situation 33.87 + where you don't <quote>own</quote> the canonical copy of a 33.88 + source tree. In the case of a Linux driver that is 33.89 + distributed with the standard kernel, Linus's tree contains 33.90 + the copy of the code that will be treated by the world as 33.91 + canonical. The upstream version of <quote>my</quote> driver 33.92 + can be modified by people I don't know, without me even 33.93 + finding out about it until after the changes show up in 33.94 + Linus's tree.</para> 33.95 + 33.96 + <para id="x_169">These approaches have the added weakness of making it 33.97 + difficult to generate well-formed patches to submit 33.98 + upstream.</para> 33.99 + 33.100 + <para id="x_16a">In principle, Mercurial Queues seems like a good candidate 33.101 + to manage a development scenario such as the above. While 33.102 + this is indeed the case, MQ contains a few added features that 33.103 + make the job more pleasant.</para> 33.104 + 33.105 + </sect2> 33.106 + </sect1> 33.107 + <sect1> 33.108 + <title>Conditionally applying patches with guards</title> 33.109 + 33.110 + <para id="x_16b">Perhaps the best way to maintain sanity with so many targets 33.111 + is to be able to choose specific patches to apply for a given 33.112 + situation. MQ provides a feature called <quote>guards</quote> 33.113 + (which originates with quilt's <literal>guards</literal> 33.114 + command) that does just this. To start off, let's create a 33.115 + simple repository for experimenting in.</para> 33.116 + 33.117 + &interaction.mq.guards.init; 33.118 + 33.119 + <para id="x_16c">This gives us a tiny repository that contains two patches 33.120 + that don't have any dependencies on each other, because they 33.121 + touch different files.</para> 33.122 + 33.123 + <para id="x_16d">The idea behind conditional application is that you can 33.124 + <quote>tag</quote> a patch with a <emphasis>guard</emphasis>, 33.125 + which is simply a text string of your choosing, then tell MQ to 33.126 + select specific guards to use when applying patches. MQ will 33.127 + then either apply, or skip over, a guarded patch, depending on 33.128 + the guards that you have selected.</para> 33.129 + 33.130 + <para id="x_16e">A patch can have an arbitrary number of guards; each one is 33.131 + <emphasis>positive</emphasis> (<quote>apply this patch if this 33.132 + guard is selected</quote>) or <emphasis>negative</emphasis> 33.133 + (<quote>skip this patch if this guard is selected</quote>). A 33.134 + patch with no guards is always applied.</para> 33.135 + 33.136 + </sect1> 33.137 + <sect1> 33.138 + <title>Controlling the guards on a patch</title> 33.139 + 33.140 + <para id="x_16f">The <command role="hg-ext-mq">qguard</command> command lets 33.141 + you determine which guards should apply to a patch, or display 33.142 + the guards that are already in effect. Without any arguments, it 33.143 + displays the guards on the current topmost patch.</para> 33.144 + 33.145 + &interaction.mq.guards.qguard; 33.146 + 33.147 + <para id="x_170">To set a positive guard on a patch, prefix the name of the 33.148 + guard with a <quote><literal>+</literal></quote>.</para> 33.149 + 33.150 + &interaction.mq.guards.qguard.pos; 33.151 + 33.152 + <para id="x_171">To set a negative guard 33.153 + on a patch, prefix the name of the guard with a 33.154 + <quote><literal>-</literal></quote>.</para> 33.155 + 33.156 + &interaction.mq.guards.qguard.neg; 33.157 + 33.158 + <para id="x_74a">Notice that we prefixed the arguments to the <command>hg 33.159 + qguard</command> command with a <literal>--</literal> here, so 33.160 + that Mercurial would not interpret the text 33.161 + <literal>-quux</literal> as an option.</para> 33.162 + 33.163 + <note> 33.164 + <title>Setting vs. modifying</title> 33.165 + 33.166 + <para id="x_172"> The <command role="hg-ext-mq">qguard</command> command 33.167 + <emphasis>sets</emphasis> the guards on a patch; it doesn't 33.168 + <emphasis>modify</emphasis> them. What this means is that if 33.169 + you run <command role="hg-cmd">hg qguard +a +b</command> on a 33.170 + patch, then <command role="hg-cmd">hg qguard +c</command> on 33.171 + the same patch, the <emphasis>only</emphasis> guard that will 33.172 + be set on it afterwards is <literal>+c</literal>.</para> 33.173 + </note> 33.174 + 33.175 + <para id="x_173">Mercurial stores guards in the <filename 33.176 + role="special">series</filename> file; the form in which they 33.177 + are stored is easy both to understand and to edit by hand. (In 33.178 + other words, you don't have to use the <command 33.179 + role="hg-ext-mq">qguard</command> command if you don't want 33.180 + to; it's okay to simply edit the <filename 33.181 + role="special">series</filename> file.)</para> 33.182 + 33.183 + &interaction.mq.guards.series; 33.184 + 33.185 + </sect1> 33.186 + <sect1> 33.187 + <title>Selecting the guards to use</title> 33.188 + 33.189 + <para id="x_174">The <command role="hg-ext-mq">qselect</command> command 33.190 + determines which guards are active at a given time. The effect 33.191 + of this is to determine which patches MQ will apply the next 33.192 + time you run <command role="hg-ext-mq">qpush</command>. It has 33.193 + no other effect; in particular, it doesn't do anything to 33.194 + patches that are already applied.</para> 33.195 + 33.196 + <para id="x_175">With no arguments, the <command 33.197 + role="hg-ext-mq">qselect</command> command lists the guards 33.198 + currently in effect, one per line of output. Each argument is 33.199 + treated as the name of a guard to apply.</para> 33.200 + 33.201 + &interaction.mq.guards.qselect.foo; 33.202 + 33.203 + <para id="x_176">In case you're interested, the currently selected guards are 33.204 + stored in the <filename role="special">guards</filename> file.</para> 33.205 + 33.206 + &interaction.mq.guards.qselect.cat; 33.207 + 33.208 + <para id="x_177">We can see the effect the selected guards have when we run 33.209 + <command role="hg-ext-mq">qpush</command>.</para> 33.210 + 33.211 + &interaction.mq.guards.qselect.qpush; 33.212 + 33.213 + <para id="x_178">A guard cannot start with a 33.214 + <quote><literal>+</literal></quote> or 33.215 + <quote><literal>-</literal></quote> character. The name of a 33.216 + guard must not contain white space, but most other characters 33.217 + are acceptable. If you try to use a guard with an invalid name, 33.218 + MQ will complain:</para> 33.219 + 33.220 + &interaction.mq.guards.qselect.error; 33.221 + 33.222 + <para id="x_179">Changing the selected guards changes the patches that are 33.223 + applied.</para> 33.224 + 33.225 + &interaction.mq.guards.qselect.quux; 33.226 + 33.227 + <para id="x_17a">You can see in the example below that negative guards take 33.228 + precedence over positive guards.</para> 33.229 + 33.230 + &interaction.mq.guards.qselect.foobar; 33.231 + 33.232 + </sect1> 33.233 + <sect1> 33.234 + <title>MQ's rules for applying patches</title> 33.235 + 33.236 + <para id="x_17b">The rules that MQ uses when deciding whether to apply a 33.237 + patch are as follows.</para> 33.238 + <itemizedlist> 33.239 + <listitem><para id="x_17c">A patch that has no guards is always 33.240 + applied.</para> 33.241 + </listitem> 33.242 + <listitem><para id="x_17d">If the patch has any negative guard that matches 33.243 + any currently selected guard, the patch is skipped.</para> 33.244 + </listitem> 33.245 + <listitem><para id="x_17e">If the patch has any positive guard that matches 33.246 + any currently selected guard, the patch is applied.</para> 33.247 + </listitem> 33.248 + <listitem><para id="x_17f">If the patch has positive or negative guards, 33.249 + but none matches any currently selected guard, the patch is 33.250 + skipped.</para> 33.251 + </listitem></itemizedlist> 33.252 + 33.253 + </sect1> 33.254 + <sect1> 33.255 + <title>Trimming the work environment</title> 33.256 + 33.257 + <para id="x_180">In working on the device driver I mentioned earlier, I don't 33.258 + apply the patches to a normal Linux kernel tree. Instead, I use 33.259 + a repository that contains only a snapshot of the source files 33.260 + and headers that are relevant to Infiniband development. This 33.261 + repository is 1% the size of a kernel repository, so it's easier 33.262 + to work with.</para> 33.263 + 33.264 + <para id="x_181">I then choose a <quote>base</quote> version on top of which 33.265 + the patches are applied. This is a snapshot of the Linux kernel 33.266 + tree as of a revision of my choosing. When I take the snapshot, 33.267 + I record the changeset ID from the kernel repository in the 33.268 + commit message. Since the snapshot preserves the 33.269 + <quote>shape</quote> and content of the relevant parts of the 33.270 + kernel tree, I can apply my patches on top of either my tiny 33.271 + repository or a normal kernel tree.</para> 33.272 + 33.273 + <para id="x_182">Normally, the base tree atop which the patches apply should 33.274 + be a snapshot of a very recent upstream tree. This best 33.275 + facilitates the development of patches that can easily be 33.276 + submitted upstream with few or no modifications.</para> 33.277 + 33.278 + </sect1> 33.279 + <sect1> 33.280 + <title>Dividing up the <filename role="special">series</filename> 33.281 + file</title> 33.282 + 33.283 + <para id="x_183">I categorise the patches in the <filename 33.284 + role="special">series</filename> file into a number of logical 33.285 + groups. Each section of like patches begins with a block of 33.286 + comments that describes the purpose of the patches that 33.287 + follow.</para> 33.288 + 33.289 + <para id="x_184">The sequence of patch groups that I maintain follows. The 33.290 + ordering of these groups is important; I'll describe why after I 33.291 + introduce the groups.</para> 33.292 + <itemizedlist> 33.293 + <listitem><para id="x_185">The <quote>accepted</quote> group. Patches that 33.294 + the development team has submitted to the maintainer of the 33.295 + Infiniband subsystem, and which he has accepted, but which 33.296 + are not present in the snapshot that the tiny repository is 33.297 + based on. These are <quote>read only</quote> patches, 33.298 + present only to transform the tree into a similar state as 33.299 + it is in the upstream maintainer's repository.</para> 33.300 + </listitem> 33.301 + <listitem><para id="x_186">The <quote>rework</quote> group. Patches that I 33.302 + have submitted, but that the upstream maintainer has 33.303 + requested modifications to before he will accept 33.304 + them.</para> 33.305 + </listitem> 33.306 + <listitem><para id="x_187">The <quote>pending</quote> group. Patches that 33.307 + I have not yet submitted to the upstream maintainer, but 33.308 + which we have finished working on. These will be <quote>read 33.309 + only</quote> for a while. If the upstream maintainer 33.310 + accepts them upon submission, I'll move them to the end of 33.311 + the <quote>accepted</quote> group. If he requests that I 33.312 + modify any, I'll move them to the beginning of the 33.313 + <quote>rework</quote> group.</para> 33.314 + </listitem> 33.315 + <listitem><para id="x_188">The <quote>in progress</quote> group. Patches 33.316 + that are actively being developed, and should not be 33.317 + submitted anywhere yet.</para> 33.318 + </listitem> 33.319 + <listitem><para id="x_189">The <quote>backport</quote> group. Patches that 33.320 + adapt the source tree to older versions of the kernel 33.321 + tree.</para> 33.322 + </listitem> 33.323 + <listitem><para id="x_18a">The <quote>do not ship</quote> group. Patches 33.324 + that for some reason should never be submitted upstream. 33.325 + For example, one such patch might change embedded driver 33.326 + identification strings to make it easier to distinguish, in 33.327 + the field, between an out-of-tree version of the driver and 33.328 + a version shipped by a distribution vendor.</para> 33.329 + </listitem></itemizedlist> 33.330 + 33.331 + <para id="x_18b">Now to return to the reasons for ordering groups of patches 33.332 + in this way. We would like the lowest patches in the stack to 33.333 + be as stable as possible, so that we will not need to rework 33.334 + higher patches due to changes in context. Putting patches that 33.335 + will never be changed first in the <filename 33.336 + role="special">series</filename> file serves this 33.337 + purpose.</para> 33.338 + 33.339 + <para id="x_18c">We would also like the patches that we know we'll need to 33.340 + modify to be applied on top of a source tree that resembles the 33.341 + upstream tree as closely as possible. This is why we keep 33.342 + accepted patches around for a while.</para> 33.343 + 33.344 + <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote> 33.345 + patches float at the end of the <filename 33.346 + role="special">series</filename> file. The backport patches 33.347 + must be applied on top of all other patches, and the <quote>do 33.348 + not ship</quote> patches might as well stay out of harm's 33.349 + way.</para> 33.350 + 33.351 + </sect1> 33.352 + <sect1> 33.353 + <title>Maintaining the patch series</title> 33.354 + 33.355 + <para id="x_18e">In my work, I use a number of guards to control which 33.356 + patches are to be applied.</para> 33.357 + 33.358 + <itemizedlist> 33.359 + <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with 33.360 + <literal>accepted</literal>. I enable this guard most of 33.361 + the time. When I'm applying the patches on top of a tree 33.362 + where the patches are already present, I can turn this patch 33.363 + off, and the patches that follow it will apply 33.364 + cleanly.</para> 33.365 + </listitem> 33.366 + <listitem><para id="x_190">Patches that are <quote>finished</quote>, but 33.367 + not yet submitted, have no guards. If I'm applying the 33.368 + patch stack to a copy of the upstream tree, I don't need to 33.369 + enable any guards in order to get a reasonably safe source 33.370 + tree.</para> 33.371 + </listitem> 33.372 + <listitem><para id="x_191">Those patches that need reworking before being 33.373 + resubmitted are guarded with 33.374 + <literal>rework</literal>.</para> 33.375 + </listitem> 33.376 + <listitem><para id="x_192">For those patches that are still under 33.377 + development, I use <literal>devel</literal>.</para> 33.378 + </listitem> 33.379 + <listitem><para id="x_193">A backport patch may have several guards, one 33.380 + for each version of the kernel to which it applies. For 33.381 + example, a patch that backports a piece of code to 2.6.9 33.382 + will have a <literal>2.6.9</literal> guard.</para> 33.383 + </listitem></itemizedlist> 33.384 + <para id="x_194">This variety of guards gives me considerable flexibility in 33.385 + determining what kind of source tree I want to end up with. For 33.386 + most situations, the selection of appropriate guards is 33.387 + automated during the build process, but I can manually tune the 33.388 + guards to use for less common circumstances.</para> 33.389 + 33.390 + <sect2> 33.391 + <title>The art of writing backport patches</title> 33.392 + 33.393 + <para id="x_195">Using MQ, writing a backport patch is a simple process. 33.394 + All such a patch has to do is modify a piece of code that uses 33.395 + a kernel feature not present in the older version of the 33.396 + kernel, so that the driver continues to work correctly under 33.397 + that older version.</para> 33.398 + 33.399 + <para id="x_196">A useful goal when writing a good backport patch is to 33.400 + make your code look as if it was written for the older version 33.401 + of the kernel you're targeting. The less obtrusive the patch, 33.402 + the easier it will be to understand and maintain. If you're 33.403 + writing a collection of backport patches to avoid the 33.404 + <quote>rat's nest</quote> effect of lots of 33.405 + <literal>#ifdef</literal>s (hunks of source code that are only 33.406 + used conditionally) in your code, don't introduce 33.407 + version-dependent <literal>#ifdef</literal>s into the patches. 33.408 + Instead, write several patches, each of which makes 33.409 + unconditional changes, and control their application using 33.410 + guards.</para> 33.411 + 33.412 + <para id="x_197">There are two reasons to divide backport patches into a 33.413 + distinct group, away from the <quote>regular</quote> patches 33.414 + whose effects they modify. The first is that intermingling the 33.415 + two makes it more difficult to use a tool like the <literal 33.416 + role="hg-ext">patchbomb</literal> extension to automate the 33.417 + process of submitting the patches to an upstream maintainer. 33.418 + The second is that a backport patch could perturb the context 33.419 + in which a subsequent regular patch is applied, making it 33.420 + impossible to apply the regular patch cleanly 33.421 + <emphasis>without</emphasis> the earlier backport patch 33.422 + already being applied.</para> 33.423 + 33.424 + </sect2> 33.425 + </sect1> 33.426 + <sect1> 33.427 + <title>Useful tips for developing with MQ</title> 33.428 + 33.429 + <sect2> 33.430 + <title>Organising patches in directories</title> 33.431 + 33.432 + <para id="x_198">If you're working on a substantial project with MQ, it's 33.433 + not difficult to accumulate a large number of patches. For 33.434 + example, I have one patch repository that contains over 250 33.435 + patches.</para> 33.436 + 33.437 + <para id="x_199">If you can group these patches into separate logical 33.438 + categories, you can if you like store them in different 33.439 + directories; MQ has no problems with patch names that contain 33.440 + path separators.</para> 33.441 + 33.442 + </sect2> 33.443 + <sect2 id="mq-collab:tips:interdiff"> 33.444 + <title>Viewing the history of a patch</title> 33.445 + 33.446 + <para id="x_19a">If you're developing a set of patches over a long time, 33.447 + it's a good idea to maintain them in a repository, as 33.448 + discussed in <xref linkend="sec:mq:repo"/>. If you do 33.449 + so, you'll quickly 33.450 + discover that using the <command role="hg-cmd">hg 33.451 + diff</command> command to look at the history of changes to 33.452 + a patch is unworkable. This is in part because you're looking 33.453 + at the second derivative of the real code (a diff of a diff), 33.454 + but also because MQ adds noise to the process by modifying 33.455 + time stamps and directory names when it updates a 33.456 + patch.</para> 33.457 + 33.458 + <para id="x_19b">However, you can use the <literal 33.459 + role="hg-ext">extdiff</literal> extension, which is bundled 33.460 + with Mercurial, to turn a diff of two versions of a patch into 33.461 + something readable. To do this, you will need a third-party 33.462 + package called <literal role="package">patchutils</literal> 33.463 + <citation>web:patchutils</citation>. This provides a command 33.464 + named <command>interdiff</command>, which shows the 33.465 + differences between two diffs as a diff. Used on two versions 33.466 + of the same diff, it generates a diff that represents the diff 33.467 + from the first to the second version.</para> 33.468 + 33.469 + <para id="x_19c">You can enable the <literal 33.470 + role="hg-ext">extdiff</literal> extension in the usual way, 33.471 + by adding a line to the <literal 33.472 + role="rc-extensions">extensions</literal> section of your 33.473 + <filename role="special">~/.hgrc</filename>.</para> 33.474 + <programlisting>[extensions] 33.475 +extdiff =</programlisting> 33.476 + <para id="x_19d">The <command>interdiff</command> command expects to be 33.477 + passed the names of two files, but the <literal 33.478 + role="hg-ext">extdiff</literal> extension passes the program 33.479 + it runs a pair of directories, each of which can contain an 33.480 + arbitrary number of files. We thus need a small program that 33.481 + will run <command>interdiff</command> on each pair of files in 33.482 + these two directories. This program is available as <filename 33.483 + role="special">hg-interdiff</filename> in the <filename 33.484 + class="directory">examples</filename> directory of the 33.485 + source code repository that accompanies this book. <!-- 33.486 + &example.hg-interdiff; --></para> 33.487 + 33.488 + <para id="x_19e">With the <filename role="special">hg-interdiff</filename> 33.489 + program in your shell's search path, you can run it as 33.490 + follows, from inside an MQ patch directory:</para> 33.491 + <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting> 33.492 + <para id="x_19f">Since you'll probably want to use this long-winded command 33.493 + a lot, you can get <literal role="hg-ext">hgext</literal> to 33.494 + make it available as a normal Mercurial command, again by 33.495 + editing your <filename 33.496 + role="special">~/.hgrc</filename>.</para> 33.497 + <programlisting>[extdiff] 33.498 +cmd.interdiff = hg-interdiff</programlisting> 33.499 + <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to 33.500 + make an <literal>interdiff</literal> command available, so you 33.501 + can now shorten the previous invocation of <command 33.502 + role="hg-ext-extdiff">extdiff</command> to something a 33.503 + little more wieldy.</para> 33.504 + <programlisting>hg interdiff -r A:B my-change.patch</programlisting> 33.505 + 33.506 + <note> 33.507 + <para id="x_1a1"> The <command>interdiff</command> command works well 33.508 + only if the underlying files against which versions of a 33.509 + patch are generated remain the same. If you create a patch, 33.510 + modify the underlying files, and then regenerate the patch, 33.511 + <command>interdiff</command> may not produce useful 33.512 + output.</para> 33.513 + </note> 33.514 + 33.515 + <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is 33.516 + useful for more than merely improving the presentation of MQ 33.517 + patches. To read more about it, go to <xref 33.518 + linkend="sec:hgext:extdiff"/>.</para> 33.519 + 33.520 + </sect2> 33.521 + </sect1> 33.522 +</chapter> 33.523 + 33.524 +<!-- 33.525 +local variables: 33.526 +sgml-parent-document: ("00book.xml" "book" "chapter") 33.527 +end: 33.528 +-->
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/en/ch14-hgext.xml Thu May 21 14:16:17 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 id="x_4fe">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 id="x_4ff">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 id="x_500"><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 id="x_501">In <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 id="x_502">The Mercurial Queues patch management extension is 34.37 + so invaluable that it merits two chapters and an appendix all 34.38 + to itself. <xref linkend="chap:mq"/> covers the 34.39 + basics; <xref 34.40 + linkend="chap:mq-collab"/> discusses advanced topics; 34.41 + and <xref linkend="chap:mqref"/> goes into detail on 34.42 + each 34.43 + command.</para> 34.44 + </listitem></itemizedlist> 34.45 + 34.46 + <para id="x_503">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 id="x_504">In <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 id="x_505">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 id="x_506">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 id="x_507">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 id="x_508">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 id="x_509">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 id="x_50a">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 behavior 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 id="x_50b">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 id="x_50c">Before we continue, please pay attention to some 34.119 + caveats.</para> 34.120 + <itemizedlist> 34.121 + <listitem><para id="x_50d">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 id="x_50e">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 id="x_50f">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 id="x_510">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 id="x_511">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 id="x_512"> 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 id="x_513">To get going, it's best to already have a functioning copy 34.161 + of Mercurial installed.</para> 34.162 + <note> 34.163 + <para id="x_514"> 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 id="x_515">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 id="x_516">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 id="x_517">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 <xref 34.190 + linkend="sec:mq:start"/> to get started 34.191 + quickly.</para> 34.192 + </listitem> 34.193 + <listitem><para id="x_518">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 id="x_519"> 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 id="x_51a">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 id="x_51b">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 id="x_51c">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 id="x_51d">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 id="x_51e">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 id="x_51f">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 id="x_520">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 + behavior, 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 id="x_521">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 id="x_522">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 id="x_523">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 id="x_524">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 id="x_525">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 id="x_526">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 id="x_527">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 id="x_528">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 id="x_529">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 id="x_52a">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 id="x_52b">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 <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 id="x_52c">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 id="x_52d">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 id="x_52e">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 id="x_52f">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 id="x_530">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 id="x_531">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 id="x_532">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 id="x_533">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 id="x_534">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 id="x_535">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 id="x_536">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 id="x_537">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 id="x_538">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 id="x_539">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 id="x_53a">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 behavior of patchbombs</title> 34.488 + 34.489 + <para id="x_53b">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 id="x_53c">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 id="x_53d">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 id="x_53e">The default behavior is to send unified diffs 34.508 + (see <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 id="x_53f">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 id="x_540">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 id="x_541">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 id="x_542">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/examples/auto-snippets.xml Sat Apr 18 11:52:33 2009 +0800 35.2 +++ b/en/examples/auto-snippets.xml Thu May 21 14:16:17 2009 +0800 35.3 @@ -1,4 +1,5 @@ 35.4 <!ENTITY ch06-apache-config.lst SYSTEM "results/ch06-apache-config.lst.lxo"> 35.5 +<!ENTITY ch09-check_whitespace.py.lst SYSTEM "results/ch09-check_whitespace.py.lst.lxo"> 35.6 <!ENTITY ch10-bugzilla-config.lst SYSTEM "results/ch10-bugzilla-config.lst.lxo"> 35.7 <!ENTITY ch10-notify-config-mail.lst SYSTEM "results/ch10-notify-config-mail.lst.lxo"> 35.8 <!ENTITY ch10-notify-config.lst SYSTEM "results/ch10-notify-config.lst.lxo"> 35.9 @@ -51,6 +52,25 @@ 35.10 <!ENTITY interaction.branching.stable SYSTEM "results/branching.stable.lxo"> 35.11 <!ENTITY interaction.branching.tag SYSTEM "results/branching.tag.lxo"> 35.12 <!ENTITY interaction.branching.update SYSTEM "results/branching.update.lxo"> 35.13 +<!ENTITY interaction.ch01-new.add SYSTEM "results/ch01-new.add.lxo"> 35.14 +<!ENTITY interaction.ch01-new.commit SYSTEM "results/ch01-new.commit.lxo"> 35.15 +<!ENTITY interaction.ch01-new.init SYSTEM "results/ch01-new.init.lxo"> 35.16 +<!ENTITY interaction.ch01-new.ls SYSTEM "results/ch01-new.ls.lxo"> 35.17 +<!ENTITY interaction.ch01-new.ls2 SYSTEM "results/ch01-new.ls2.lxo"> 35.18 +<!ENTITY interaction.ch02-rename.alice SYSTEM "results/ch02-rename.alice.lxo"> 35.19 +<!ENTITY interaction.ch02-rename.bob SYSTEM "results/ch02-rename.bob.lxo"> 35.20 +<!ENTITY interaction.ch02-rename.clone SYSTEM "results/ch02-rename.clone.lxo"> 35.21 +<!ENTITY interaction.ch02-rename.clone2 SYSTEM "results/ch02-rename.clone2.lxo"> 35.22 +<!ENTITY interaction.ch02-rename.init SYSTEM "results/ch02-rename.init.lxo"> 35.23 +<!ENTITY interaction.ch02-rename.merge SYSTEM "results/ch02-rename.merge.lxo"> 35.24 +<!ENTITY interaction.ch02-rename.merge2 SYSTEM "results/ch02-rename.merge2.lxo"> 35.25 +<!ENTITY interaction.ch02-rename.status SYSTEM "results/ch02-rename.status.lxo"> 35.26 +<!ENTITY interaction.ch02-rename.status2 SYSTEM "results/ch02-rename.status2.lxo"> 35.27 +<!ENTITY interaction.ch04-diff.chmod SYSTEM "results/ch04-diff.chmod.lxo"> 35.28 +<!ENTITY interaction.ch04-diff.chmod.git SYSTEM "results/ch04-diff.chmod.git.lxo"> 35.29 +<!ENTITY interaction.ch04-diff.rename.basic SYSTEM "results/ch04-diff.rename.basic.lxo"> 35.30 +<!ENTITY interaction.ch04-diff.rename.git SYSTEM "results/ch04-diff.rename.git.lxo"> 35.31 +<!ENTITY interaction.ch04-rename.basic SYSTEM "results/ch04-rename.basic.lxo"> 35.32 <!ENTITY interaction.ch04-resolve.cifail SYSTEM "results/ch04-resolve.cifail.lxo"> 35.33 <!ENTITY interaction.ch04-resolve.export SYSTEM "results/ch04-resolve.export.lxo"> 35.34 <!ENTITY interaction.ch04-resolve.heads SYSTEM "results/ch04-resolve.heads.lxo"> 35.35 @@ -60,6 +80,13 @@ 35.36 <!ENTITY interaction.ch04-resolve.merge SYSTEM "results/ch04-resolve.merge.lxo"> 35.37 <!ENTITY interaction.ch04-resolve.pull SYSTEM "results/ch04-resolve.pull.lxo"> 35.38 <!ENTITY interaction.ch04-resolve.right SYSTEM "results/ch04-resolve.right.lxo"> 35.39 +<!ENTITY interaction.ch09-hook.ws.better SYSTEM "results/ch09-hook.ws.better.lxo"> 35.40 +<!ENTITY interaction.ch09-hook.ws.simple SYSTEM "results/ch09-hook.ws.simple.lxo"> 35.41 +<!ENTITY interaction.ch10-multiline.go SYSTEM "results/ch10-multiline.go.lxo"> 35.42 +<!ENTITY interaction.ch10-multiline.orig.go SYSTEM "results/ch10-multiline.orig.go.lxo"> 35.43 +<!ENTITY interaction.ch11-qdelete.convert SYSTEM "results/ch11-qdelete.convert.lxo"> 35.44 +<!ENTITY interaction.ch11-qdelete.go SYSTEM "results/ch11-qdelete.go.lxo"> 35.45 +<!ENTITY interaction.ch11-qdelete.import SYSTEM "results/ch11-qdelete.import.lxo"> 35.46 <!ENTITY interaction.cmdref.diff-p SYSTEM "results/cmdref.diff-p.lxo"> 35.47 <!ENTITY interaction.daily.copy.after SYSTEM "results/daily.copy.after.lxo"> 35.48 <!ENTITY interaction.daily.copy.cat SYSTEM "results/daily.copy.cat.lxo"> 35.49 @@ -70,6 +97,19 @@ 35.50 <!ENTITY interaction.daily.copy.dir-src-dest SYSTEM "results/daily.copy.dir-src-dest.lxo"> 35.51 <!ENTITY interaction.daily.copy.init SYSTEM "results/daily.copy.init.lxo"> 35.52 <!ENTITY interaction.daily.copy.merge SYSTEM "results/daily.copy.merge.lxo"> 35.53 +<!ENTITY interaction.daily.copy.orig.after SYSTEM "results/daily.copy.orig.after.lxo"> 35.54 +<!ENTITY interaction.daily.copy.orig.cat SYSTEM "results/daily.copy.orig.cat.lxo"> 35.55 +<!ENTITY interaction.daily.copy.orig.clone SYSTEM "results/daily.copy.orig.clone.lxo"> 35.56 +<!ENTITY interaction.daily.copy.orig.copy SYSTEM "results/daily.copy.orig.copy.lxo"> 35.57 +<!ENTITY interaction.daily.copy.orig.dir-dest SYSTEM "results/daily.copy.orig.dir-dest.lxo"> 35.58 +<!ENTITY interaction.daily.copy.orig.dir-src SYSTEM "results/daily.copy.orig.dir-src.lxo"> 35.59 +<!ENTITY interaction.daily.copy.orig.dir-src-dest SYSTEM "results/daily.copy.orig.dir-src-dest.lxo"> 35.60 +<!ENTITY interaction.daily.copy.orig.init SYSTEM "results/daily.copy.orig.init.lxo"> 35.61 +<!ENTITY interaction.daily.copy.orig.merge SYSTEM "results/daily.copy.orig.merge.lxo"> 35.62 +<!ENTITY interaction.daily.copy.orig.other SYSTEM "results/daily.copy.orig.other.lxo"> 35.63 +<!ENTITY interaction.daily.copy.orig.simple SYSTEM "results/daily.copy.orig.simple.lxo"> 35.64 +<!ENTITY interaction.daily.copy.orig.status SYSTEM "results/daily.copy.orig.status.lxo"> 35.65 +<!ENTITY interaction.daily.copy.orig.status-copy SYSTEM "results/daily.copy.orig.status-copy.lxo"> 35.66 <!ENTITY interaction.daily.copy.other SYSTEM "results/daily.copy.other.lxo"> 35.67 <!ENTITY interaction.daily.copy.simple SYSTEM "results/daily.copy.simple.lxo"> 35.68 <!ENTITY interaction.daily.copy.status SYSTEM "results/daily.copy.status.lxo"> 35.69 @@ -114,8 +154,6 @@ 35.70 <!ENTITY interaction.hook.simple.ext SYSTEM "results/hook.simple.ext.lxo"> 35.71 <!ENTITY interaction.hook.simple.init SYSTEM "results/hook.simple.init.lxo"> 35.72 <!ENTITY interaction.hook.simple.pretxncommit SYSTEM "results/hook.simple.pretxncommit.lxo"> 35.73 -<!ENTITY interaction.hook.ws.better SYSTEM "results/hook.ws.better.lxo"> 35.74 -<!ENTITY interaction.hook.ws.simple SYSTEM "results/hook.ws.simple.lxo"> 35.75 <!ENTITY interaction.issue29.go SYSTEM "results/issue29.go.lxo"> 35.76 <!ENTITY interaction.mq.dodiff.diff SYSTEM "results/mq.dodiff.diff.lxo"> 35.77 <!ENTITY interaction.mq.guards.init SYSTEM "results/mq.guards.init.lxo"> 35.78 @@ -208,6 +246,8 @@ 35.79 <!ENTITY interaction.tour.lxogoing SYSTEM "results/tour.lxogoing.lxo"> 35.80 <!ENTITY interaction.tour.lxogoing.net SYSTEM "results/tour.lxogoing.net.lxo"> 35.81 <!ENTITY interaction.tour.merge.cat SYSTEM "results/tour.merge.cat.lxo"> 35.82 +<!ENTITY interaction.tour.merge.cat1 SYSTEM "results/tour.merge.cat1.lxo"> 35.83 +<!ENTITY interaction.tour.merge.cat2 SYSTEM "results/tour.merge.cat2.lxo"> 35.84 <!ENTITY interaction.tour.merge.clone SYSTEM "results/tour.merge.clone.lxo"> 35.85 <!ENTITY interaction.tour.merge.commit SYSTEM "results/tour.merge.commit.lxo"> 35.86 <!ENTITY interaction.tour.merge.dummy1 SYSTEM "results/tour.merge.dummy1.lxo">
36.1 --- a/en/examples/backout Sat Apr 18 11:52:33 2009 +0800 36.2 +++ b/en/examples/backout Thu May 21 14:16:17 2009 +0800 36.3 @@ -68,6 +68,10 @@ 36.4 36.5 hg heads 36.6 36.7 +#$ name: 36.8 + 36.9 +echo 'first change' > myfile 36.10 + 36.11 #$ name: manual.cat 36.12 36.13 cat myfile
37.1 --- a/en/examples/bisect Sat Apr 18 11:52:33 2009 +0800 37.2 +++ b/en/examples/bisect Thu May 21 14:16:17 2009 +0800 37.3 @@ -37,15 +37,15 @@ 37.4 37.5 #$ name: search.init 37.6 37.7 -hg bisect init 37.8 +hg bisect --reset 37.9 37.10 #$ name: search.bad-init 37.11 37.12 -hg bisect bad 37.13 +hg bisect --bad 37.14 37.15 #$ name: search.good-init 37.16 37.17 -hg bisect good 10 37.18 +hg bisect --good 10 37.19 37.20 #$ name: search.step1 37.21 37.22 @@ -70,7 +70,7 @@ 37.23 fi 37.24 37.25 echo this revision is $result 37.26 - hg bisect $result 37.27 + hg bisect --$result 37.28 } 37.29 37.30 #$ name: search.step2 37.31 @@ -85,7 +85,7 @@ 37.32 37.33 #$ name: search.reset 37.34 37.35 -hg bisect reset 37.36 +hg bisect --reset 37.37 37.38 #$ name: 37.39
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/en/examples/ch01/new Thu May 21 14:16:17 2009 +0800 38.3 @@ -0,0 +1,39 @@ 38.4 +#!/bin/bash 38.5 + 38.6 +cat > hello.c <<EOF 38.7 +int main() 38.8 +{ 38.9 + printf("hello world!\n"); 38.10 +} 38.11 +EOF 38.12 + 38.13 +cat > goodbye.c <<EOF 38.14 +int main() 38.15 +{ 38.16 + printf("goodbye world!\n"); 38.17 +} 38.18 +EOF 38.19 + 38.20 +#$ name: init 38.21 + 38.22 +hg init myproject 38.23 + 38.24 +#$ name: ls 38.25 + 38.26 +ls -l 38.27 + 38.28 +#$ name: ls2 38.29 + 38.30 +ls -al myproject 38.31 + 38.32 +#$ name: add 38.33 + 38.34 +cd myproject 38.35 +cp ../hello.c . 38.36 +cp ../goodbye.c . 38.37 +hg add 38.38 +hg status 38.39 + 38.40 +#$ name: commit 38.41 + 38.42 +hg commit -m 'Initial commit'
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/en/examples/ch04/diff Thu May 21 14:16:17 2009 +0800 39.3 @@ -0,0 +1,30 @@ 39.4 +#!/bin/bash 39.5 + 39.6 +hg init a 39.7 +cd a 39.8 +echo a > a 39.9 +hg ci -Ama 39.10 + 39.11 +#$ name: rename.basic 39.12 + 39.13 +hg rename a b 39.14 +hg diff 39.15 + 39.16 +#$ name: rename.git 39.17 + 39.18 +hg diff -g 39.19 + 39.20 +#$ name: 39.21 + 39.22 +hg revert -a 39.23 +rm b 39.24 + 39.25 +#$ name: chmod 39.26 + 39.27 +chmod +x a 39.28 +hg st 39.29 +hg diff 39.30 + 39.31 +#$ name: chmod.git 39.32 + 39.33 +hg diff -g
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/en/examples/ch09/check_whitespace.py.lst Thu May 21 14:16:17 2009 +0800 40.3 @@ -0,0 +1,47 @@ 40.4 +#!/usr/bin/env python 40.5 +# 40.6 +# save as .hg/check_whitespace.py and make executable 40.7 + 40.8 +import re 40.9 + 40.10 +def trailing_whitespace(difflines): 40.11 + # 40.12 + linenum, header = 0, False 40.13 + 40.14 + for line in difflines: 40.15 + if header: 40.16 + # remember the name of the file that this diff affects 40.17 + m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line) 40.18 + if m and m.group(1) != '/dev/null': 40.19 + filename = m.group(1).split('/', 1)[-1] 40.20 + if line.startswith('+++ '): 40.21 + header = False 40.22 + continue 40.23 + if line.startswith('diff '): 40.24 + header = True 40.25 + continue 40.26 + # hunk header - save the line number 40.27 + m = re.match(r'@@ -\d+,\d+ \+(\d+),', line) 40.28 + if m: 40.29 + linenum = int(m.group(1)) 40.30 + continue 40.31 + # hunk body - check for an added line with trailing whitespace 40.32 + m = re.match(r'\+.*\s$', line) 40.33 + if m: 40.34 + yield filename, linenum 40.35 + if line and line[0] in ' +': 40.36 + linenum += 1 40.37 + 40.38 +if __name__ == '__main__': 40.39 + import os, sys 40.40 + 40.41 + added = 0 40.42 + for filename, linenum in trailing_whitespace(os.popen('hg export tip')): 40.43 + print >> sys.stderr, ('%s, line %d: trailing whitespace added' % 40.44 + (filename, linenum)) 40.45 + added += 1 40.46 + if added: 40.47 + # save the commit message so we don't need to retype it 40.48 + os.system('hg tip --template "{desc}" > .hg/commit.save') 40.49 + print >> sys.stderr, 'commit message saved to .hg/commit.save' 40.50 + sys.exit(1)
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/en/examples/ch09/hook.ws Thu May 21 14:16:17 2009 +0800 41.3 @@ -0,0 +1,32 @@ 41.4 +#!/bin/bash 41.5 + 41.6 +hg init a 41.7 +cd a 41.8 +echo '[hooks]' > .hg/hgrc 41.9 +echo "pretxncommit.whitespace = hg export tip | (! egrep -q '^\\+.*[ \\t]$')" >> .hg/hgrc 41.10 + 41.11 +#$ name: simple 41.12 + 41.13 +cat .hg/hgrc 41.14 +echo 'a ' > a 41.15 +hg commit -A -m 'test with trailing whitespace' 41.16 +echo 'a' > a 41.17 +hg commit -A -m 'drop trailing whitespace and try again' 41.18 + 41.19 +#$ name: 41.20 + 41.21 +echo '[hooks]' > .hg/hgrc 41.22 +echo "pretxncommit.whitespace = .hg/check_whitespace.py" >> .hg/hgrc 41.23 +cp $EXAMPLE_DIR/ch09/check_whitespace.py.lst .hg/check_whitespace.py 41.24 +chmod +x .hg/check_whitespace.py 41.25 + 41.26 +#$ name: better 41.27 + 41.28 +cat .hg/hgrc 41.29 +echo 'a ' >> a 41.30 +hg commit -A -m 'add new line with trailing whitespace' 41.31 +sed -i 's, *$,,' a 41.32 +hg commit -A -m 'trimmed trailing whitespace' 41.33 + 41.34 +#$ name: 41.35 +exit 0
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/en/examples/ch10/multiline Thu May 21 14:16:17 2009 +0800 42.3 @@ -0,0 +1,13 @@ 42.4 +#!/bin/sh 42.5 + 42.6 +hg init 42.7 +echo a > test.c 42.8 +hg ci -Am'First commit' 42.9 + 42.10 +#$ name: go 42.11 + 42.12 +cat > multiline << EOF 42.13 +changeset = "Changed in {node|short}:\n{files}" 42.14 +file = " {file}\n" 42.15 +EOF 42.16 +hg log --style multiline
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/en/examples/ch11/qdelete Thu May 21 14:16:17 2009 +0800 43.3 @@ -0,0 +1,32 @@ 43.4 +#!/bin/bash 43.5 + 43.6 +echo '[extensions]' >> $HGRC 43.7 +echo 'hgext.mq =' >> $HGRC 43.8 + 43.9 +#$ name: go 43.10 + 43.11 +hg init myrepo 43.12 +cd myrepo 43.13 +hg qinit 43.14 +hg qnew bad.patch 43.15 +echo a > a 43.16 +hg add a 43.17 +hg qrefresh 43.18 +hg qdelete bad.patch 43.19 +hg qpop 43.20 +hg qdelete bad.patch 43.21 + 43.22 +#$ name: convert 43.23 + 43.24 +hg qnew good.patch 43.25 +echo a > a 43.26 +hg add a 43.27 +hg qrefresh -m 'Good change' 43.28 +hg qfinish tip 43.29 +hg qapplied 43.30 +hg tip --style=compact 43.31 + 43.32 +#$ name: import 43.33 + 43.34 +hg qimport -r tip 43.35 +hg qapplied
44.1 --- a/en/examples/daily.copy Sat Apr 18 11:52:33 2009 +0800 44.2 +++ b/en/examples/daily.copy Thu May 21 14:16:17 2009 +0800 44.3 @@ -51,9 +51,9 @@ 44.4 cd copy-example 44.5 echo a > a 44.6 echo b > b 44.7 -mkdir c 44.8 -mkdir c/a 44.9 -echo c > c/a/c 44.10 +mkdir z 44.11 +mkdir z/a 44.12 +echo c > z/a/c 44.13 hg ci -Ama 44.14 44.15 #$ name: simple 44.16 @@ -70,13 +70,13 @@ 44.17 44.18 #$ name: dir-src 44.19 44.20 -hg copy c e 44.21 +hg copy z e 44.22 44.23 #$ name: dir-src-dest 44.24 44.25 -hg copy c d 44.26 +hg copy z d 44.27 44.28 #$ name: after 44.29 44.30 -cp a z 44.31 -hg copy --after a z 44.32 +cp a n 44.33 +hg copy --after a n
45.1 --- a/en/examples/data/check_whitespace.py Sat Apr 18 11:52:33 2009 +0800 45.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 45.3 @@ -1,44 +0,0 @@ 45.4 -#!/usr/bin/python 45.5 - 45.6 -import re 45.7 - 45.8 -def trailing_whitespace(difflines): 45.9 - added, linenum, header = [], 0, False 45.10 - 45.11 - for line in difflines: 45.12 - if header: 45.13 - # remember the name of the file that this diff affects 45.14 - m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line) 45.15 - if m and m.group(1) != '/dev/null': 45.16 - filename = m.group(1).split('/', 1)[-1] 45.17 - if line.startswith('+++ '): 45.18 - header = False 45.19 - continue 45.20 - if line.startswith('diff '): 45.21 - header = True 45.22 - continue 45.23 - # hunk header - save the line number 45.24 - m = re.match(r'@@ -\d+,\d+ \+(\d+),', line) 45.25 - if m: 45.26 - linenum = int(m.group(1)) 45.27 - continue 45.28 - # hunk body - check for an added line with trailing whitespace 45.29 - m = re.match(r'\+.*\s$', line) 45.30 - if m: 45.31 - added.append((filename, linenum)) 45.32 - if line and line[0] in ' +': 45.33 - linenum += 1 45.34 - return added 45.35 - 45.36 -if __name__ == '__main__': 45.37 - import os, sys 45.38 - 45.39 - added = trailing_whitespace(os.popen('hg export tip')) 45.40 - if added: 45.41 - for filename, linenum in added: 45.42 - print >> sys.stderr, ('%s, line %d: trailing whitespace added' % 45.43 - (filename, linenum)) 45.44 - # save the commit message so we don't need to retype it 45.45 - os.system('hg tip --template "{desc}" > .hg/commit.save') 45.46 - print >> sys.stderr, 'commit message saved to .hg/commit.save' 45.47 - sys.exit(1)
46.1 --- a/en/examples/hook.ws Sat Apr 18 11:52:33 2009 +0800 46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 46.3 @@ -1,31 +0,0 @@ 46.4 -#!/bin/bash 46.5 - 46.6 -hg init a 46.7 -cd a 46.8 -echo '[hooks]' > .hg/hgrc 46.9 -echo "pretxncommit.whitespace = hg export tip | (! egrep -q '^\\+.*[ \\t]$')" >> .hg/hgrc 46.10 - 46.11 -#$ name: simple 46.12 - 46.13 -cat .hg/hgrc 46.14 -echo 'a ' > a 46.15 -hg commit -A -m 'test with trailing whitespace' 46.16 -echo 'a' > a 46.17 -hg commit -A -m 'drop trailing whitespace and try again' 46.18 - 46.19 -#$ name: 46.20 - 46.21 -echo '[hooks]' > .hg/hgrc 46.22 -echo "pretxncommit.whitespace = .hg/check_whitespace.py" >> .hg/hgrc 46.23 -cp $EXAMPLE_DIR/data/check_whitespace.py .hg 46.24 - 46.25 -#$ name: better 46.26 - 46.27 -cat .hg/hgrc 46.28 -echo 'a ' >> a 46.29 -hg commit -A -m 'add new line with trailing whitespace' 46.30 -sed -i 's, *$,,' a 46.31 -hg commit -A -m 'trimmed trailing whitespace' 46.32 - 46.33 -#$ name: 46.34 -exit 0
47.1 --- a/en/examples/mq.guards Sat Apr 18 11:52:33 2009 +0800 47.2 +++ b/en/examples/mq.guards Thu May 21 14:16:17 2009 +0800 47.3 @@ -29,7 +29,7 @@ 47.4 47.5 #$ name: qguard.neg 47.6 47.7 -hg qguard hello.patch -quux 47.8 +hg qguard -- hello.patch -quux 47.9 hg qguard hello.patch 47.10 47.11 #$ name: series
48.1 --- a/en/examples/tour Sat Apr 18 11:52:33 2009 +0800 48.2 +++ b/en/examples/tour Thu May 21 14:16:17 2009 +0800 48.3 @@ -119,6 +119,7 @@ 48.4 hg update 2 48.5 hg parents 48.6 hg update 48.7 +hg parents 48.8 48.9 #$ name: clone-push 48.10 48.11 @@ -148,24 +149,32 @@ 48.12 48.13 #$ name: 48.14 cp hello.c ../new-hello.c 48.15 -sed -i '/printf/i\\tprintf("once more, hello.\\n");' ../new-hello.c 48.16 +sed -i '/printf("hello,/i\\tprintf("once more, hello.\\n");' ../new-hello.c 48.17 + 48.18 +my-text-editor() 48.19 +{ 48.20 +cp ../new-hello.c hello.c 48.21 +} 48.22 48.23 #$ name: merge.clone 48.24 48.25 cd .. 48.26 hg clone hello my-new-hello 48.27 cd my-new-hello 48.28 -# The file new-hello.c is lightly edited. 48.29 -cp ../new-hello.c hello.c 48.30 +# Make some simple edits to hello.c. 48.31 +my-text-editor hello.c 48.32 hg commit -m 'A new hello for a new day.' 48.33 48.34 #$ name: merge.dummy2 48.35 48.36 hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-new-hello 48.37 48.38 -#$ name: merge.cat 48.39 - 48.40 -cat hello.c 48.41 +#$ name: merge.cat1 48.42 + 48.43 +cat hello.c 48.44 + 48.45 +#$ name: merge.cat2 48.46 + 48.47 cat ../my-hello/hello.c 48.48 48.49 #$ name: merge.pull
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/en/figs/bad-merge-1.dot Thu May 21 14:16:17 2009 +0800 49.3 @@ -0,0 +1,13 @@ 49.4 +digraph bad_merge_1 { 49.5 + ancestor [label="1: ancestor"]; 49.6 + left [label="2: my change"]; 49.7 + right [label="3: your change"]; 49.8 + bad [label="4: bad merge"]; 49.9 + new [label="5: new change"]; 49.10 + 49.11 + ancestor -> left; 49.12 + ancestor -> right; 49.13 + left -> bad; 49.14 + right -> bad; 49.15 + bad -> new; 49.16 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/en/figs/bad-merge-2.dot Thu May 21 14:16:17 2009 +0800 50.3 @@ -0,0 +1,18 @@ 50.4 +digraph bad_merge_2 { 50.5 + ancestor [label="1: ancestor",color=grey,fontcolor=grey]; 50.6 + left [label="2: my change",color=grey,fontcolor=grey]; 50.7 + right [label="3: your change",color=grey,fontcolor=grey]; 50.8 + bad [label="4: bad merge",color=grey,fontcolor=grey]; 50.9 + new [label="5: new change",color=grey,fontcolor=grey]; 50.10 + 50.11 + bak_left [label="6: backout 1 of\nbad merge",shape=box]; 50.12 + 50.13 + ancestor -> left [color=grey]; 50.14 + ancestor -> right [color=grey]; 50.15 + left -> bad [color=grey]; 50.16 + right -> bad [color=grey]; 50.17 + bad -> new [color=grey]; 50.18 + 50.19 + bad -> bak_left; 50.20 + left -> bak_left [style=dotted,label="--parent=2"]; 50.21 +}
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/en/figs/bad-merge-3.dot Thu May 21 14:16:17 2009 +0800 51.3 @@ -0,0 +1,22 @@ 51.4 +digraph bad_merge_3 { 51.5 + ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"]; 51.6 + left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"]; 51.7 + right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"]; 51.8 + bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"]; 51.9 + new [label="5: new change",color="#bbbbbb",fontcolor="#bbbbbb"]; 51.10 + 51.11 + bak_left [label="6: backout 1 of\nbad merge",color=grey,shape=box]; 51.12 + bak_right [label="8: backout 2 of\nbad merge",shape=box]; 51.13 + 51.14 + ancestor -> left [color="#bbbbbb"]; 51.15 + ancestor -> right [color="#bbbbbb"]; 51.16 + left -> bad [color="#bbbbbb"]; 51.17 + right -> bad [color="#bbbbbb"]; 51.18 + bad -> new [color="#bbbbbb"]; 51.19 + 51.20 + bad -> bak_left [color=grey]; 51.21 + left -> bak_left [style=dotted,label="--parent=2",color=grey,fontcolor=grey]; 51.22 + 51.23 + bad -> bak_right; 51.24 + right -> bak_right [style=dotted,label="--parent=3"]; 51.25 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/en/figs/bad-merge-4.dot Thu May 21 14:16:17 2009 +0800 52.3 @@ -0,0 +1,26 @@ 52.4 +digraph bad_merge_4 { 52.5 + ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"]; 52.6 + left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"]; 52.7 + right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"]; 52.8 + bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"]; 52.9 + new [label="5: new change",color="#bbbbbb",fontcolor="#bbbbbb"]; 52.10 + 52.11 + bak_left [label="6: backout 1 of\nbad merge",color=grey,fontcolor=grey,shape=box]; 52.12 + bak_right [label="7: backout 2 of\nbad merge",color=grey,fontcolor=grey,shape=box]; 52.13 + good [label="8: merge\nof backouts",shape=box]; 52.14 + 52.15 + ancestor -> left [color="#bbbbbb"]; 52.16 + ancestor -> right [color="#bbbbbb"]; 52.17 + left -> bad [color="#bbbbbb"]; 52.18 + right -> bad [color="#bbbbbb"]; 52.19 + bad -> new [color="#bbbbbb"]; 52.20 + 52.21 + bad -> bak_left [color=grey]; 52.22 + left -> bak_left [style=dotted,label="--parent=2",color=grey,fontcolor=grey]; 52.23 + 52.24 + bad -> bak_right [color=grey]; 52.25 + right -> bak_right [style=dotted,label="--parent=3",color=grey,fontcolor=grey]; 52.26 + 52.27 + bak_left -> good; 52.28 + bak_right -> good; 52.29 +}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/en/figs/bad-merge-5.dot Thu May 21 14:16:17 2009 +0800 53.3 @@ -0,0 +1,30 @@ 53.4 +digraph bad_merge_5 { 53.5 + ancestor [label="1: ancestor",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.6 + left [label="2: my change",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.7 + right [label="3: your change",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.8 + bad [label="4: bad merge",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.9 + new [label="5: new change",color=grey,fontcolor=grey]; 53.10 + 53.11 + bak_left [label="6: backout 1 of\nbad merge",color="#bbbbbb",fontcolor="#bbbbbb",shape=box]; 53.12 + bak_right [label="7: backout 2 of\nbad merge",color="#bbbbbb",fontcolor="#bbbbbb",shape=box]; 53.13 + good [label="8: merge\nof backouts",color=grey,fontcolor=grey,shape=box]; 53.14 + last [label="9: merge with\nnew change",shape=box]; 53.15 + 53.16 + ancestor -> left [color="#bbbbbb"]; 53.17 + ancestor -> right [color="#bbbbbb"]; 53.18 + left -> bad [color="#bbbbbb"]; 53.19 + right -> bad [color="#bbbbbb"]; 53.20 + bad -> new [color="#bbbbbb"]; 53.21 + 53.22 + bad -> bak_left [color="#bbbbbb"]; 53.23 + left -> bak_left [style=dotted,label="--parent=2",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.24 + 53.25 + bad -> bak_right [color="#bbbbbb"]; 53.26 + right -> bak_right [style=dotted,label="--parent=3",color="#bbbbbb",fontcolor="#bbbbbb"]; 53.27 + 53.28 + bak_left -> good [color=grey]; 53.29 + bak_right -> good [color=grey]; 53.30 + 53.31 + good -> last; 53.32 + new -> last; 53.33 +}
54.1 --- a/web/genindex.py Sat Apr 18 11:52:33 2009 +0800 54.2 +++ b/web/genindex.py Thu May 21 14:16:17 2009 +0800 54.3 @@ -6,7 +6,8 @@ 54.4 filename_re = re.compile(r'<\?dbhtml filename="([^"]+)"\?>') 54.5 title_re = re.compile(r'<title>(.*)</title>') 54.6 54.7 -chapters = glob.glob('../en/ch*.xml') + glob.glob('../en/app*.xml') 54.8 +chapters = (sorted(glob.glob('../en/ch*.xml')) + 54.9 + sorted(glob.glob('../en/app*.xml'))) 54.10 54.11 fp = open('index-read.html.in', 'w') 54.12
55.1 --- a/web/index.html.in Sat Apr 18 11:52:33 2009 +0800 55.2 +++ b/web/index.html.in Thu May 21 14:16:17 2009 +0800 55.3 @@ -19,10 +19,14 @@ 55.4 55.5 <h2>You can contribute!</h2> 55.6 55.7 - <p>I publish the <a href="http://hgbook.red-bean.com/">source 55.8 - code</a> for this book as a Mercurial repository. Please feel 55.9 + <p>I publish the source code for this book 55.10 + as <a href="http://hg.serpentine.com/mercurial/book">a 55.11 + Mercurial repository</a>. Please feel 55.12 welcome to clone it, make modifications to your copy, and send me 55.13 - changes.</p> 55.14 + changes. Getting a copy of the source takes just a few seconds if 55.15 + you have Mercurial installed:</p> 55.16 + 55.17 + <pre class="screen">hg clone http://hg.serpentine.com/mercurial/book</pre> 55.18 55.19 <p>The online version of the book includes a comment system 55.20 that you can use to send feedback involving errors, omissions, and