Anonymous avatar Anonymous committed 547d3aa

Initial copy from the english version, added package for french input.

Comments (0)

Files changed (91)

+% The use of oneside here is a temporary hack; \marginpar entries
+% don't show up on odd pages of PDF output without it.  Sigh.
+\documentclass[oneside]{book}
+\usepackage{enumerate}
+\usepackage{fullpage}
+\usepackage{makeidx}
+\usepackage{ifpdf}
+\usepackage{graphicx}
+\usepackage{pslatex}
+\usepackage{fancyvrb}
+% adding package specific to the french version
+\usepackage[french]{babel}
+\usepackage[utf8]{inputenc}
+% leave hyperref until last
+\usepackage[colorlinks=true,bookmarks=true,pdftitle={Distributed
+  revision control with Mercurial},pdfsubject={Revision
+  control},pdfkeywords={Mercurial, Revision control, Distributed
+  revision control},pdfauthor={Bryan O'Sullivan}]{hyperref}
+
+\include{99defs}
+
+\title{Gestion de source distribué avec Mercurial} \author{Bryan
+  O'Sullivan}
+\date{Copyright \copyright\ 2006, 2007 Bryan O'Sullivan.\\
+  Ce document peut être librement distribué selon les termes et 
+  les conditions décrites dans la version 1.0 de la licence Open Publication.
+  La licence est en annexe~\ref{chap:opl} de ce document.\\
+  
+  Cette traduction a été généré depuis 
+  \href{http://hg.serpentine.com/mercurial/book/}{rev~\input{build_id}}
+  avec \href{http://www.selenic.com/hg/}{rev~\input{hg_id}} of Mercurial.}
+
+\makeindex
+
+\begin{document}
+
+\maketitle
+
+\addcontentsline{toc}{chapter}{Contents}
+\pagenumbering{roman}
+\tableofcontents
+\listoffigures
+%\listoftables
+
+\pagenumbering{arabic}
+
+\include{preface}
+\include{intro}
+\include{tour-basic}
+\include{tour-merge}
+\include{concepts}
+\include{daily}
+\include{collab}
+\include{filenames}
+\include{branch}
+\include{undo}
+\include{hook}
+\include{template}
+\include{mq}
+\include{mq-collab}
+\include{hgext}
+
+\appendix
+\include{cmdref}
+\include{mq-ref}
+\include{srcinstall}
+\include{license}
+\addcontentsline{toc}{chapter}{Bibliography}
+\bibliographystyle{alpha}
+\bibliography{99book}
+
+\addcontentsline{toc}{chapter}{Index}
+\printindex
+
+\end{document}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: t
+%%% End: 
+@Unpublished{gruenbacher:2005,
+  author = 	 {Andreas Gruenbacher},
+  title = 	 {How To Survive With Many Patches (Introduction to \texttt{quilt})},
+  year = 	 {2005},
+  month = 	 {June},
+  note =         {\url{http://www.suse.de/~agruen/quilt.pdf}},
+}
+
+@InProceedings{web:europython,
+  author = 	 {Bryan O'Sullivan},
+  title = 	 {Achieving High Performance in Mercurial},
+  booktitle = 	 {EuroPython Conference},
+  year = 	 {2006},
+  month = 	 {July},
+  note = 	 {\url{XXX}},
+}
+
+@Misc{web:diffstat,
+  author = 	 {Thomas Dickey},
+  title = 	 {\texttt{diffstat}--make a histogram of \texttt{diff} output},
+  note = 	 {\url{http://dickey.his.com/diffstat/diffstat.html}},
+}
+
+@Misc{web:quilt,
+  author = 	 {Andreas Gruenbacher, Martin Quinson, Jean Delvare},
+  title = 	 {Patchwork Quilt},
+  note = 	 {\url{http://savannah.nongnu.org/projects/quilt}},
+}
+
+@Misc{web:patchutils,
+  author = 	 {Tim Waugh},
+  title = 	 {\texttt{patchutils}--programs that operate on patch files},
+  note = 	 {\url{http://cyberelk.net/tim/patchutils/}},
+}
+
+@Misc{web:mpatch,
+  author = 	 {Chris Mason},
+  title = 	 {\texttt{mpatch}--help solve patch rejects},
+  note = 	 {\url{http://oss.oracle.com/~mason/mpatch/}},
+}
+
+@Misc{web:wiggle,
+  author = 	 {Neil Brown},
+  title = 	 {\texttt{wiggle}--apply conflicting patches},
+  note = 	 {\url{http://cgi.cse.unsw.edu.au/~neilb/source/wiggle/}},
+}
+
+@Misc{web:mysql-python,
+  author =	 {Andy Dustman},
+  title =	 {MySQL for Python},
+  note =	 {\url{http://sourceforge.net/projects/mysql-python}},
+}
+
+@Misc{web:changelog,
+  author =	 {Richard Stallman, GNU Project volunteers},
+  title =	 {GNU Coding Standards---Change Logs},
+  note =	 {\url{http://www.gnu.org/prep/standards/html_node/Change-Logs.html}},
+}
+
+@Misc{web:macpython,
+  author =	 {Bob Ippolito, Ronald Oussoren},
+  title =	 {Universal MacPython},
+  note =	 {\url{http://bob.pythonmac.org/archives/2006/04/10/python-and-universal-binaries-on-mac-os-x/}},
+}
+
+@Misc{web:putty,
+  author =	 {Simon Tatham},
+  title =	 {PuTTY---open source ssh client for Windows},
+  note =	 {\url{http://www.chiark.greenend.org.uk/~sgtatham/putty/}},
+}
+
+@Misc{web:configparser,
+  author =       {Python.org},
+  title =	 {\texttt{ConfigParser}---Configuration file parser},
+  note =	 {\url{http://docs.python.org/lib/module-ConfigParser.html}},
+}
+% Bug ID.
+\newcommand{\bug}[1]{\index{Mercurial bug
+    database!\href{http://www.selenic.com/mercurial/bts/issue#1}{bug
+      ~#1}}\href{http://www.selenic.com/mercurial/bts/issue#1}{Mercurial
+    bug no.~#1}}
+
+% File name in the user's home directory.
+\newcommand{\tildefile}[1]{\texttt{\~{}/#1}}
+
+% File name.
+\newcommand{\filename}[1]{\texttt{#1}}
+
+% Directory name.
+\newcommand{\dirname}[1]{\texttt{#1}}
+
+% File name, with index entry.
+% The ``s'' prefix comes from ``special''.
+\newcommand{\sfilename}[1]{\index{\texttt{#1} file}\texttt{#1}}
+
+% Directory name, with index entry.
+\newcommand{\sdirname}[1]{\index{\texttt{#1} directory}\texttt{#1}}
+
+% Mercurial extension.
+\newcommand{\hgext}[1]{\index{\texttt{#1} extension}\texttt{#1}}
+
+% Command provided by a Mercurial extension.
+\newcommand{\hgxcmd}[2]{\index{\texttt{#2} command (\texttt{#1}
+      extension)}\index{\texttt{#1} extension!\texttt{#2} command}``\texttt{hg #2}''}
+
+% Mercurial command.
+\newcommand{\hgcmd}[1]{\index{\texttt{#1} command}``\texttt{hg #1}''}
+
+% Mercurial command, with arguments.
+\newcommand{\hgcmdargs}[2]{\index{\texttt{#1} command}``\texttt{hg #1 #2}''}
+
+\newcommand{\tplkword}[1]{\index{\texttt{#1} template keyword}\index{template keywords!\texttt{#1}}\texttt{#1}}
+
+\newcommand{\tplkwfilt}[2]{\index{\texttt{#1} template keyword!\texttt{#2}
+    filter}\index{template filters!\texttt{#2}}\index{\texttt{#2}
+    template filter}\texttt{#2}}
+
+\newcommand{\tplfilter}[1]{\index{template
+    filters!\texttt{#1}}\index{\texttt{#1} template
+    filter}\texttt{#1}}
+
+% Shell/system command.
+\newcommand{\command}[1]{\index{\texttt{#1} system command}\texttt{#1}}
+
+% Shell/system command, with arguments.
+\newcommand{\cmdargs}[2]{\index{\texttt{#1} system command}``\texttt{#1 #2}''}
+
+% Mercurial command option.
+\newcommand{\hgopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
+
+% Mercurial command option, provided by an extension command.
+\newcommand{\hgxopt}[3]{\index{\texttt{#2} command (\texttt{#1} extension)!\texttt{#3} option}\index{\texttt{#1} extension!\texttt{#2} command!\texttt{#3} option}\texttt{#3}}
+
+% Mercurial global option.
+\newcommand{\hggopt}[1]{\index{global options!\texttt{#1} option}\texttt{#1}}
+
+% Shell/system command option.
+\newcommand{\cmdopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
+
+% Command option.
+\newcommand{\option}[1]{\texttt{#1}}
+
+% Software package.
+\newcommand{\package}[1]{\index{\texttt{#1} package}\texttt{#1}}
+
+% Section name from a hgrc file.
+\newcommand{\rcsection}[1]{\index{\texttt{hgrc} file!\texttt{#1} section}\texttt{[#1]}}
+
+% Named item in a hgrc file section.
+\newcommand{\rcitem}[2]{\index{\texttt{hgrc} file!\texttt{#1}
+    section!\texttt{#2} entry}\texttt{#2}}
+
+% hgrc file.
+\newcommand{\hgrc}{\index{configuration file!\texttt{hgrc}
+    (Linux/Unix)}\index{\texttt{hgrc} configuration file}\texttt{hgrc}}
+
+% Mercurial.ini file.
+\newcommand{\hgini}{\index{configuration file!\texttt{Mercurial.ini}
+    (Windows)}\index{\texttt{Mercurial.ini} configuration file}\texttt{Mercurial.ini}}
+
+% Hook name.
+\newcommand{\hook}[1]{\index{\texttt{#1} hook}\index{hooks!\texttt{#1}}\texttt{#1}}
+
+% Environment variable.
+\newcommand{\envar}[1]{\index{\texttt{#1} environment
+    variable}\index{environment variables!\texttt{#1}}\texttt{#1}}
+
+% Python module.
+\newcommand{\pymod}[1]{\index{\texttt{#1} module}\texttt{#1}}
+
+% Python class in a module.
+\newcommand{\pymodclass}[2]{\index{\texttt{#1} module!\texttt{#2}
+    class}\texttt{#1.#2}}
+
+% Python function in a module.
+\newcommand{\pymodfunc}[2]{\index{\texttt{#1} module!\texttt{#2}
+    function}\texttt{#1.#2}}
+
+% Note: blah blah.
+\newsavebox{\notebox}
+\newenvironment{note}%
+  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Note:}\space}%
+  {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}}
+\newenvironment{caution}%
+  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Caution:}\space}%
+  {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}}
+
+% Code sample, eating 4 characters of leading space.
+\DefineVerbatimEnvironment{codesample4}{Verbatim}{frame=single,gobble=4,numbers=left,commandchars=\\\{\}}
+
+% Code sample, eating 2 characters of leading space.
+\DefineVerbatimEnvironment{codesample2}{Verbatim}{frame=single,gobble=2,numbers=left,commandchars=\\\{\}}
+
+% Interaction from the examples directory.
+\newcommand{\interaction}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{examples/#1.lxo}}
+% Example code from the examples directory.
+\newcommand{\excode}[1]{\VerbatimInput[frame=single,numbers=left,commandchars=\\\{\}]{../examples/#1}}
+
+% Graphics inclusion.
+\ifpdf
+  \newcommand{\grafix}[1]{\includegraphics{#1}}
+\else
+  \newcommand{\grafix}[1]{\includegraphics{#1.png}}
+\fi
+
+% Reference entry for a command.
+\newcommand{\cmdref}[2]{\section{\hgcmd{#1}---#2}\label{cmdref:#1}\index{\texttt{#1} command}}
+
+% Reference entry for a command option with long and short forms.
+\newcommand{\optref}[3]{\subsubsection{\hgopt{#1}{--#3}, also \hgopt{#1}{-#2}}}
+
+% Reference entry for a command option with only long form.
+\newcommand{\loptref}[2]{\subsubsection{\hgopt{#1}{--#2} option}}
+
+% command to generate a footnote to be used as a translator's note
+\newcommand{\ndt}[1]{\footnote{\textbf{N. del T.} #1}}
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
+# This makefile requires GNU make.
+
+sources := \
+	00book.tex \
+	99book.bib \
+	99defs.tex \
+	build_id.tex \
+	branch.tex \
+	cmdref.tex \
+	collab.tex \
+	concepts.tex \
+	daily.tex \
+	filenames.tex \
+	hg_id.tex \
+	hgext.tex \
+	hook.tex \
+	intro.tex \
+	mq.tex \
+	mq-collab.tex \
+	mq-ref.tex \
+	preface.tex \
+	srcinstall.tex \
+	template.tex \
+	tour-basic.tex \
+	tour-merge.tex \
+	undo.tex
+
+image-sources := \
+	feature-branches.dot \
+	filelog.svg \
+	kdiff3.png \
+	metadata.svg \
+	mq-stack.svg \
+	note.png \
+	revlog.svg \
+	snapshot.svg \
+	tour-history.svg \
+	tour-merge-conflict.svg \
+	tour-merge-merge.svg \
+	tour-merge-pull.svg \
+	tour-merge-sep-repos.svg \
+	undo-manual.dot \
+	undo-manual-merge.dot \
+	undo-non-tip.dot \
+	undo-simple.dot \
+	wdir.svg \
+	wdir-after-commit.svg \
+	wdir-branch.svg \
+	wdir-merge.svg \
+	wdir-pre-branch.svg
+
+image-dot := $(filter %.dot,$(image-sources))
+image-svg := $(filter %.svg,$(image-sources))
+image-png := $(filter %.png,$(image-sources))
+
+image-pdf := $(image-dot:%.dot=%.pdf) $(image-svg:%.svg=%.pdf) $(image-png)
+image-html := $(image-dot:%.dot=%.png) $(image-svg:%.svg=%.png) $(image-png)
+
+example-sources := \
+	backout \
+	bisect \
+	branching \
+	branch-named \
+	branch-repo \
+	cmdref \
+	daily.copy \
+	daily.files \
+	daily.rename \
+	daily.revert \
+	extdiff \
+	filenames \
+	hook.msglen \
+	hook.simple \
+	hook.ws \
+	issue29 \
+	mq.guards \
+	mq.qinit-help \
+	mq.dodiff \
+	mq.id \
+	mq.tarball \
+	mq.tools \
+	mq.tutorial \
+	rename.divergent \
+	rollback \
+	tag \
+	template.simple \
+	template.svnstyle \
+	tour \
+	tour-merge-conflict
+
+example-prereqs := \
+	/usr/bin/merge
+
+dist-sources := \
+	../html/hgicon.png \
+	../html/index.html.var \
+	../html/index.en.html
+
+latex-options = \
+	-interaction batchmode \
+	-output-directory $(dir $(1)) \
+	-jobname $(basename $(notdir $(1)))
+
+hg = $(shell which hg)
+
+hg-id = $(shell hg parents --template '{node|short}, dated {date|isodate},\n')
+
+hg-version = $(shell hg version -q | \
+		     sed 's,.*(version \(unknown\|[a-f0-9+]*\)),\1,')
+
+all: pdf html
+
+pdf: pdf/hgbook.pdf
+
+define pdf
+	mkdir -p $(dir $@)
+	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+	cp 99book.bib $(dir $@)
+	cd $(dir $@) && bibtex $(basename $(notdir $@))
+	cd $(dir $@) && makeindex $(basename $(notdir $@))
+	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+	if grep 'Reference.*undefined' $(@:.pdf=.log); then exit 1; fi
+endef
+
+pdf/hgbook.pdf: $(sources) examples $(image-pdf)
+	$(call pdf)
+
+html: onepage split
+
+onepage: $(htlatex) html/onepage/hgbook.html html/onepage/hgbook.css $(image-html:%=html/onepage/%)
+
+html/onepage/%: %
+	cp $< $@
+
+split: $(htlatex) html/split/hgbook.html html/split/hgbook.css $(image-html:%=html/split/%)
+
+html/split/%: %
+	cp $< $@
+
+# This is a horrible hack to work around the fact that the htlatex
+# command in tex4ht is itself a horrible hack.  I really don't want to
+# include verbatim the big wad of TeX that is repeated in that script,
+# but I've given up and run a hacked copy as htlatex.book here.
+
+define htlatex
+	mkdir -p $(dir $(1))
+	cp 99book.bib $(dir $(1))
+	TEXINPUTS=$(dir $(2)): ./htlatex.book $(2) "bookhtml,html4-uni,$(3)" " -cunihtf -utf8" "$(dir $(1))" "$(call latex-options,$(1))" || (rm -f $(1); exit 1)
+	cd $(dir $(1)) && tex4ht -f/$(basename $(notdir $(1))) -cvalidate -cunihtf
+	cd $(dir $(1)) && t4ht -f/$(basename $(notdir $(1)))
+	./fixhtml.py $(dir $(1))/*.html
+	rm $(dir $(1))/hgbook.css
+endef
+
+html/onepage/hgbook.html: $(sources) examples $(image-html) bookhtml.cfg
+	$(call htlatex,$@,$<)
+
+html/split/hgbook.html: $(sources) examples bookhtml.cfg
+	$(call htlatex,$@,$<,2)
+
+# Produce 90dpi PNGs for the web.
+
+%.png: %.svg fixsvg
+	./fixsvg $<
+	inkscape -D -e $@ $<-tmp.svg
+	rm $<-tmp.svg
+
+%.svg: %.dot
+	dot -Tsvg -o $@ $<
+
+# Produce eps & pdf for the pdf
+
+%.pdf: %.eps
+	epstopdf $<
+
+%.eps: %.svg
+	./fixsvg $<
+	inkscape -E $@ $<-tmp.svg
+	rm $<-tmp.svg
+
+%.eps: %.dot
+	dot -Tps -o $@ $<
+
+examples: $(example-prereqs) examples/.run
+
+examples/.run: $(example-sources:%=examples/%.run)
+	touch examples/.run
+
+examples/%.run: examples/% examples/run-example
+	cd examples && ./run-example $(notdir $<)
+
+changelog := $(wildcard ../.hg/store/00changelog.[id])
+ifeq ($(changelog),)
+changelog := $(wildcard ../.hg/00changelog.[id])
+endif
+
+build_id.tex: $(changelog)
+	echo -n '$(hg-id)' > build_id.tex
+
+hg_id.tex: $(hg)
+	echo -n '$(hg-version)' > hg_id.tex
+
+clean:
+	rm -rf dist html pdf \
+		$(image-dot:%.dot=%.pdf) \
+		$(image-dot:%.dot=%.png) \
+		$(image-svg:%.svg=%.pdf) \
+		$(image-svg:%.svg=%.png) \
+		examples/*.{lxo,run} examples/.run build_id.tex hg_id.tex
+
+install: pdf split $(dist-sources)
+	rm -rf dist
+	mkdir -p dist
+	cp pdf/hgbook.pdf dist
+	cp html/split/*.{css,html,png} dist
+	cp $(dist-sources) dist
+
+rsync: install
+	rsync -avz --delete dist sp.red-bean.com:public_html/hgbook
+% -*- latex -*-
+
+\Preamble{xhtml}
+
+% Tex4ht's default definition of lists is complete crap.
+% Unfortunately, it can't distinguish between "ul" and "dl" lists.
+
+\ConfigureList{itemize}%
+   {\EndP\HCode{<ul>}\let\endItem=\empty}
+   {\ifvmode \IgnorePar\fi
+    \EndP\HCode{</li></ul>}\ShowPar}
+   {\endItem \def\endItem{\EndP\Tg</span>}\HCode{<li><span class="dt">}}
+   {\HCode{</span><span class="dd">}}
+\def\textbullet{}
+
+\begin{document}
+
+\EndPreamble
+\chapter{Managing releases and branchy development}
+\label{chap:branch}
+
+Mercurial provides several mechanisms for you to manage a project that
+is making progress on multiple fronts at once.  To understand these
+mechanisms, let's first take a brief look at a fairly normal software
+project structure.
+
+Many software projects issue periodic ``major'' releases that contain
+substantial new features.  In parallel, they may issue ``minor''
+releases.  These are usually identical to the major releases off which
+they're based, but with a few bugs fixed.
+
+In this chapter, we'll start by talking about how to keep records of
+project milestones such as releases.  We'll then continue on to talk
+about the flow of work between different phases of a project, and how
+Mercurial can help you to isolate and manage this work.
+
+\section{Giving a persistent name to a revision}
+
+Once you decide that you'd like to call a particular revision a
+``release'', it's a good idea to record the identity of that revision.
+This will let you reproduce that release at a later date, for whatever
+purpose you might need at the time (reproducing a bug, porting to a
+new platform, etc).
+\interaction{tag.init}
+
+Mercurial lets you give a permanent name to any revision using the
+\hgcmd{tag} command.  Not surprisingly, these names are called
+``tags''.
+\interaction{tag.tag}
+
+A tag is nothing more than a ``symbolic name'' for a revision.  Tags
+exist purely for your convenience, so that you have a handy permanent
+way to refer to a revision; Mercurial doesn't interpret the tag names
+you use in any way.  Neither does Mercurial place any restrictions on
+the name of a tag, beyond a few that are necessary to ensure that a
+tag can be parsed unambiguously.  A tag name cannot contain any of the
+following characters:
+\begin{itemize}
+\item Colon (ASCII 58, ``\texttt{:}'')
+\item Carriage return (ASCII 13, ``\Verb+\r+'')
+\item Newline (ASCII 10, ``\Verb+\n+'')
+\end{itemize}
+
+You can use the \hgcmd{tags} command to display the tags present in
+your repository.  In the output, each tagged revision is identified
+first by its name, then by revision number, and finally by the unique
+hash of the revision.  
+\interaction{tag.tags}
+Notice that \texttt{tip} is listed in the output of \hgcmd{tags}.  The
+\texttt{tip} tag is a special ``floating'' tag, which always
+identifies the newest revision in the repository.
+
+In the output of the \hgcmd{tags} command, tags are listed in reverse
+order, by revision number.  This usually means that recent tags are
+listed before older tags.  It also means that \texttt{tip} is always
+going to be the first tag listed in the output of \hgcmd{tags}.
+
+When you run \hgcmd{log}, if it displays a revision that has tags
+associated with it, it will print those tags.
+\interaction{tag.log}
+
+Any time you need to provide a revision~ID to a Mercurial command, the
+command will accept a tag name in its place.  Internally, Mercurial
+will translate your tag name into the corresponding revision~ID, then
+use that.
+\interaction{tag.log.v1.0}
+
+There's no limit on the number of tags you can have in a repository,
+or on the number of tags that a single revision can have.  As a
+practical matter, it's not a great idea to have ``too many'' (a number
+which will vary from project to project), simply because tags are
+supposed to help you to find revisions.  If you have lots of tags, the
+ease of using them to identify revisions diminishes rapidly.
+
+For example, if your project has milestones as frequent as every few
+days, it's perfectly reasonable to tag each one of those.  But if you
+have a continuous build system that makes sure every revision can be
+built cleanly, you'd be introducing a lot of noise if you were to tag
+every clean build.  Instead, you could tag failed builds (on the
+assumption that they're rare!), or simply not use tags to track
+buildability.
+
+If you want to remove a tag that you no longer want, use
+\hgcmdargs{tag}{--remove}.  
+\interaction{tag.remove}
+You can also modify a tag at any time, so that it identifies a
+different revision, by simply issuing a new \hgcmd{tag} command.
+You'll have to use the \hgopt{tag}{-f} option to tell Mercurial that
+you \emph{really} want to update the tag.
+\interaction{tag.replace}
+There will still be a permanent record of the previous identity of the
+tag, but Mercurial will no longer use it.  There's thus no penalty to
+tagging the wrong revision; all you have to do is turn around and tag
+the correct revision once you discover your error.
+
+Mercurial stores tags in a normal revision-controlled file in your
+repository.  If you've created any tags, you'll find them in a file
+named \sfilename{.hgtags}.  When you run the \hgcmd{tag} command,
+Mercurial modifies this file, then automatically commits the change to
+it.  This means that every time you run \hgcmd{tag}, you'll see a
+corresponding changeset in the output of \hgcmd{log}.
+\interaction{tag.tip}
+
+\subsection{Handling tag conflicts during a merge}
+
+You won't often need to care about the \sfilename{.hgtags} file, but
+it sometimes makes its presence known during a merge.  The format of
+the file is simple: it consists of a series of lines.  Each line
+starts with a changeset hash, followed by a space, followed by the
+name of a tag.
+
+If you're resolving a conflict in the \sfilename{.hgtags} file during
+a merge, there's one twist to modifying the \sfilename{.hgtags} file:
+when Mercurial is parsing the tags in a repository, it \emph{never}
+reads the working copy of the \sfilename{.hgtags} file.  Instead, it
+reads the \emph{most recently committed} revision of the file.
+
+An unfortunate consequence of this design is that you can't actually
+verify that your merged \sfilename{.hgtags} file is correct until
+\emph{after} you've committed a change.  So if you find yourself
+resolving a conflict on \sfilename{.hgtags} during a merge, be sure to
+run \hgcmd{tags} after you commit.  If it finds an error in the
+\sfilename{.hgtags} file, it will report the location of the error,
+which you can then fix and commit.  You should then run \hgcmd{tags}
+again, just to be sure that your fix is correct.
+
+\subsection{Tags and cloning}
+
+You may have noticed that the \hgcmd{clone} command has a
+\hgopt{clone}{-r} option that lets you clone an exact copy of the
+repository as of a particular changeset.  The new clone will not
+contain any project history that comes after the revision you
+specified.  This has an interaction with tags that can surprise the
+unwary.
+
+Recall that a tag is stored as a revision to the \sfilename{.hgtags}
+file, so that when you create a tag, the changeset in which it's
+recorded necessarily refers to an older changeset.  When you run
+\hgcmdargs{clone}{-r foo} to clone a repository as of tag
+\texttt{foo}, the new clone \emph{will not contain the history that
+  created the tag} that you used to clone the repository.  The result
+is that you'll get exactly the right subset of the project's history
+in the new repository, but \emph{not} the tag you might have expected.
+
+\subsection{When permanent tags are too much}
+
+Since Mercurial's tags are revision controlled and carried around with
+a project's history, everyone you work with will see the tags you
+create.  But giving names to revisions has uses beyond simply noting
+that revision \texttt{4237e45506ee} is really \texttt{v2.0.2}.  If
+you're trying to track down a subtle bug, you might want a tag to
+remind you of something like ``Anne saw the symptoms with this
+revision''.
+
+For cases like this, what you might want to use are \emph{local} tags.
+You can create a local tag with the \hgopt{tag}{-l} option to the
+\hgcmd{tag} command.  This will store the tag in a file called
+\sfilename{.hg/localtags}.  Unlike \sfilename{.hgtags},
+\sfilename{.hg/localtags} is not revision controlled.  Any tags you
+create using \hgopt{tag}{-l} remain strictly local to the repository
+you're currently working in.
+
+\section{The flow of changes---big picture vs. little}
+
+To return to the outline I sketched at the beginning of a chapter,
+let's think about a project that has multiple concurrent pieces of
+work under development at once.
+
+There might be a push for a new ``main'' release; a new minor bugfix
+release to the last main release; and an unexpected ``hot fix'' to an
+old release that is now in maintenance mode.
+
+The usual way people refer to these different concurrent directions of
+development is as ``branches''.  However, we've already seen numerous
+times that Mercurial treats \emph{all of history} as a series of
+branches and merges.  Really, what we have here is two ideas that are
+peripherally related, but which happen to share a name.
+\begin{itemize}
+\item ``Big picture'' branches represent the sweep of a project's
+  evolution; people give them names, and talk about them in
+  conversation.
+\item ``Little picture'' branches are artefacts of the day-to-day
+  activity of developing and merging changes.  They expose the
+  narrative of how the code was developed.
+\end{itemize}
+
+\section{Managing big-picture branches in repositories}
+
+The easiest way to isolate a ``big picture'' branch in Mercurial is in
+a dedicated repository.  If you have an existing shared
+repository---let's call it \texttt{myproject}---that reaches a ``1.0''
+milestone, you can start to prepare for future maintenance releases on
+top of version~1.0 by tagging the revision from which you prepared
+the~1.0 release.
+\interaction{branch-repo.tag}
+You can then clone a new shared \texttt{myproject-1.0.1} repository as
+of that tag.
+\interaction{branch-repo.clone}
+
+Afterwards, if someone needs to work on a bug fix that ought to go
+into an upcoming~1.0.1 minor release, they clone the
+\texttt{myproject-1.0.1} repository, make their changes, and push them
+back.
+\interaction{branch-repo.bugfix}
+Meanwhile, development for the next major release can continue,
+isolated and unabated, in the \texttt{myproject} repository.
+\interaction{branch-repo.new}
+
+\section{Don't repeat yourself: merging across branches}
+
+In many cases, if you have a bug to fix on a maintenance branch, the
+chances are good that the bug exists on your project's main branch
+(and possibly other maintenance branches, too).  It's a rare developer
+who wants to fix the same bug multiple times, so let's look at a few
+ways that Mercurial can help you to manage these bugfixes without
+duplicating your work.
+
+In the simplest instance, all you need to do is pull changes from your
+maintenance branch into your local clone of the target branch.
+\interaction{branch-repo.pull}
+You'll then need to merge the heads of the two branches, and push back
+to the main branch.
+\interaction{branch-repo.merge}
+
+\section{Naming branches within one repository}
+
+In most instances, isolating branches in repositories is the right
+approach.  Its simplicity makes it easy to understand; and so it's
+hard to make mistakes.  There's a one-to-one relationship between
+branches you're working in and directories on your system.  This lets
+you use normal (non-Mercurial-aware) tools to work on files within a
+branch/repository.
+
+If you're more in the ``power user'' category (\emph{and} your
+collaborators are too), there is an alternative way of handling
+branches that you can consider.  I've already mentioned the
+human-level distinction between ``small picture'' and ``big picture''
+branches.  While Mercurial works with multiple ``small picture''
+branches in a repository all the time (for example after you pull
+changes in, but before you merge them), it can \emph{also} work with
+multiple ``big picture'' branches.
+
+The key to working this way is that Mercurial lets you assign a
+persistent \emph{name} to a branch.  There always exists a branch
+named \texttt{default}.  Even before you start naming branches
+yourself, you can find traces of the \texttt{default} branch if you
+look for them.
+
+As an example, when you run the \hgcmd{commit} command, and it pops up
+your editor so that you can enter a commit message, look for a line
+that contains the text ``\texttt{HG: branch default}'' at the bottom.
+This is telling you that your commit will occur on the branch named
+\texttt{default}.
+
+To start working with named branches, use the \hgcmd{branches}
+command.  This command lists the named branches already present in
+your repository, telling you which changeset is the tip of each.
+\interaction{branch-named.branches}
+Since you haven't created any named branches yet, the only one that
+exists is \texttt{default}.
+
+To find out what the ``current'' branch is, run the \hgcmd{branch}
+command, giving it no arguments.  This tells you what branch the
+parent of the current changeset is on.
+\interaction{branch-named.branch}
+
+To create a new branch, run the \hgcmd{branch} command again.  This
+time, give it one argument: the name of the branch you want to create.
+\interaction{branch-named.create}
+
+After you've created a branch, you might wonder what effect the
+\hgcmd{branch} command has had.  What do the \hgcmd{status} and
+\hgcmd{tip} commands report?
+\interaction{branch-named.status}
+Nothing has changed in the working directory, and there's been no new
+history created.  As this suggests, running the \hgcmd{branch} command
+has no permanent effect; it only tells Mercurial what branch name to
+use the \emph{next} time you commit a changeset.
+
+When you commit a change, Mercurial records the name of the branch on
+which you committed.  Once you've switched from the \texttt{default}
+branch to another and committed, you'll see the name of the new branch
+show up in the output of \hgcmd{log}, \hgcmd{tip}, and other commands
+that display the same kind of output.
+\interaction{branch-named.commit}
+The \hgcmd{log}-like commands will print the branch name of every
+changeset that's not on the \texttt{default} branch.  As a result, if
+you never use named branches, you'll never see this information.
+
+Once you've named a branch and committed a change with that name,
+every subsequent commit that descends from that change will inherit
+the same branch name.  You can change the name of a branch at any
+time, using the \hgcmd{branch} command.  
+\interaction{branch-named.rebranch}
+In practice, this is something you won't do very often, as branch
+names tend to have fairly long lifetimes.  (This isn't a rule, just an
+observation.)
+
+\section{Dealing with multiple named branches in a repository}
+
+If you have more than one named branch in a repository, Mercurial will
+remember the branch that your working directory on when you start a
+command like \hgcmd{update} or \hgcmdargs{pull}{-u}.  It will update
+the working directory to the tip of this branch, no matter what the
+``repo-wide'' tip is.  To update to a revision that's on a different
+named branch, you may need to use the \hgopt{update}{-C} option to
+\hgcmd{update}.
+
+This behaviour is a little subtle, so let's see it in action.  First,
+let's remind ourselves what branch we're currently on, and what
+branches are in our repository.
+\interaction{branch-named.parents}
+We're on the \texttt{bar} branch, but there also exists an older
+\hgcmd{foo} branch.
+
+We can \hgcmd{update} back and forth between the tips of the
+\texttt{foo} and \texttt{bar} branches without needing to use the
+\hgopt{update}{-C} option, because this only involves going backwards
+and forwards linearly through our change history.
+\interaction{branch-named.update-switchy}
+
+If we go back to the \texttt{foo} branch and then run \hgcmd{update},
+it will keep us on \texttt{foo}, not move us to the tip of
+\texttt{bar}.
+\interaction{branch-named.update-nothing}
+
+Committing a new change on the \texttt{foo} branch introduces a new
+head.
+\interaction{branch-named.foo-commit}
+
+\section{Branch names and merging}
+
+As you've probably noticed, merges in Mercurial are not symmetrical.
+Let's say our repository has two heads, 17 and 23.  If I
+\hgcmd{update} to 17 and then \hgcmd{merge} with 23, Mercurial records
+17 as the first parent of the merge, and 23 as the second.  Whereas if
+I \hgcmd{update} to 23 and then \hgcmd{merge} with 17, it records 23
+as the first parent, and 17 as the second.
+
+This affects Mercurial's choice of branch name when you merge.  After
+a merge, Mercurial will retain the branch name of the first parent
+when you commit the result of the merge.  If your first parent's
+branch name is \texttt{foo}, and you merge with \texttt{bar}, the
+branch name will still be \texttt{foo} after you merge.
+
+It's not unusual for a repository to contain multiple heads, each with
+the same branch name.  Let's say I'm working on the \texttt{foo}
+branch, and so are you.  We commit different changes; I pull your
+changes; I now have two heads, each claiming to be on the \texttt{foo}
+branch.  The result of a merge will be a single head on the
+\texttt{foo} branch, as you might hope.
+
+But if I'm working on the \texttt{bar} branch, and I merge work from
+the \texttt{foo} branch, the result will remain on the \texttt{bar}
+branch.
+\interaction{branch-named.merge}
+
+To give a more concrete example, if I'm working on the
+\texttt{bleeding-edge} branch, and I want to bring in the latest fixes
+from the \texttt{stable} branch, Mercurial will choose the ``right''
+(\texttt{bleeding-edge}) branch name when I pull and merge from
+\texttt{stable}.
+
+\section{Branch naming is generally useful}
+
+You shouldn't think of named branches as applicable only to situations
+where you have multiple long-lived branches cohabiting in a single
+repository.  They're very useful even in the one-branch-per-repository
+case.  
+
+In the simplest case, giving a name to each branch gives you a
+permanent record of which branch a changeset originated on.  This
+gives you more context when you're trying to follow the history of a
+long-lived branchy project.
+
+If you're working with shared repositories, you can set up a
+\hook{pretxnchangegroup} hook on each that will block incoming changes
+that have the ``wrong'' branch name.  This provides a simple, but
+effective, defence against people accidentally pushing changes from a
+``bleeding edge'' branch to a ``stable'' branch.  Such a hook might
+look like this inside the shared repo's \hgrc.
+\begin{codesample2}
+  [hooks]
+  pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
+\end{codesample2}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
+#!/usr/bin/env python
+
+import getopt
+import itertools
+import os
+import re
+import sys
+
+def usage(exitcode):
+    print >> sys.stderr, ('usage: %s [-H|--hidden] hg_repo' % 
+                          os.path.basename(sys.argv[0]))
+    sys.exit(exitcode)
+
+try:
+    opts, args = getopt.getopt(sys.argv[1:], 'AHh?', ['all', 'help', 'hidden'])
+    opt_all = False
+    opt_hidden = False
+    for o, a in opts:
+        if o in ('-h', '-?', '--help'):
+            usage(0)
+        if o in ('-A', '--all'):
+            opt_all = True
+        if o in ('-H', '--hidden'):
+            opt_hidden = True
+except getopt.GetoptError, err:
+    print >> sys.stderr, 'error:', err
+    usage(1)
+
+try:
+    hg_repo, ltx_file = args
+except ValueError:
+    usage(1)
+
+if not os.path.isfile(os.path.join(hg_repo, 'mercurial', 'commands.py')):
+    print >> sys.stderr, ('error: %r does not contain mercurial code' %
+                          hg_repo)
+    sys.exit(1)
+
+sys.path.insert(0, hg_repo)
+
+from mercurial import commands
+
+def get_commands():
+    seen = {}
+    for name, info in sorted(commands.table.iteritems()):
+        aliases = name.split('|', 1)
+        name = aliases.pop(0).lstrip('^')
+        function, options, synopsis = info
+        seen[name] = {}
+        for shortopt, longopt, arg, desc in options:
+            seen[name][longopt] = shortopt
+    return seen
+
+def cmd_filter((name, aliases, options)):
+    if opt_all:
+        return True
+    if opt_hidden:
+        return name.startswith('debug')
+    return not name.startswith('debug')
+
+def scan(ltx_file):
+    cmdref_re = re.compile(r'^\\cmdref{(?P<cmd>\w+)}')
+    optref_re = re.compile(r'^\\l?optref{(?P<cmd>\w+)}'
+                           r'(?:{(?P<short>[^}])})?'
+                           r'{(?P<long>[^}]+)}')
+
+    seen = {}
+    locs = {}
+    for lnum, line in enumerate(open(ltx_file)):
+        m = cmdref_re.match(line)
+        if m:
+            d = m.groupdict()
+            cmd = d['cmd']
+            seen[cmd] = {}
+            locs[cmd] = lnum + 1
+            continue
+        m = optref_re.match(line)
+        if m:
+            d = m.groupdict()
+            seen[d['cmd']][d['long']] = d['short']
+            continue
+    return seen, locs
+    
+documented, locs = scan(ltx_file)
+known = get_commands()
+
+doc_set = set(documented)
+known_set = set(known)
+
+errors = 0
+
+for nonexistent in sorted(doc_set.difference(known_set)):
+    print >> sys.stderr, ('%s:%d: %r command does not exist' %
+                          (ltx_file, locs[nonexistent], nonexistent))
+    errors += 1
+
+def optcmp(a, b):
+    la, sa = a
+    lb, sb = b
+    sc = cmp(sa, sb)
+    if sc:
+        return sc
+    return cmp(la, lb)
+
+for cmd in doc_set.intersection(known_set):
+    doc_opts = documented[cmd]
+    known_opts = known[cmd]
+    
+    do_set = set(doc_opts)
+    ko_set = set(known_opts)
+
+    for nonexistent in sorted(do_set.difference(ko_set)):
+        print >> sys.stderr, ('%s:%d: %r option to %r command does not exist' %
+                              (ltx_file, locs[cmd], nonexistent, cmd))
+        errors += 1
+
+    def mycmp(la, lb):
+        sa = known_opts[la]
+        sb = known_opts[lb]
+        return optcmp((la, sa), (lb, sb))
+
+    for undocumented in sorted(ko_set.difference(do_set), cmp=mycmp):
+        print >> sys.stderr, ('%s:%d: %r option to %r command not documented' %
+                              (ltx_file, locs[cmd], undocumented, cmd))
+        shortopt = known_opts[undocumented]
+        if shortopt:
+            print '\optref{%s}{%s}{%s}' % (cmd, shortopt, undocumented)
+        else:
+            print '\loptref{%s}{%s}' % (cmd, undocumented)
+        errors += 1
+    sys.stdout.flush()
+
+if errors:
+    sys.exit(1)
+
+sorted_locs = sorted(locs.iteritems(), key=lambda x:x[1])
+
+def next_loc(cmd):
+    for i, (name, loc) in enumerate(sorted_locs):
+        if name >= cmd:
+            return sorted_locs[i-1][1] + 1
+    return loc
+
+for undocumented in sorted(known_set.difference(doc_set)):
+    print >> sys.stderr, ('%s:%d: %r command not documented' %
+                          (ltx_file, next_loc(undocumented), undocumented))
+    print '\cmdref{%s}' % undocumented
+    for longopt, shortopt in sorted(known[undocumented].items(), cmp=optcmp):
+        if shortopt:
+            print '\optref{%s}{%s}{%s}' % (undocumented, shortopt, longopt)
+        else:
+            print '\loptref{%s}{%s}' % (undocumented, longopt)
+    sys.stdout.flush()
+    errors += 1
+
+sys.exit(errors and 1 or 0)
+\chapter{Command reference}
+\label{cmdref}
+
+\cmdref{add}{add files at the next commit}
+\optref{add}{I}{include}
+\optref{add}{X}{exclude}
+\optref{add}{n}{dry-run}
+
+\cmdref{diff}{print changes in history or working directory}
+
+Show differences between revisions for the specified files or
+directories, using the unified diff format.  For a description of the
+unified diff format, see section~\ref{sec:mq:patch}.
+
+By default, this command does not print diffs for files that Mercurial
+considers to contain binary data.  To control this behaviour, see the
+\hgopt{diff}{-a} and \hgopt{diff}{--git} options.
+
+\subsection{Options}
+
+\loptref{diff}{nodates}
+
+Omit date and time information when printing diff headers.
+
+\optref{diff}{B}{ignore-blank-lines}
+
+Do not print changes that only insert or delete blank lines.  A line
+that contains only whitespace is not considered blank.
+
+\optref{diff}{I}{include}
+
+Include files and directories whose names match the given patterns.
+
+\optref{diff}{X}{exclude}
+
+Exclude files and directories whose names match the given patterns.
+
+\optref{diff}{a}{text}
+
+If this option is not specified, \hgcmd{diff} will refuse to print
+diffs for files that it detects as binary. Specifying \hgopt{diff}{-a}
+forces \hgcmd{diff} to treat all files as text, and generate diffs for
+all of them.
+
+This option is useful for files that are ``mostly text'' but have a
+few embedded NUL characters.  If you use it on files that contain a
+lot of binary data, its output will be incomprehensible.
+
+\optref{diff}{b}{ignore-space-change}
+
+Do not print a line if the only change to that line is in the amount
+of white space it contains.
+
+\optref{diff}{g}{git}
+
+Print \command{git}-compatible diffs.  XXX reference a format
+description.
+
+\optref{diff}{p}{show-function}
+
+Display the name of the enclosing function in a hunk header, using a
+simple heuristic.  This functionality is enabled by default, so the
+\hgopt{diff}{-p} option has no effect unless you change the value of
+the \rcitem{diff}{showfunc} config item, as in the following example.
+\interaction{cmdref.diff-p}
+
+\optref{diff}{r}{rev}
+
+Specify one or more revisions to compare.  The \hgcmd{diff} command
+accepts up to two \hgopt{diff}{-r} options to specify the revisions to
+compare.
+
+\begin{enumerate}
+\setcounter{enumi}{0}
+\item Display the differences between the parent revision of the
+  working directory and the working directory.
+\item Display the differences between the specified changeset and the
+  working directory.
+\item Display the differences between the two specified changesets.
+\end{enumerate}
+
+You can specify two revisions using either two \hgopt{diff}{-r}
+options or revision range notation.  For example, the two revision
+specifications below are equivalent.
+\begin{codesample2}
+  hg diff -r 10 -r 20
+  hg diff -r10:20
+\end{codesample2}
+
+When you provide two revisions, Mercurial treats the order of those
+revisions as significant.  Thus, \hgcmdargs{diff}{-r10:20} will
+produce a diff that will transform files from their contents as of
+revision~10 to their contents as of revision~20, while
+\hgcmdargs{diff}{-r20:10} means the opposite: the diff that will
+transform files from their revision~20 contents to their revision~10
+contents.  You cannot reverse the ordering in this way if you are
+diffing against the working directory.
+
+\optref{diff}{w}{ignore-all-space}
+
+\cmdref{version}{print version and copyright information}
+
+This command displays the version of Mercurial you are running, and
+its copyright license.  There are four kinds of version string that
+you may see.
+\begin{itemize}
+\item The string ``\texttt{unknown}''. This version of Mercurial was
+  not built in a Mercurial repository, and cannot determine its own
+  version.
+\item A short numeric string, such as ``\texttt{1.1}''. This is a
+  build of a revision of Mercurial that was identified by a specific
+  tag in the repository where it was built.  (This doesn't necessarily
+  mean that you're running an official release; someone else could
+  have added that tag to any revision in the repository where they
+  built Mercurial.)
+\item A hexadecimal string, such as ``\texttt{875489e31abe}''.  This
+  is a build of the given revision of Mercurial.
+\item A hexadecimal string followed by a date, such as
+  ``\texttt{875489e31abe+20070205}''.  This is a build of the given
+  revision of Mercurial, where the build repository contained some
+  local changes that had not been committed.
+\end{itemize}
+
+\subsection{Tips and tricks}
+
+\subsubsection{Why do the results of \hgcmd{diff} and \hgcmd{status}
+  differ?}
+\label{cmdref:diff-vs-status}
+
+When you run the \hgcmd{status} command, you'll see a list of files
+that Mercurial will record changes for the next time you perform a
+commit.  If you run the \hgcmd{diff} command, you may notice that it
+prints diffs for only a \emph{subset} of the files that \hgcmd{status}
+listed.  There are two possible reasons for this.
+
+The first is that \hgcmd{status} prints some kinds of modifications
+that \hgcmd{diff} doesn't normally display.  The \hgcmd{diff} command
+normally outputs unified diffs, which don't have the ability to
+represent some changes that Mercurial can track.  Most notably,
+traditional diffs can't represent a change in whether or not a file is
+executable, but Mercurial records this information.
+
+If you use the \hgopt{diff}{--git} option to \hgcmd{diff}, it will
+display \command{git}-compatible diffs that \emph{can} display this
+extra information.
+
+The second possible reason that \hgcmd{diff} might be printing diffs
+for a subset of the files displayed by \hgcmd{status} is that if you
+invoke it without any arguments, \hgcmd{diff} prints diffs against the
+first parent of the working directory.  If you have run \hgcmd{merge}
+to merge two changesets, but you haven't yet committed the results of
+the merge, your working directory has two parents (use \hgcmd{parents}
+to see them).  While \hgcmd{status} prints modifications relative to
+\emph{both} parents after an uncommitted merge, \hgcmd{diff} still
+operates relative only to the first parent.  You can get it to print
+diffs relative to the second parent by specifying that parent with the
+\hgopt{diff}{-r} option.  There is no way to print diffs relative to
+both parents.
+
+\subsubsection{Generating safe binary diffs}
+
+If you use the \hgopt{diff}{-a} option to force Mercurial to print
+diffs of files that are either ``mostly text'' or contain lots of
+binary data, those diffs cannot subsequently be applied by either
+Mercurial's \hgcmd{import} command or the system's \command{patch}
+command.  
+
+If you want to generate a diff of a binary file that is safe to use as
+input for \hgcmd{import}, use the \hgcmd{diff}{--git} option when you
+generate the patch.  The system \command{patch} command cannot handle
+binary patches at all.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
+\chapter{Collaborating with other people}
+\label{cha:collab}
+
+As a completely decentralised tool, Mercurial doesn't impose any
+policy on how people ought to work with each other.  However, if
+you're new to distributed revision control, it helps to have some
+tools and examples in mind when you're thinking about possible
+workflow models.
+
+\section{Mercurial's web interface}
+
+Mercurial has a powerful web interface that provides several 
+useful capabilities.
+
+For interactive use, the web interface lets you browse a single
+repository or a collection of repositories.  You can view the history
+of a repository, examine each change (comments and diffs), and view
+the contents of each directory and file.
+
+Also for human consumption, the web interface provides an RSS feed of
+the changes in a repository.  This lets you ``subscribe'' to a
+repository using your favourite feed reader, and be automatically
+notified of activity in that repository as soon as it happens.  I find
+this capability much more convenient than the model of subscribing to
+a mailing list to which notifications are sent, as it requires no
+additional configuration on the part of whoever is serving the
+repository.
+
+The web interface also lets remote users clone a repository, pull
+changes from it, and (when the server is configured to permit it) push
+changes back to it.  Mercurial's HTTP tunneling protocol aggressively
+compresses data, so that it works efficiently even over low-bandwidth
+network connections.
+
+The easiest way to get started with the web interface is to use your
+web browser to visit an existing repository, such as the master
+Mercurial repository at
+\url{http://www.selenic.com/repo/hg?style=gitweb}.
+
+If you're interested in providing a web interface to your own
+repositories, Mercurial provides two ways to do this.  The first is
+using the \hgcmd{serve} command, which is best suited to short-term
+``lightweight'' serving.  See section~\ref{sec:collab:serve} below for
+details of how to use this command.  If you have a long-lived
+repository that you'd like to make permanently available, Mercurial
+has built-in support for the CGI (Common Gateway Interface) standard,
+which all common web servers support.  See
+section~\ref{sec:collab:cgi} for details of CGI configuration.
+
+\section{Collaboration models}
+
+With a suitably flexible tool, making decisions about workflow is much
+more of a social engineering challenge than a technical one.
+Mercurial imposes few limitations on how you can structure the flow of
+work in a project, so it's up to you and your group to set up and live
+with a model that matches your own particular needs.
+
+\subsection{Factors to keep in mind}
+
+The most important aspect of any model that you must keep in mind is
+how well it matches the needs and capabilities of the people who will
+be using it.  This might seem self-evident; even so, you still can't
+afford to forget it for a moment.
+
+I once put together a workflow model that seemed to make perfect sense
+to me, but that caused a considerable amount of consternation and
+strife within my development team.  In spite of my attempts to explain
+why we needed a complex set of branches, and how changes ought to flow
+between them, a few team members revolted.  Even though they were
+smart people, they didn't want to pay attention to the constraints we
+were operating under, or face the consequences of those constraints in
+the details of the model that I was advocating.
+
+Don't sweep foreseeable social or technical problems under the rug.
+Whatever scheme you put into effect, you should plan for mistakes and
+problem scenarios.  Consider adding automated machinery to prevent, or
+quickly recover from, trouble that you can anticipate.  As an example,
+if you intend to have a branch with not-for-release changes in it,
+you'd do well to think early about the possibility that someone might
+accidentally merge those changes into a release branch.  You could
+avoid this particular problem by writing a hook that prevents changes
+from being merged from an inappropriate branch.
+
+\subsection{Informal anarchy}
+
+I wouldn't suggest an ``anything goes'' approach as something
+sustainable, but it's a model that's easy to grasp, and it works
+perfectly well in a few unusual situations.
+
+As one example, many projects have a loose-knit group of collaborators
+who rarely physically meet each other.  Some groups like to overcome
+the isolation of working at a distance by organising occasional
+``sprints''.  In a sprint, a number of people get together in a single
+location (a company's conference room, a hotel meeting room, that kind
+of place) and spend several days more or less locked in there, hacking
+intensely on a handful of projects.
+
+A sprint is the perfect place to use the \hgcmd{serve} command, since
+\hgcmd{serve} does not requires any fancy server infrastructure.  You
+can get started with \hgcmd{serve} in moments, by reading
+section~\ref{sec:collab:serve} below.  Then simply tell the person
+next to you that you're running a server, send the URL to them in an
+instant message, and you immediately have a quick-turnaround way to
+work together.  They can type your URL into their web browser and
+quickly review your changes; or they can pull a bugfix from you and
+verify it; or they can clone a branch containing a new feature and try
+it out.
+
+The charm, and the problem, with doing things in an ad hoc fashion
+like this is that only people who know about your changes, and where
+they are, can see them.  Such an informal approach simply doesn't
+scale beyond a handful people, because each individual needs to know
+about $n$ different repositories to pull from.
+
+\subsection{A single central repository}
+
+For smaller projects migrating from a centralised revision control
+tool, perhaps the easiest way to get started is to have changes flow
+through a single shared central repository.  This is also the
+most common ``building block'' for more ambitious workflow schemes.
+
+Contributors start by cloning a copy of this repository.  They can
+pull changes from it whenever they need to, and some (perhaps all)
+developers have permission to push a change back when they're ready
+for other people to see it.
+
+Under this model, it can still often make sense for people to pull
+changes directly from each other, without going through the central
+repository.  Consider a case in which I have a tentative bug fix, but
+I am worried that if I were to publish it to the central repository,
+it might subsequently break everyone else's trees as they pull it.  To
+reduce the potential for damage, I can ask you to clone my repository
+into a temporary repository of your own and test it.  This lets us put
+off publishing the potentially unsafe change until it has had a little
+testing.
+
+In this kind of scenario, people usually use the \command{ssh}
+protocol to securely push changes to the central repository, as
+documented in section~\ref{sec:collab:ssh}.  It's also usual to
+publish a read-only copy of the repository over HTTP using CGI, as in
+section~\ref{sec:collab:cgi}.  Publishing over HTTP satisfies the
+needs of people who don't have push access, and those who want to use
+web browsers to browse the repository's history.
+
+\subsection{Working with multiple branches}
+
+Projects of any significant size naturally tend to make progress on
+several fronts simultaneously.  In the case of software, it's common
+for a project to go through periodic official releases.  A release
+might then go into ``maintenance mode'' for a while after its first
+publication; maintenance releases tend to contain only bug fixes, not
+new features.  In parallel with these maintenance releases, one or
+more future releases may be under development.  People normally use
+the word ``branch'' to refer to one of these many slightly different
+directions in which development is proceeding.
+
+Mercurial is particularly well suited to managing a number of
+simultaneous, but not identical, branches.  Each ``development
+direction'' can live in its own central repository, and you can merge
+changes from one to another as the need arises.  Because repositories
+are independent of each other, unstable changes in a development
+branch will never affect a stable branch unless someone explicitly
+merges those changes in.
+
+Here's an example of how this can work in practice.  Let's say you
+have one ``main branch'' on a central server.
+\interaction{branching.init}
+People clone it, make changes locally, test them, and push them back.
+
+Once the main branch reaches a release milestone, you can use the
+\hgcmd{tag} command to give a permanent name to the milestone
+revision.
+\interaction{branching.tag}
+Let's say some ongoing development occurs on the main branch.
+\interaction{branching.main}
+Using the tag that was recorded at the milestone, people who clone
+that repository at any time in the future can use \hgcmd{update} to
+get a copy of the working directory exactly as it was when that tagged
+revision was committed.  
+\interaction{branching.update}
+
+In addition, immediately after the main branch is tagged, someone can
+then clone the main branch on the server to a new ``stable'' branch,
+also on the server.
+\interaction{branching.clone}
+
+Someone who needs to make a change to the stable branch can then clone
+\emph{that} repository, make their changes, commit, and push their
+changes back there.
+\interaction{branching.stable}
+Because Mercurial repositories are independent, and Mercurial doesn't
+move changes around automatically, the stable and main branches are
+\emph{isolated} from each other.  The changes that you made on the
+main branch don't ``leak'' to the stable branch, and vice versa.
+
+You'll often want all of your bugfixes on the stable branch to show up
+on the main branch, too.  Rather than rewrite a bugfix on the main
+branch, you can simply pull and merge changes from the stable to the
+main branch, and Mercurial will bring those bugfixes in for you.
+\interaction{branching.merge}
+The main branch will still contain changes that are not on the stable
+branch, but it will also contain all of the bugfixes from the stable
+branch.  The stable branch remains unaffected by these changes.
+
+\subsection{Feature branches}
+
+For larger projects, an effective way to manage change is to break up
+a team into smaller groups.  Each group has a shared branch of its
+own, cloned from a single ``master'' branch used by the entire
+project.  People working on an individual branch are typically quite
+isolated from developments on other branches.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{feature-branches}
+  \caption{Feature branches}
+  \label{fig:collab:feature-branches}
+\end{figure}
+
+When a particular feature is deemed to be in suitable shape, someone
+on that feature team pulls and merges from the master branch into the
+feature branch, then pushes back up to the master branch.
+
+\subsection{The release train}
+
+Some projects are organised on a ``train'' basis: a release is
+scheduled to happen every few months, and whatever features are ready
+when the ``train'' is ready to leave are allowed in.
+
+This model resembles working with feature branches.  The difference is
+that when a feature branch misses a train, someone on the feature team
+pulls and merges the changes that went out on that train release into
+the feature branch, and the team continues its work on top of that
+release so that their feature can make the next release.
+
+\subsection{The Linux kernel model}
+
+The development of the Linux kernel has a shallow hierarchical
+structure, surrounded by a cloud of apparent chaos.  Because most
+Linux developers use \command{git}, a distributed revision control
+tool with capabilities similar to Mercurial, it's useful to describe
+the way work flows in that environment; if you like the ideas, the
+approach translates well across tools.
+
+At the center of the community sits Linus Torvalds, the creator of
+Linux.  He publishes a single source repository that is considered the
+``authoritative'' current tree by the entire developer community.
+Anyone can clone Linus's tree, but he is very choosy about whose trees
+he pulls from.
+
+Linus has a number of ``trusted lieutenants''.  As a general rule, he
+pulls whatever changes they publish, in most cases without even
+reviewing those changes.  Some of those lieutenants are generally
+agreed to be ``maintainers'', responsible for specific subsystems
+within the kernel.  If a random kernel hacker wants to make a change
+to a subsystem that they want to end up in Linus's tree, they must
+find out who the subsystem's maintainer is, and ask that maintainer to
+take their change.  If the maintainer reviews their changes and agrees
+to take them, they'll pass them along to Linus in due course.
+
+Individual lieutenants have their own approaches to reviewing,
+accepting, and publishing changes; and for deciding when to feed them
+to Linus.  In addition, there are several well known branches that
+people use for different purposes.  For example, a few people maintain
+``stable'' repositories of older versions of the kernel, to which they
+apply critical fixes as needed.  Some maintainers publish multiple
+trees: one for experimental changes; one for changes that they are
+about to feed upstream; and so on.  Others just publish a single
+tree.
+
+This model has two notable features.  The first is that it's ``pull
+only''.  You have to ask, convince, or beg another developer to take a
+change from you, because there are almost no trees to which more than
+one person can push, and there's no way to push changes into a tree
+that someone else controls.
+
+The second is that it's based on reputation and acclaim.  If you're an
+unknown, Linus will probably ignore changes from you without even
+responding.  But a subsystem maintainer will probably review them, and
+will likely take them if they pass their criteria for suitability.
+The more ``good'' changes you contribute to a maintainer, the more
+likely they are to trust your judgment and accept your changes.  If
+you're well-known and maintain a long-lived branch for something Linus
+hasn't yet accepted, people with similar interests may pull your
+changes regularly to keep up with your work.
+
+Reputation and acclaim don't necessarily cross subsystem or ``people''
+boundaries.  If you're a respected but specialised storage hacker, and
+you try to fix a networking bug, that change will receive a level of
+scrutiny from a network maintainer comparable to a change from a
+complete stranger.
+
+To people who come from more orderly project backgrounds, the
+comparatively chaotic Linux kernel development process often seems
+completely insane.  It's subject to the whims of individuals; people
+make sweeping changes whenever they deem it appropriate; and the pace
+of development is astounding.  And yet Linux is a highly successful,
+well-regarded piece of software.
+
+\subsection{Pull-only versus shared-push collaboration}
+
+A perpetual source of heat in the open source community is whether a
+development model in which people only ever pull changes from others
+is ``better than'' one in which multiple people can push changes to a
+shared repository.
+
+Typically, the backers of the shared-push model use tools that
+actively enforce this approach.  If you're using a centralised
+revision control tool such as Subversion, there's no way to make a
+choice over which model you'll use: the tool gives you shared-push,
+and if you want to do anything else, you'll have to roll your own
+approach on top (such as applying a patch by hand).
+
+A good distributed revision control tool, such as Mercurial, will
+support both models.  You and your collaborators can then structure
+how you work together based on your own needs and preferences, not on
+what contortions your tools force you into.
+
+\subsection{Where collaboration meets branch management}
+
+Once you and your team set up some shared repositories and start
+propagating changes back and forth between local and shared repos, you
+begin to face a related, but slightly different challenge: that of
+managing the multiple directions in which your team may be moving at
+once.  Even though this subject is intimately related to how your team
+collaborates, it's dense enough to merit treatment of its own, in
+chapter~\ref{chap:branch}.
+
+\section{The technical side of sharing}
+
+The remainder of this chapter is devoted to the question of serving
+data to your collaborators.
+
+\section{Informal sharing with \hgcmd{serve}}
+\label{sec:collab:serve}
+
+Mercurial's \hgcmd{serve} command is wonderfully suited to small,
+tight-knit, and fast-paced group environments.  It also provides a
+great way to get a feel for using Mercurial commands over a network.
+
+Run \hgcmd{serve} inside a repository, and in under a second it will
+bring up a specialised HTTP server; this will accept connections from
+any client, and serve up data for that repository until you terminate
+it.  Anyone who knows the URL of the server you just started, and can
+talk to your computer over the network, can then use a web browser or
+Mercurial to read data from that repository.  A URL for a
+\hgcmd{serve} instance running on a laptop is likely to look something
+like \Verb|http://my-laptop.local:8000/|.
+
+The \hgcmd{serve} command is \emph{not} a general-purpose web server.
+It can do only two things:
+\begin{itemize}
+\item Allow people to browse the history of the repository it's
+  serving, from their normal web browsers.
+\item Speak Mercurial's wire protocol, so that people can
+  \hgcmd{clone} or \hgcmd{pull} changes from that repository.
+\end{itemize}
+In particular, \hgcmd{serve} won't allow remote users to \emph{modify}
+your repository.  It's intended for read-only use.
+
+If you're getting started with Mercurial, there's nothing to prevent
+you from using \hgcmd{serve} to serve up a repository on your own
+computer, then use commands like \hgcmd{clone}, \hgcmd{incoming}, and
+so on to talk to that server as if the repository was hosted remotely.
+This can help you to quickly get acquainted with using commands on
+network-hosted repositories.
+
+\subsection{A few things to keep in mind}
+
+Because it provides unauthenticated read access to all clients, you
+should only use \hgcmd{serve} in an environment where you either don't
+care, or have complete control over, who can access your network and
+pull data from your repository.
+
+The \hgcmd{serve} command knows nothing about any firewall software
+you might have installed on your system or network.  It cannot detect
+or control your firewall software.  If other people are unable to talk
+to a running \hgcmd{serve} instance, the second thing you should do
+(\emph{after} you make sure that they're using the correct URL) is
+check your firewall configuration.
+
+By default, \hgcmd{serve} listens for incoming connections on
+port~8000.  If another process is already listening on the port you
+want to use, you can specify a different port to listen on using the
+\hgopt{serve}{-p} option.
+
+Normally, when \hgcmd{serve} starts, it prints no output, which can be
+a bit unnerving.  If you'd like to confirm that it is indeed running
+correctly, and find out what URL you should send to your
+collaborators, start it with the \hggopt{-v} option.
+
+\section{Using the Secure Shell (ssh) protocol}
+\label{sec:collab:ssh}
+
+You can pull and push changes securely over a network connection using
+the Secure Shell (\texttt{ssh}) protocol.  To use this successfully,
+you may have to do a little bit of configuration on the client or
+server sides.
+
+If you're not familiar with ssh, it's a network protocol that lets you
+securely communicate with another computer.  To use it with Mercurial,
+you'll be setting up one or more user accounts on a server so that
+remote users can log in and execute commands.
+
+(If you \emph{are} familiar with ssh, you'll probably find some of the
+material that follows to be elementary in nature.)
+
+\subsection{How to read and write ssh URLs}
+
+An ssh URL tends to look like this:
+\begin{codesample2}
+  ssh://bos@hg.serpentine.com:22/hg/hgbook
+\end{codesample2}
+\begin{enumerate}
+\item The ``\texttt{ssh://}'' part tells Mercurial to use the ssh
+  protocol.
+\item The ``\texttt{bos@}'' component indicates what username to log
+  into the server as.  You can leave this out if the remote username
+  is the same as your local username.
+\item The ``\texttt{hg.serpentine.com}'' gives the hostname of the
+  server to log into.
+\item The ``:22'' identifies the port number to connect to the server
+  on.  The default port is~22, so you only need to specify this part
+  if you're \emph{not} using port~22.
+\item The remainder of the URL is the local path to the repository on
+  the server.
+\end{enumerate}
+
+There's plenty of scope for confusion with the path component of ssh
+URLs, as there is no standard way for tools to interpret it.  Some
+programs behave differently than others when dealing with these paths.
+This isn't an ideal situation, but it's unlikely to change.  Please
+read the following paragraphs carefully.
+
+Mercurial treats the path to a repository on the server as relative to
+the remote user's home directory.  For example, if user \texttt{foo}
+on the server has a home directory of \dirname{/home/foo}, then an ssh
+URL that contains a path component of \dirname{bar}
+\emph{really} refers to the directory \dirname{/home/foo/bar}.
+
+If you want to specify a path relative to another user's home
+directory, you can use a path that starts with a tilde character
+followed by the user's name (let's call them \texttt{otheruser}), like
+this.
+\begin{codesample2}
+  ssh://server/~otheruser/hg/repo
+\end{codesample2}
+
+And if you really want to specify an \emph{absolute} path on the
+server, begin the path component with two slashes, as in this example.
+\begin{codesample2}
+  ssh://server//absolute/path
+\end{codesample2}
+
+\subsection{Finding an ssh client for your system}
+
+Almost every Unix-like system comes with OpenSSH preinstalled.  If
+you're using such a system, run \Verb|which ssh| to find out if
+the \command{ssh} command is installed (it's usually in
+\dirname{/usr/bin}).  In the unlikely event that it isn't present,
+take a look at your system documentation to figure out how to install
+it.
+
+On Windows, you'll first need to download a suitable ssh
+client.  There are two alternatives.
+\begin{itemize}
+\item Simon Tatham's excellent PuTTY package~\cite{web:putty} provides
+  a complete suite of ssh client commands.
+\item If you have a high tolerance for pain, you can use the Cygwin
+  port of OpenSSH.
+\end{itemize}
+In either case, you'll need to edit your \hgini\ file to tell
+Mercurial where to find the actual client command.  For example, if
+you're using PuTTY, you'll need to use the \command{plink} command as
+a command-line ssh client.
+\begin{codesample2}
+  [ui]
+  ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"
+\end{codesample2}
+
+\begin{note}
+  The path to \command{plink} shouldn't contain any whitespace
+  characters, or Mercurial may not be able to run it correctly (so
+  putting it in \dirname{C:\\Program Files} is probably not a good
+  idea).
+\end{note}
+
+\subsection{Generating a key pair}
+
+To avoid the need to repetitively type a password every time you need
+to use your ssh client, I recommend generating a key pair.  On a
+Unix-like system, the \command{ssh-keygen} command will do the trick.
+On Windows, if you're using PuTTY, the \command{puttygen} command is
+what you'll need.
+
+When you generate a key pair, it's usually \emph{highly} advisable to
+protect it with a passphrase.  (The only time that you might not want
+to do this is when you're using the ssh protocol for automated tasks
+on a secure network.)
+
+Simply generating a key pair isn't enough, however.  You'll need to
+add the public key to the set of authorised keys for whatever user
+you're logging in remotely as.  For servers using OpenSSH (the vast
+majority), this will mean adding the public key to a list in a file
+called \sfilename{authorized\_keys} in their \sdirname{.ssh}
+directory.
+
+On a Unix-like system, your public key will have a \filename{.pub}
+extension.  If you're using \command{puttygen} on Windows, you can
+save the public key to a file of your choosing, or paste it from the
+window it's displayed in straight into the
+\sfilename{authorized\_keys} file.
+
+\subsection{Using an authentication agent}
+
+An authentication agent is a daemon that stores passphrases in memory
+(so it will forget passphrases if you log out and log back in again).
+An ssh client will notice if it's running, and query it for a
+passphrase.  If there's no authentication agent running, or the agent
+doesn't store the necessary passphrase, you'll have to type your
+passphrase every time Mercurial tries to communicate with a server on
+your behalf (e.g.~whenever you pull or push changes).
+
+The downside of storing passphrases in an agent is that it's possible
+for a well-prepared attacker to recover the plain text of your
+passphrases, in some cases even if your system has been power-cycled.
+You should make your own judgment as to whether this is an acceptable
+risk.  It certainly saves a lot of repeated typing.
+
+On Unix-like systems, the agent is called \command{ssh-agent}, and
+it's often run automatically for you when you log in.  You'll need to
+use the \command{ssh-add} command to add passphrases to the agent's
+store.  On Windows, if you're using PuTTY, the \command{pageant}
+command acts as the agent.  It adds an icon to your system tray that
+will let you manage stored passphrases.
+
+\subsection{Configuring the server side properly}
+
+Because ssh can be fiddly to set up if you're new to it, there's a
+variety of things that can go wrong.  Add Mercurial on top, and
+there's plenty more scope for head-scratching.  Most of these
+potential problems occur on the server side, not the client side.  The
+good news is that once you've gotten a configuration working, it will
+usually continue to work indefinitely.
+
+Before you try using Mercurial to talk to an ssh server, it's best to
+make sure that you can use the normal \command{ssh} or \command{putty}
+command to talk to the server first.  If you run into problems with
+using these commands directly, Mercurial surely won't work.  Worse, it
+will obscure the underlying problem.  Any time you want to debug
+ssh-related Mercurial problems, you should drop back to making sure
+that plain ssh client commands work first, \emph{before} you worry
+about whether there's a problem with Mercurial.
+
+The first thing to be sure of on the server side is that you can
+actually log in from another machine at all.  If you can't use
+\command{ssh} or \command{putty} to log in, the error message you get
+may give you a few hints as to what's wrong.  The most common problems
+are as follows.
+\begin{itemize}
+\item If you get a ``connection refused'' error, either there isn't an
+  SSH daemon running on the server at all, or it's inaccessible due to
+  firewall configuration.
+\item If you get a ``no route to host'' error, you either have an
+  incorrect address for the server or a seriously locked down firewall
+  that won't admit its existence at all.
+\item If you get a ``permission denied'' error, you may have mistyped
+  the username on the server, or you could have mistyped your key's
+  passphrase or the remote user's password.
+\end{itemize}
+In summary, if you're having trouble talking to the server's ssh
+daemon, first make sure that one is running at all.  On many systems
+it will be installed, but disabled, by default.  Once you're done with
+this step, you should then check that the server's firewall is
+configured to allow incoming connections on the port the ssh daemon is
+listening on (usually~22).  Don't worry about more exotic
+possibilities for misconfiguration until you've checked these two
+first.
+
+If you're using an authentication agent on the client side to store
+passphrases for your keys, you ought to be able to log into the server
+without being prompted for a passphrase or a password.  If you're
+prompted for a passphrase, there are a few possible culprits.
+\begin{itemize}
+\item You might have forgotten to use \command{ssh-add} or
+  \command{pageant} to store the passphrase.
+\item You might have stored the passphrase for the wrong key.
+\end{itemize}
+If you're being prompted for the remote user's password, there are
+another few possible problems to check.
+\begin{itemize}
+\item Either the user's home directory or their \sdirname{.ssh}
+  directory might have excessively liberal permissions.  As a result,
+  the ssh daemon will not trust or read their
+  \sfilename{authorized\_keys} file.  For example, a group-writable
+  home or \sdirname{.ssh} directory will often cause this symptom.
+\item The user's \sfilename{authorized\_keys} file may have a problem.
+  If anyone other than the user owns or can write to that file, the
+  ssh daemon will not trust or read it.
+\end{itemize}
+
+In the ideal world, you should be able to run the following command
+successfully, and it should print exactly one line of output, the
+current date and time.
+\begin{codesample2}
+  ssh myserver date
+\end{codesample2}
+
+If, on your server, you have login scripts that print banners or other
+junk even when running non-interactive commands like this, you should
+fix them before you continue, so that they only print output if
+they're run interactively.  Otherwise these banners will at least
+clutter up Mercurial's output.  Worse, they could potentially cause
+problems with running Mercurial commands remotely.  Mercurial makes
+tries to detect and ignore banners in non-interactive \command{ssh}
+sessions, but it is not foolproof.  (If you're editing your login
+scripts on your server, the usual way to see if a login script is
+running in an interactive shell is to check the return code from the
+command \Verb|tty -s|.)
+
+Once you've verified that plain old ssh is working with your server,
+the next step is to ensure that Mercurial runs on the server.  The
+following command should run successfully:
+\begin{codesample2}
+  ssh myserver hg version
+\end{codesample2}
+If you see an error message instead of normal \hgcmd{version} output,
+this is usually because you haven't installed Mercurial to
+\dirname{/usr/bin}.  Don't worry if this is the case; you don't need
+to do that.  But you should check for a few possible problems.
+\begin{itemize}
+\item Is Mercurial really installed on the server at all?  I know this
+  sounds trivial, but it's worth checking!
+\item Maybe your shell's search path (usually set via the \envar{PATH}
+  environment variable) is simply misconfigured.
+\item Perhaps your \envar{PATH} environment variable is only being set
+  to point to the location of the \command{hg} executable if the login
+  session is interactive.  This can happen if you're setting the path
+  in the wrong shell login script.  See your shell's documentation for
+  details.
+\item The \envar{PYTHONPATH} environment variable may need to contain
+  the path to the Mercurial Python modules.  It might not be set at
+  all; it could be incorrect; or it may be set only if the login is
+  interactive.
+\end{itemize}
+
+If you can run \hgcmd{version} over an ssh connection, well done!
+You've got the server and client sorted out.  You should now be able
+to use Mercurial to access repositories hosted by that username on
+that server.  If you run into problems with Mercurial and ssh at this
+point, try using the \hggopt{--debug} option to get a clearer picture
+of what's going on.
+
+\subsection{Using compression with ssh}
+
+Mercurial does not compress data when it uses the ssh protocol,
+because the ssh protocol can transparently compress data.  However,
+the default behaviour of ssh clients is \emph{not} to request
+compression.
+
+Over any network other than a fast LAN (even a wireless network),
+using compression is likely to significantly speed up Mercurial's
+network operations.  For example, over a WAN, someone measured
+compression as reducing the amount of time required to clone a
+particularly large repository from~51 minutes to~17 minutes.
+
+Both \command{ssh} and \command{plink} accept a \cmdopt{ssh}{-C}
+option which turns on compression.  You can easily edit your \hgrc\ to
+enable compression for all of Mercurial's uses of the ssh protocol.
+\begin{codesample2}
+  [ui]
+  ssh = ssh -C
+\end{codesample2}
+
+If you use \command{ssh}, you can configure it to always use
+compression when talking to your server.  To do this, edit your
+\sfilename{.ssh/config} file (which may not yet exist), as follows.
+\begin{codesample2}
+  Host hg
+    Compression yes
+    HostName hg.example.com
+\end{codesample2}
+This defines an alias, \texttt{hg}.  When you use it on the
+\command{ssh} command line or in a Mercurial \texttt{ssh}-protocol
+URL, it will cause \command{ssh} to connect to \texttt{hg.example.com}
+and use compression.  This gives you both a shorter name to type and
+compression, each of which is a good thing in its own right.
+
+\section{Serving over HTTP using CGI}
+\label{sec:collab:cgi}
+
+Depending on how ambitious you are, configuring Mercurial's CGI
+interface can take anything from a few moments to several hours.
+
+We'll begin with the simplest of examples, and work our way towards a
+more complex configuration.  Even for the most basic case, you're
+almost certainly going to need to read and modify your web server's
+configuration.
+
+\begin{note}
+  Configuring a web server is a complex, fiddly, and highly
+  system-dependent activity.  I can't possibly give you instructions
+  that will cover anything like all of the cases you will encounter.
+  Please use your discretion and judgment in following the sections
+  below.  Be prepared to make plenty of mistakes, and to spend a lot
+  of time reading your server's error logs.
+\end{note}
+
+\subsection{Web server configuration checklist}
+
+Before you continue, do take a few moments to check a few aspects of
+your system's setup.
+
+\begin{enumerate}
+\item Do you have a web server installed at all?  Mac OS X ships with
+  Apache, but many other systems may not have a web server installed.
+\item If you have a web server installed, is it actually running?  On
+  most systems, even if one is present, it will be disabled by
+  default.
+\item Is your server configured to allow you to run CGI programs in
+  the directory where you plan to do so?  Most servers default to
+  explicitly disabling the ability to run CGI programs.
+\end{enumerate}
+
+If you don't have a web server installed, and don't have substantial
+experience configuring Apache, you should consider using the
+\texttt{lighttpd} web server instead of Apache.  Apache has a
+well-deserved reputation for baroque and confusing configuration.
+While \texttt{lighttpd} is less capable in some ways than Apache, most
+of these capabilities are not relevant to serving Mercurial
+repositories.  And \texttt{lighttpd} is undeniably \emph{much} easier
+to get started with than Apache.
+
+\subsection{Basic CGI configuration}
+
+On Unix-like systems, it's common for users to have a subdirectory
+named something like \dirname{public\_html} in their home directory,
+from which they can serve up web pages.  A file named \filename{foo}
+in this directory will be accessible at a URL of the form
+\texttt{http://www.example.com/\~{}username/foo}.
+
+To get started, find the \sfilename{hgweb.cgi} script that should be
+present in your Mercurial installation.  If you can't quickly find a
+local copy on your system, simply download one from the master
+Mercurial repository at
+\url{http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi}.
+
+You'll need to copy this script into your \dirname{public\_html}
+directory, and ensure that it's executable.
+\begin{codesample2}
+  cp .../hgweb.cgi ~/public_html
+  chmod 755 ~/public_html/hgweb.cgi
+\end{codesample2}
+The \texttt{755} argument to \command{chmod} is a little more general
+than just making the script executable: it ensures that the script is
+executable by anyone, and that ``group'' and ``other'' write
+permissions are \emph{not} set.  If you were to leave those write
+permissions enabled, Apache's \texttt{suexec} subsystem would likely
+refuse to execute the script.  In fact, \texttt{suexec} also insists
+that the \emph{directory} in which the script resides must not be
+writable by others.
+\begin{codesample2}
+  chmod 755 ~/public_html
+\end{codesample2}
+
+\subsubsection{What could \emph{possibly} go wrong?}
+\label{sec:collab:wtf}
+
+Once you've copied the CGI script into place, go into a web browser,
+and try to open the URL \url{http://myhostname/~myuser/hgweb.cgi},
+\emph{but} brace yourself for instant failure.  There's a high
+probability that trying to visit this URL will fail, and there are
+many possible reasons for this.  In fact, you're likely to stumble
+over almost every one of the possible errors below, so please read
+carefully.  The following are all of the problems I ran into on a
+system running Fedora~7, with a fresh installation of Apache, and a
+user account that I created specially to perform this exercise.
+
+Your web server may have per-user directories disabled.  If you're
+using Apache, search your config file for a \texttt{UserDir}
+directive.  If there's none present, per-user directories will be
+disabled.  If one exists, but its value is \texttt{disabled}, then
+per-user directories will be disabled.  Otherwise, the string after
+\texttt{UserDir} gives the name of the subdirectory that Apache will
+look in under your home directory, for example \dirname{public\_html}.
+
+Your file access permissions may be too restrictive.  The web server
+must be able to traverse your home directory and directories under
+your \dirname{public\_html} directory, and read files under the latter
+too.  Here's a quick recipe to help you to make your permissions more
+appropriate.
+\begin{codesample2}
+  chmod 755 ~
+  find ~/public_html -type d -print0 | xargs -0r chmod 755
+  find ~/public_html -type f -print0 | xargs -0r chmod 644
+\end{codesample2}
+
+The other possibility with permissions is that you might get a
+completely empty window when you try to load the script.  In this
+case, it's likely that your access permissions are \emph{too
+  permissive}.  Apache's \texttt{suexec} subsystem won't execute a
+script that's group-~or world-writable, for example.
+
+Your web server may be configured to disallow execution of CGI
+programs in your per-user web directory.  Here's Apache's
+default per-user configuration from my Fedora system.
+\begin{codesample2}
+  <Directory /home/*/public_html>
+      AllowOverride FileInfo AuthConfig Limit
+      Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
+      <Limit GET POST OPTIONS>
+          Order allow,deny
+          Allow from all
+      </Limit>
+      <LimitExcept GET POST OPTIONS>
+          Order deny,allow
+          Deny from all
+      </LimitExcept>
+  </Directory>
+\end{codesample2}
+If you find a similar-looking \texttt{Directory} group in your Apache
+configuration, the directive to look at inside it is \texttt{Options}.
+Add \texttt{ExecCGI} to the end of this list if it's missing, and
+restart the web server.
+
+If you find that Apache serves you the text of the CGI script instead
+of executing it, you may need to either uncomment (if already present)
+or add a directive like this.
+\begin{codesample2}
+  AddHandler cgi-script .cgi
+\end{codesample2}
+
+The next possibility is that you might be served with a colourful
+Python backtrace claiming that it can't import a
+\texttt{mercurial}-related module.  This is actually progress!  The
+server is now capable of executing your CGI script.  This error is
+only likely to occur if you're running a private installation of
+Mercurial, instead of a system-wide version.  Remember that the web
+server runs the CGI program without any of the environment variables
+that you take for granted in an interactive session.  If this error
+happens to you, edit your copy of \sfilename{hgweb.cgi} and follow the
+directions inside it to correctly set your \envar{PYTHONPATH}
+environment variable.
+
+Finally, you are \emph{certain} to by served with another colourful
+Python backtrace: this one will complain that it can't find
+\dirname{/path/to/repository}.  Edit your \sfilename{hgweb.cgi} script
+and replace the \dirname{/path/to/repository} string with the complete
+path to the repository you want to serve up.
+
+At this point, when you try to reload the page, you should be
+presented with a nice HTML view of your repository's history.  Whew!
+
+\subsubsection{Configuring lighttpd}
+
+To be exhaustive in my experiments, I tried configuring the
+increasingly popular \texttt{lighttpd} web server to serve the same
+repository as I described with Apache above.  I had already overcome
+all of the problems I outlined with Apache, many of which are not
+server-specific.  As a result, I was fairly sure that my file and
+directory permissions were good, and that my \sfilename{hgweb.cgi}
+script was properly edited.
+
+Once I had Apache running, getting \texttt{lighttpd} to serve the
+repository was a snap (in other words, even if you're trying to use
+\texttt{lighttpd}, you should read the Apache section).  I first had
+to edit the \texttt{mod\_access} section of its config file to enable
+\texttt{mod\_cgi} and \texttt{mod\_userdir}, both of which were
+disabled by default on my system.  I then added a few lines to the end
+of the config file, to configure these modules.
+\begin{codesample2}
+  userdir.path = "public_html"
+  cgi.assign = ( ".cgi" => "" )
+\end{codesample2}
+With this done, \texttt{lighttpd} ran immediately for me.  If I had
+configured \texttt{lighttpd} before Apache, I'd almost certainly have
+run into many of the same system-level configuration problems as I did
+with Apache.  However, I found \texttt{lighttpd} to be noticeably
+easier to configure than Apache, even though I've used Apache for over
+a decade, and this was my first exposure to \texttt{lighttpd}.
+
+\subsection{Sharing multiple repositories with one CGI script}
+
+The \sfilename{hgweb.cgi} script only lets you publish a single
+repository, which is an annoying restriction.  If you want to publish
+more than one without wracking yourself with multiple copies of the
+same script, each with different names, a better choice is to use the
+\sfilename{hgwebdir.cgi} script.
+
+The procedure to configure \sfilename{hgwebdir.cgi} is only a little
+more involved than for \sfilename{hgweb.cgi}.  First, you must obtain
+a copy of the script.  If you don't have one handy, you can download a
+copy from the master Mercurial repository at
+\url{http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi}.
+
+You'll need to copy this script into your \dirname{public\_html}
+directory, and ensure that it's executable.
+\begin{codesample2}
+  cp .../hgwebdir.cgi ~/public_html
+  chmod 755 ~/public_html ~/public_html/hgwebdir.cgi
+\end{codesample2}
+With basic configuration out of the way, try to visit
+\url{http://myhostname/~myuser/hgwebdir.cgi} in your browser.  It
+should display an empty list of repositories.  If you get a blank
+window or error message, try walking through the list of potential
+problems in section~\ref{sec:collab:wtf}.
+
+The \sfilename{hgwebdir.cgi} script relies on an external
+configuration file.  By default, it searches for a file named
+\sfilename{hgweb.config} in the same directory as itself.  You'll need
+to create this file, and make it world-readable.  The format of the
+file is similar to a Windows ``ini'' file, as understood by Python's
+\texttt{ConfigParser}~\cite{web:configparser} module.
+
+The easiest way to configure \sfilename{hgwebdir.cgi} is with a
+section named \texttt{collections}.  This will automatically publish
+\emph{every} repository under the directories you name.  The section
+should look like this:
+\begin{codesample2}
+  [collections]
+  /my/root = /my/root
+\end{codesample2}
+Mercurial interprets this by looking at the directory name on the
+\emph{right} hand side of the ``\texttt{=}'' sign; finding
+repositories in that directory hierarchy; and using the text on the
+\emph{left} to strip off matching text from the names it will actually
+list in the web interface.  The remaining component of a path after
+this stripping has occurred is called a ``virtual path''.
+
+Given the example above, if we have a repository whose local path is
+\dirname{/my/root/this/repo}, the CGI script will strip the leading
+\dirname{/my/root} from the name, and publish the repository with a
+virtual path of \dirname{this/repo}.  If the base URL for our CGI
+script is \url{http://myhostname/~myuser/hgwebdir.cgi}, the complete
+URL for that repository will be
+\url{http://myhostname/~myuser/hgwebdir.cgi/this/repo}.