changeset 776:019040fbf5f5

merged to upstream: phase 1
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 21 Apr 2009 00:36:40 +0900
parents 5981a0f7540a (current diff) 29f0f79cf614 (diff)
children 3274ff6650df
files en/00book.tex en/99book.bib en/99defs.tex en/Makefile en/bookhtml.cfg en/branch.tex en/cmdref.tex en/collab.tex en/concepts.tex en/daily.tex en/examples/backout.init.out en/examples/backout.manual.backout.out en/examples/backout.manual.cat.out en/examples/backout.manual.clone.out en/examples/backout.manual.heads.out en/examples/backout.manual.log.out en/examples/backout.manual.merge.out en/examples/backout.manual.parents.out en/examples/backout.non-tip.backout.out en/examples/backout.non-tip.cat.out en/examples/backout.non-tip.clone.out en/examples/backout.simple.log.out en/examples/backout.simple.out en/examples/bisect.commits.out en/examples/bisect.help.out en/examples/bisect.init.out en/examples/bisect.search.bad-init.out en/examples/bisect.search.good-init.out en/examples/bisect.search.init.out en/examples/bisect.search.mytest.out en/examples/bisect.search.reset.out en/examples/bisect.search.rest.out en/examples/bisect.search.step1.out en/examples/bisect.search.step2.out en/examples/branch-named.branch.out en/examples/branch-named.branches.out en/examples/branch-named.commit.out en/examples/branch-named.create.out en/examples/branch-named.foo-commit.out en/examples/branch-named.merge.out en/examples/branch-named.parents.out en/examples/branch-named.rebranch.out en/examples/branch-named.status.out en/examples/branch-named.update-bar.out en/examples/branch-named.update-foo.out en/examples/branch-named.update-nothing.out en/examples/branch-named.update-switchy.out en/examples/branch-named.update.out en/examples/branch-repo.bugfix.out en/examples/branch-repo.clone.out en/examples/branch-repo.merge.out en/examples/branch-repo.new.out en/examples/branch-repo.pull.out en/examples/branch-repo.tag.out en/examples/branching.clone.out en/examples/branching.init.out en/examples/branching.main.out en/examples/branching.merge.out en/examples/branching.stable.out en/examples/branching.tag.out en/examples/branching.update.out en/examples/cmdref.diff-p.out en/examples/daily.copy.after.out en/examples/daily.copy.cat.out en/examples/daily.copy.clone.out en/examples/daily.copy.copy.out en/examples/daily.copy.dir-dest.out en/examples/daily.copy.dir-src-dest.out en/examples/daily.copy.dir-src.out en/examples/daily.copy.init.out en/examples/daily.copy.merge.out en/examples/daily.copy.other.out en/examples/daily.copy.simple.out en/examples/daily.copy.status-copy.out en/examples/daily.copy.status.out en/examples/daily.files.add-dir.out en/examples/daily.files.add.out en/examples/daily.files.addremove.out en/examples/daily.files.commit-addremove.out en/examples/daily.files.hidden.out en/examples/daily.files.missing.out en/examples/daily.files.recover-missing.out en/examples/daily.files.remove-after.out en/examples/daily.files.remove.out en/examples/daily.rename.rename.out en/examples/daily.rename.status-copy.out en/examples/daily.rename.status.out en/examples/daily.revert.add.out en/examples/daily.revert.copy.out en/examples/daily.revert.missing.out en/examples/daily.revert.modify.out en/examples/daily.revert.remove.out en/examples/daily.revert.rename-orig.out en/examples/daily.revert.rename.out en/examples/daily.revert.status.out en/examples/daily.revert.unmodify.out en/examples/extdiff.diff.out en/examples/extdiff.extdiff-ctx.out en/examples/extdiff.extdiff.out en/examples/filenames.dirs.out en/examples/filenames.files.out en/examples/filenames.filter.exclude.out en/examples/filenames.filter.include.out en/examples/filenames.glob.group.out en/examples/filenames.glob.question.out en/examples/filenames.glob.range.out en/examples/filenames.glob.star-starstar.out en/examples/filenames.glob.star.out en/examples/filenames.glob.starstar.out en/examples/filenames.wdir-relname.out en/examples/filenames.wdir-subdir.out en/examples/hook.msglen.go.out en/examples/hook.msglen.run.out en/examples/hook.simple.ext.out en/examples/hook.simple.init.out en/examples/hook.simple.pretxncommit.out en/examples/hook.ws.better.out en/examples/hook.ws.simple.out en/examples/issue29.go.out en/examples/mq.dodiff.diff.out en/examples/mq.guards.init.out en/examples/mq.guards.qguard.neg.out en/examples/mq.guards.qguard.out en/examples/mq.guards.qguard.pos.out en/examples/mq.guards.qselect.cat.out en/examples/mq.guards.qselect.error.out en/examples/mq.guards.qselect.foo.out en/examples/mq.guards.qselect.foobar.out en/examples/mq.guards.qselect.qpush.out en/examples/mq.guards.qselect.quux.out en/examples/mq.guards.series.out en/examples/mq.id.out.out en/examples/mq.id.output.out en/examples/mq.qinit-help.help.out en/examples/mq.tarball.download.out en/examples/mq.tarball.newsource.out en/examples/mq.tarball.qinit.out en/examples/mq.tarball.repush.out en/examples/mq.tools.lsdiff.out en/examples/mq.tools.tools.out en/examples/mq.tutorial.add.out en/examples/mq.tutorial.qinit.out en/examples/mq.tutorial.qnew.out en/examples/mq.tutorial.qnew2.out en/examples/mq.tutorial.qpop.out en/examples/mq.tutorial.qpush-a.out en/examples/mq.tutorial.qrefresh.out en/examples/mq.tutorial.qrefresh2.out en/examples/mq.tutorial.qseries.out en/examples/rename.divergent.clone.out en/examples/rename.divergent.merge.out en/examples/rename.divergent.rename.anne.out en/examples/rename.divergent.rename.bob.out en/examples/rollback.add.out en/examples/rollback.commit.out en/examples/rollback.rollback.out en/examples/rollback.status.out en/examples/rollback.tip.out en/examples/rollback.twice.out en/examples/run-example en/examples/tag.init.out en/examples/tag.log.out en/examples/tag.log.v1.0.out en/examples/tag.remove.out en/examples/tag.replace.out en/examples/tag.tag.out en/examples/tag.tags.out en/examples/tag.tip.out en/examples/template.simple.changelog.out en/examples/template.simple.combine.out en/examples/template.simple.compact.out en/examples/template.simple.datekeyword.out en/examples/template.simple.keywords.out en/examples/template.simple.manyfilters.out en/examples/template.simple.normal.out en/examples/template.simple.rev.out en/examples/template.simple.simplest.out en/examples/template.simple.simplesub.out en/examples/template.svnstyle.id.out en/examples/template.svnstyle.result.out en/examples/template.svnstyle.short.out en/examples/template.svnstyle.simplest.out en/examples/template.svnstyle.style.out en/examples/template.svnstyle.syntax.error.out en/examples/template.svnstyle.syntax.input.out en/examples/template.svnstyle.template.out en/examples/tour-merge-conflict.commit.out en/examples/tour-merge-conflict.cousin.out en/examples/tour-merge-conflict.merge.out en/examples/tour-merge-conflict.pull.out en/examples/tour-merge-conflict.son.out en/examples/tour-merge-conflict.wife.out en/examples/tour.clone-pull.out en/examples/tour.clone-push.out en/examples/tour.clone.out en/examples/tour.commit.out en/examples/tour.diff.out en/examples/tour.help.out en/examples/tour.incoming.out en/examples/tour.log-r.out en/examples/tour.log-v.out en/examples/tour.log-vp.out en/examples/tour.log.out en/examples/tour.log.range.out en/examples/tour.ls-a.out en/examples/tour.ls.out en/examples/tour.merge.cat.out en/examples/tour.merge.clone.out en/examples/tour.merge.commit.out en/examples/tour.merge.heads.out en/examples/tour.merge.merge.out en/examples/tour.merge.parents.out en/examples/tour.merge.pull.out en/examples/tour.merge.tip.out en/examples/tour.merge.update.out en/examples/tour.older.out en/examples/tour.outgoing.net.out en/examples/tour.outgoing.out en/examples/tour.parents.out en/examples/tour.pull.out en/examples/tour.push.net.out en/examples/tour.push.nothing.out en/examples/tour.push.out en/examples/tour.reclone.out en/examples/tour.sed.out en/examples/tour.status.out en/examples/tour.tip.out en/examples/tour.update.out en/examples/tour.version.out en/feature-branches.dot en/filelog.svg en/filenames.tex en/fixhtml.py en/hgbook.css en/hgext.tex en/hook.tex en/htlatex.book en/intro.tex en/kdiff3.png en/license.tex en/metadata.svg en/mq-collab.tex en/mq-ref.tex en/mq-stack.svg en/mq.tex en/note.png en/preface.tex en/revlog.svg en/snapshot.svg en/srcinstall.tex en/template.tex en/tour-basic.tex en/tour-history.svg en/tour-merge-conflict.svg en/tour-merge-merge.svg en/tour-merge-pull.svg en/tour-merge-sep-repos.svg en/tour-merge.tex en/undo-manual-merge.dot en/undo-manual.dot en/undo-non-tip.dot en/undo-simple.dot en/undo.tex en/wdir-after-commit.svg en/wdir-branch.svg en/wdir-merge.svg en/wdir-pre-branch.svg en/wdir.svg es/99defs.tex examples/hg-interdiff examples/hg-replay html/hgicon.png html/index.en.html html/index.html.var ja/Makefile ja/Makefile.orig ja/examples/bisect ja/examples/branch-named ja/examples/daily.files ja/examples/rename.divergent ja/examples/run-example ja/examples/template.svnstyle ja/examples/tour ja/examples/tour-merge-conflict sillybench/sillybench.py
diffstat 507 files changed, 63290 insertions(+), 19262 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Apr 20 23:50:34 2009 +0900
+++ b/.hgignore	Tue Apr 21 00:36:40 2009 +0900
@@ -1,37 +1,32 @@
-[^/]+/auto/
-[^/]+/dist/
-[^/]+/html/
+[^/]+/htdocs/
 
 syntax: glob
 
-beta/*.tex
-build_id.tex
-hg_id.tex
-*.4[ct][ct]
-*.aux
-*.bbl
-*.bib
-*.blg
-*.dvi
-*.eps
+*-tmp.*
 *.err
-*.idx
-*.ilg
-*.ind
-*.lg
-*.lo[fgt]
 *.lxo
+*.mo
 *.orig
-*/pdf/*.out
-*.pdf
+*.out
 *.png
-*.ps
+*.pyc
 *.rej
 *.run
-*.tmp
-*.toc
-*.xref
 *~
-.*.swp
+.*.sw[op]
 .\#*
 .run
+.validated-00book.xml
+Makefile.vars
+build
+en/all-ids.dat
+en/complete.xml
+en/examples/results
+en/html
+en/svn
+stylesheets/system-xsl
+tools
+web/hgbook/.database.sqlite3
+web/hgbook/secrets.py
+web/index-read.html.in
+xsl/system-xsl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,243 @@
+#
+# Makefile for the hgbook, top-level
+#
+include Makefile.vars
+
+FORMATS=html html-single pdf epub
+
+PO_LANGUAGES := zh
+DBK_LANGUAGES := en
+LANGUAGES := $(DBK_LANGUAGES) $(PO_LANGUAGES)
+
+UPDATEPO = PERLLIB=$(PO4A_LIB) $(PO4A_HOME)/po4a-updatepo -M UTF-8 \
+	   -f docbook -o doctype=docbook -o includeexternal \
+	   -o nodefault="<programlisting> <screen>" \
+	   -o untranslated="<programlisting> <screen>"
+TRANSLATE = PERLLIB=$(PO4A_LIB) $(PO4A_HOME)/po4a-translate -M UTF-8 \
+	   -f docbook -o doctype=docbook -o includeexternal \
+	   -o nodefault="<programlisting> <screen>" \
+	   -o untranslated="<programlisting> <screen>" \
+	   -k 0
+
+#rev_id = $(shell hg parents --template '{node|short} ({date|isodate})')
+rev_id = $(shell hg parents --template '{node|short} ({date|shortdate})')
+
+images := \
+	en/figs/feature-branches.png \
+	en/figs/filelog.png \
+	en/figs/metadata.png \
+	en/figs/mq-stack.png \
+	en/figs/revlog.png \
+	en/figs/snapshot.png \
+	en/figs/tour-history.png \
+	en/figs/tour-merge-conflict.png \
+	en/figs/tour-merge-merge.png \
+	en/figs/tour-merge-pull.png \
+	en/figs/tour-merge-sep-repos.png \
+	en/figs/undo-manual-merge.png \
+	en/figs/undo-manual.png \
+	en/figs/undo-non-tip.png \
+	en/figs/undo-simple.png \
+	en/figs/wdir-after-commit.png \
+	en/figs/wdir-branch.png \
+	en/figs/wdir-merge.png \
+	en/figs/wdir.png \
+	en/figs/wdir-pre-branch.png
+
+help:
+	@echo "  make epub         [LINGUA=en|zh|...]"
+	@echo "  make html         [LINGUA=en|zh|...]"
+	@echo "  make html-single  [LINGUA=en|zh|...]"
+	@echo "  make pdf          [LINGUA=en|zh|...]"
+	@echo "  make validate     [LINGUA=en|zh|...] # always before commit!"
+	@echo "  make tidypo       [LINGUA=zh|...]    # always before commit!"
+	@echo "  make updatepo     [LINGUA=zh|...]    # update po files."
+	@echo "  make all          [LINGUA=en|zh|...]"
+	@echo "  make stat         # print statistics about po files."
+	@echo "  make clean        # Remove the build files."
+
+clean:
+	@rm -fr build po/*.mo hello en/hello en/html en/.validated-00book.xml en/examples/.run en/examples/results \
+          stylesheets/system-xsl en/figs/*-tmp.svg \
+          en/figs/feature-branches.png \
+          en/figs/filelog.png \
+          en/figs/feature-branches.png \
+          en/figs/filelog.png \
+          en/figs/metadata.png \
+          en/figs/mq-stack.png \
+          en/figs/revlog.png \
+          en/figs/snapshot.png \
+          en/figs/tour-history.png \
+          en/figs/tour-merge-conflict.png \
+          en/figs/tour-merge-merge.png \
+          en/figs/tour-merge-pull.png \
+          en/figs/tour-merge-sep-repos.png \
+          en/figs/undo-manual-merge.png \
+          en/figs/undo-manual.png \
+          en/figs/undo-non-tip.png \
+          en/figs/undo-simple.png \
+          en/figs/wdir-after-commit.png \
+          en/figs/wdir-branch.png \
+          en/figs/wdir-merge.png \
+          en/figs/wdir-pre-branch.png \
+          en/figs/wdir.png
+
+all:
+ifdef LINGUA
+	for f in $(FORMATS); do \
+	  $(MAKE) LINGUA=$(LINGUA) $$f; \
+	done
+else
+	for l in $(LANGUAGES); do \
+	    for f in $(FORMATS); do \
+		$(MAKE) LINGUA=$$l $$f; \
+	    done; \
+	done
+endif
+
+stat:
+	@( \
+	LANG=C; export LANG; cd po; \
+	for f in *.po; do \
+	    printf "%s\t" $$f; \
+	    msgfmt --statistics -c $$f; \
+	done; \
+	)
+
+tidypo:
+ifdef LINGUA
+	msgcat --sort-by-file --width=80 po/$(LINGUA).po > po/$(LINGUA).tmp && \
+	    mv po/$(LINGUA).tmp po/$(LINGUA).po;
+else
+	for po in $(wildcard po/*.po); do \
+	    msgcat --sort-by-file --width=80 $$po > $$po.tmp && mv $$po.tmp $$po; \
+	done
+endif
+
+ifndef LINGUA
+updatepo:
+	for l in $(PO_LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+updatepo:
+ifneq "$(findstring $(LINGUA),$(PO_LANGUAGES))" ""
+	(cd po; \
+	$(UPDATEPO) -m ../en/00book.xml -p $(LINGUA).po; \
+	)
+	$(MAKE) tidypo LINGUA=$(LINGUA)
+endif
+endif
+
+ifndef LINGUA
+validate:
+	for l in $(LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+validate: build/$(LINGUA)/source/hgbook.xml
+	xmllint --nonet --noout --postvalid --xinclude $<
+
+ifneq "$(findstring $(LINGUA),$(DBK_LANGUAGES))" ""
+$(LINGUA)/examples/.run:
+	(cd $(LINGUA)/examples; ./run-example -v -a)
+
+build/$(LINGUA)/source/hgbook.xml: $(wildcard $(LINGUA)/*.xml) $(images) $(LINGUA)/examples/.run
+	mkdir -p build/$(LINGUA)/source/figs
+	cp $(LINGUA)/figs/*.png build/$(LINGUA)/source/figs
+	cp stylesheets/hgbook.css build/$(LINGUA)/source
+	(cd $(LINGUA); xmllint --nonet --noent --xinclude --postvalid --output ../$@.tmp 00book.xml)
+	cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@
+else
+en/examples/.run:
+	(cd en/examples; ./run-example -v -a)
+
+build/en/source/hgbook.xml:
+	${MAKE} LINGUA=en $@
+
+build/$(LINGUA)/source/hgbook.xml: $(wildcard en/*.xml) po/$(LINGUA).po $(images)
+	mkdir -p build/$(LINGUA)/source/figs
+	cp en/figs/*.png build/$(LINGUA)/source/figs
+	cp stylesheets/hgbook.css build/$(LINGUA)/source
+	$(TRANSLATE) -m en/00book.xml -p po/$(LINGUA).po -l en/hgbook.xml.$(LINGUA)
+	xmllint --nonet --noent --xinclude --postvalid --output $@.tmp en/hgbook.xml.$(LINGUA)
+	cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@
+	mv en/hgbook.xml.$(LINGUA) build/$(LINGUA)/source
+endif
+
+endif
+
+ifndef LINGUA
+epub:
+	for l in $(LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+epub: build/$(LINGUA)/epub/hgbook.epub
+
+build/$(LINGUA)/epub/hgbook.epub: build/$(LINGUA)/source/hgbook.xml
+	mkdir -p build/$(LINGUA)/epub
+	(cd build/$(LINGUA)/source; $(DB2EPUB) -c hgbook.css -v hgbook.xml; mv hgbook.epub ../epub)
+endif
+
+ifndef LINGUA
+html:
+	for l in $(LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+html: build/$(LINGUA)/html/index.html
+
+build/$(LINGUA)/html/index.html: build/$(LINGUA)/source/hgbook.xml stylesheets/html.xsl stylesheets/$(LINGUA)/html.xsl
+	mkdir -p build/$(LINGUA)/html/figs
+	cp en/figs/*.png build/$(LINGUA)/html/figs
+	cp stylesheets/hgbook.css build/$(LINGUA)/html
+	xsltproc --output build/$(LINGUA)/html/ \
+	    stylesheets/$(LINGUA)/html.xsl build/$(LINGUA)/source/hgbook.xml
+endif
+
+ifndef LINGUA
+html-single:
+	for l in $(LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+html-single: build/$(LINGUA)/html-single/hgbook.html
+
+build/$(LINGUA)/html-single/hgbook.html: build/$(LINGUA)/source/hgbook.xml stylesheets/html-single.xsl stylesheets/$(LINGUA)/html-single.xsl
+	mkdir -p build/$(LINGUA)/html-single/figs
+	cp en/figs/*.png build/$(LINGUA)/html-single/figs
+	cp stylesheets/hgbook.css build/$(LINGUA)/html-single
+	xsltproc --output build/$(LINGUA)/html-single/hgbook.html \
+	    stylesheets/$(LINGUA)/html-single.xsl build/$(LINGUA)/source/hgbook.xml
+endif
+
+ifndef LINGUA
+pdf:
+	for l in $(LANGUAGES); do \
+	    $(MAKE) $@ LINGUA=$$l; \
+	done
+else
+pdf: build/$(LINGUA)/pdf/hgbook.pdf
+
+build/$(LINGUA)/pdf/hgbook.pdf: build/$(LINGUA)/source/hgbook.xml stylesheets/fo.xsl stylesheets/$(LINGUA)/fo.xsl
+	mkdir -p build/$(LINGUA)/pdf
+	java -classpath $(JAVA_LIB)/saxon65.jar:$(JAVA_LIB)/saxon65-dbxsl.jar:$(JAVA_LIB)/xml-commons-resolver-1.2.jar:$(JAVA_LIB) \
+	    com.icl.saxon.StyleSheet \
+	    -x org.apache.xml.resolver.tools.ResolvingXMLReader \
+	    -y org.apache.xml.resolver.tools.ResolvingXMLReader \
+	    -r org.apache.xml.resolver.tools.CatalogResolver \
+	    -o build/$(LINGUA)/source/hgbook.fo \
+	    build/$(LINGUA)/source/hgbook.xml \
+	    stylesheets/$(LINGUA)/fo.xsl \
+	    fop1.extensions=1
+
+	(cd build/$(LINGUA)/source && $(FOP_HOME)/fop.sh -c $(FOP_HOME)/conf/userconfig.xml hgbook.fo ../pdf/hgbook.pdf)
+endif
+
+en/figs/%.png: en/figs/%.svg en/fixsvg
+	en/fixsvg $<
+	inkscape -D -d 120 -e $@ $<-tmp.svg
+
+en/figs/%.svg: en/figs/%.dot
+	dot -Tsvg -o $@ $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.vars.tmpl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,20 @@
+#
+# Please create your Makefile.vars file from this template file.
+#
+# Please use absolute path, DO NOT use relative path !
+#
+
+# po4a (>= 0.36.1): Only for PO based Makefile !
+# po4A_HOME=/usr/bin
+# PO4A_LIB=/usr/share/perl5
+PO4A_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/po4a
+PO4A_LIB=$(PO4A_HOME)/lib
+
+# saxon65.jar, saxon65-dbxsl.jar, xml-commons-resolver-1.2.jar: Only for pdf format !
+JAVA_LIB=/home/dongsheng/var/svn/i18n-zh/trunk/lib/share/java
+
+# fop (>= 0.9.6): Only for pdf format !
+FOP_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/fop
+
+# docbook-xsl (>= 1.74.3): Only for ePub format !
+DB2EPUB=/home/dongsheng/var/svn/i18n-zh/trunk/lib/docbook/docbook-xsl/epub/bin/dbtoepub
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,16 @@
+Mercurial: The Definitive Guide
+-------------------------------
+
+Welcome to the source code for the book.  You can clone the definitive
+copy of the source tree using Mercurial as follows:
+
+  hg clone http://hg.serpentine.com/mercurial/book
+
+Here's a top-level tour of interesting directories:
+
+en        English-language content
+es        Spanish-language content
+examples  Miscellaneous example scripts
+tools     Old, largely unused conversion scripts
+web       Content and comment system for http://hgbook.red-bean.com/
+xsl       XSLT scripts for generating HTML
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.BUILD	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,99 @@
+HOW-TO:  Compiling the Mercurial Book
+======================================
+
+This Mercurial Book is written in DocBook 4.5.
+
+The goal of this document is to give simple instructions to anyone who
+wants to compile this book into a useful format, like HTML or PDF.  It
+should state *exactly* which tools to use, and how to invoke them, in
+simplest terms.
+
+Table of Contents:
+
+  I. PRIMER
+ II. COMPILING THE DOCS
+III. HACKING ON THE DOCS
+
+I. PRIMER
+
+  DocBook has a tortured, confusing history.  Before you do anything,
+  take a look at Eric Raymond's excellent "DocBook Demystification HOWTO":
+
+      http://tldp.org/HOWTO/DocBook-Demystification-HOWTO/
+
+  It's very short and clears up many things.
+
+
+II. COMPILING THE DOCS
+
+
+1. Install XML DTD and XSL stylesheets for DocBook
+
+      % sudo apt-get install docbook-xml docbook-xsl
+
+2. Install libxml2-utils
+
+      % sudo apt-get install libxml2-utils
+
+3. Install graph drawing tools
+
+      % sudo apt-get install graphviz inkscape
+
+4. Install pdf support
+
+      % sudo apt-get install openjdk-6-jdk docbook-xsl-saxon libsaxon-java fop
+
+  The Makefile will actually invoke tools/fop/fop.sh, you should do
+  some trick, let fop's CLASSPATH include saxon.jar and docbook-xsl-saxon.jar .
+
+5. Make
+  Run 'make' for more details, for example:
+
+  * make all document(pdf, html and html-single for all languages)
+      % make all
+
+  * make english document(pdf, html and html-single for all languages)
+      % make LINGUA=en all
+
+  * make Chinese document(pdf, html and html-single for all languages)
+      % make LINGUA=zh all
+
+  * make Chinese pdf document
+      % make LINGUA=zh pdf
+
+III. HACKING ON THE DOCS
+
+In addition to everything in section II:
+
+
+1. Get a nice editing environment for SGML/XML.
+
+  This isn't strictly required, but it's nice when your editor
+  colorizes things, understands the DTD, tells you what tags you can
+  insert, etc.
+
+  If you use emacs, we recommend the PSGML major-mode.  Most free
+  operating systems package it, or its home page is here:
+
+      http://www.lysator.liu.se/projects/about_psgml.html
+
+  If you use vim, you might check out xmledit, at:
+
+      http://www.vim.org/scripts/script.php?script_id=301
+
+
+2. Get a validating parser.
+
+  Actually, if you have what you need to compile the documentation,
+  then you almost certainly have an XML validator installed already -
+  it is called xmllint, and comes as part of libxml2.
+
+  The makefile is preconfigured with a suitable invocation of it,
+  so simply run:
+
+      $ make validate
+
+3. Read about DocBook.
+
+  You'll want to get real intimate with a DocBook reference, such as
+  can be found at:  http://www.docbook.org/tdg/en/html/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/hg-interdiff	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+#
+# Adapter for using interdiff with mercurial's extdiff extension.
+#
+# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+#
+# This software may be used and distributed according to the terms of
+# the GNU General Public License, incorporated herein by reference.
+
+import os, sys
+
+def walk(base):
+    # yield all non-directories below the base path.
+    for root, dirs, files in os.walk(base):
+        for f in files:
+            path = os.path.join(root, f)
+            yield path[len(base)+1:], path
+    else:
+        if os.path.isfile(base):
+            yield '', base
+
+# create list of unique file names under both directories.
+files = dict(walk(sys.argv[1]))
+files.update(walk(sys.argv[2]))
+files = files.keys()
+files.sort()
+
+def name(base, f):
+    if f:
+        path = os.path.join(base, f)
+    else:
+        path = base
+    # interdiff requires two files; use /dev/null if one is missing.
+    if os.path.exists(path):
+        return path
+    return '/dev/null'
+
+ret = 0
+
+for f in files:
+    if os.system('interdiff "%s" "%s"' % (name(sys.argv[1], f),
+                                          name(sys.argv[2], f))):
+        ret = 1
+
+sys.exit(ret)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/hg-package	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+build_dir=`dirname "$0"`/../build
+rev_id=`hg parents --template '{date|shortdate}' | sed 's/-//g'`
+
+for l in en zh; do
+  (
+  if [ ! -d "${build_dir}/${l}" ] ; then
+    continue
+  fi
+
+  cd ${build_dir}/${l};
+
+  f='html'
+  if [ -f "${f}/index.html" ] ; then
+     d=hgbook-${l}-${f}
+     rm -fr ${d} && cp -r ${f} ${d} && tar czf ../${d}-${rev_id}.tar.gz ${d}
+  fi
+
+  f='html-single'
+  if [ -f "${f}/hgbook.html" ] ; then
+     d=hgbook-${l}-${f}
+     rm -fr ${d} && cp -r ${f} ${d} && tar czf ../${d}-${rev_id}.tar.gz ${d}
+  fi
+
+  if [ -f "pdf/hgbook.pdf" ] ; then
+     cp pdf/hgbook.pdf ../hgbook-${l}-${rev_id}.pdf
+     gzip -f9 ../hgbook-${l}-${rev_id}.pdf
+  fi
+
+  if [ -f "epub/hgbook.epub" ] ; then
+     cp epub/hgbook.epub ../hgbook-${l}-${rev_id}.epub
+  fi
+  )
+done
+
+upload_pass=$1
+upload_user=$2
+
+# echo "upload_pass: ${upload_pass}"
+# echo "upload_user: ${upload_user}"
+
+if [ "${upload_user}x" == "x" ]; then
+  upload_user="dongsheng.song"
+fi
+
+if [ "${upload_pass}x" != "x" ]; then
+  (
+  cd ${build_dir}
+  curl -s -O http://support.googlecode.com/svn/trunk/scripts/googlecode_upload.py
+  if [[ "0" != $? ]]; then
+    exit 1
+  fi
+
+  for l in en zh; do
+    if [ -f "hgbook-${l}-${rev_id}.epub" ] ; then
+      python googlecode_upload.py --user="${upload_user}" --password="${upload_pass}" \
+          -p "i18n-zh" -l "Type-Docs,book,hgbook,hg,mercurial,ebook" \
+          -s "Distributed revision control with Mercurial - ${l} - ePub" \
+          hgbook-${l}-${rev_id}.epub
+    fi
+
+    if [ -f "hgbook-${l}-${rev_id}.pdf.gz" ] ; then
+      python googlecode_upload.py --user="${upload_user}" --password="${upload_pass}" \
+          -p "i18n-zh" -l "Type-Docs,book,hgbook,hg,mercurial" \
+          -s "Distributed revision control with Mercurial - ${l} - pdf" \
+          hgbook-${l}-${rev_id}.pdf.gz
+    fi
+
+    for f in html html-single; do
+      if [ -f "hgbook-${l}-${f}-${rev_id}.tar.gz" ] ; then
+        python googlecode_upload.py --user="${upload_user}" --password="${upload_pass}" \
+            -p "i18n-zh" -l "Type-Docs,book,hgbook,hg,mercurial" \
+            -s "Distributed revision control with Mercurial - ${l} - ${f}" \
+            hgbook-${l}-${f}-${rev_id}.tar.gz
+      fi
+    done
+  done
+  )
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/hg-replay	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+#
+# Adapter for using interdiff with mercurial's extdiff extension.
+#
+# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
+#
+# This software may be used and distributed according to the terms of
+# the GNU General Public License, incorporated herein by reference.
+
+import os
+import shutil
+import sys
+import tempfile
+
+if len(sys.argv) < 4:
+    print >> sys.stderr, ('usage: %s srcrepo destrepo cset-to-omit [...]' %
+                          os.path.basename(sys.argv[0]))
+    sys.exit(1)
+
+srcrepo, destrepo = sys.argv[1], sys.argv[2]
+omit = sys.argv[3:]
+    
+changemap = {}
+revs = []
+
+parent = None
+
+sys.stdout.write('gathering history...')
+sys.stdout.flush()
+
+for line in os.popen("hg --cwd %r log -r0:tip --template '{rev}:{node} {parents}\n'" % srcrepo):
+    changes = line.split()
+    cset = changes[0].split(':')[1]
+    rev = len(revs)
+    changemap[cset] = rev
+    if len(changes) >= 2:
+        p1 = int(changes[1].split(':', 1)[0])
+    if len(changes) == 3:
+        p2 = int(changes[2].split(':', 1)[0])
+    else:
+        p2 = None
+    if len(changes) == 1:
+        p1 = parent
+    revs.append((cset, p1, p2))
+    parent = rev
+
+sys.stdout.write(' %d revs\n' % len(revs))
+
+def findrev(r):
+    try:
+        i = int(r)
+        if str(i) == r:
+            rev = i
+        if rev < 0:
+            rev += len(revs)
+        if rev < 0 or rev > len(revs):
+            print >> sys.stderr, 'bad changeset: %r' % r
+            sys.exit(1)
+        cset = revs[rev][0]
+    except ValueError:
+        cset = r
+        matches = [changemap[c] for c in changemap if c.startswith(cset)]
+        if len(matches) != 1:
+            print >> sys.stderr, 'bad changeset: %r' % r
+            sys.exit(1)
+        rev = matches[0]
+    return rev
+
+def run(cmd):
+    print cmd
+    ret = os.system(cmd)
+    if ret:
+        print >> sys.stderr, 'failure:', cmd
+        sys.exit(1)
+
+omit = map(findrev, omit)
+omit.sort()
+newrevs = revs[:omit[0]]
+tip = len(newrevs) - 1
+run('hg clone -q -r%s %r %r' % (tip, srcrepo, destrepo))
+    
+os.environ['HGMERGE'] = 'true'
+
+patchdir = tempfile.mkdtemp(prefix='replay.')
+try:
+    run('hg --cwd %r export --git -o %r%s%%R %d:tip' %
+        (srcrepo, patchdir, os.sep, omit[0]+1))
+    for rev in xrange(omit[0], len(revs)):
+        if rev in omit:
+            print 'omit', rev
+            newrevs.append((None, revs[rev][1], None))
+            continue
+        _, p1, p2 = revs[rev]
+        np1 = newrevs[p1][1]
+        if tip != np1:
+            run('hg --cwd %r update -q -C %s' % (destrepo, np1))
+        np2 = None
+        if p2:
+            np2 = newrevs[p2][1]
+            run('hg --cwd %r merge -q %s' % (destrepo, np2))
+            print >> sys.stderr, 'XXX - cannot handle merges properly yet'
+        run('hg --cwd %r import -q -f %r%s%d' % (destrepo, patchdir, os.sep, rev))
+        tip = len(newrevs) - 1
+        newrevs.append((None, tip, np2))
+finally:
+    print 'cleaning up ...'
+    #shutil.rmtree(patchdir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/latex-to-docbook	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,198 @@
+#!/usr/bin/python
+#
+# This is the most horrible of hacks. Pretend you're not looking.</para>
+
+import cStringIO as StringIO
+import re, sys
+
+sections = {
+    'chapter': 'chapter',
+    'section': 'sect1',
+    'subsection': 'sect2',
+    'subsubsection': 'sect3',
+    }
+
+envs = {
+    'codesample2': 'programlisting',
+    'codesample4': 'programlisting',
+    'enumerate': 'orderedlist',
+    'figure': 'informalfigure',
+    'itemize': 'itemizedlist',
+    'note': 'note',
+    'quote': 'blockquote',
+    }
+
+def process(ifp, ofp):
+    print >> ofp, '<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->\n'
+    stack = []
+    para = True
+    inlist = 0
+    for line in ifp:
+        if line.startswith('%%% Local Variables:'):
+            break
+        line = (line.rstrip()
+                .replace('~', ' ')
+                .replace('&', '&amp;')
+                .replace('---', '&emdash;')
+                .replace('\_', '_')
+                .replace('\{', '{')
+                .replace('\}', '}')
+                .replace('\$', '$')
+                .replace('\%', '%')
+                .replace('\#', '#')
+                .replace('<', '&lt;')
+                .replace('>', '&gt;')
+                .replace('``', '<quote>')
+                .replace("''", '</quote>')
+                .replace('\\', '\\'))
+        line = re.sub(r'\s*\\(?:centering|small)\b\s*', '', line)
+        line = re.sub(r'\\(?:hgrc\\|hgrc)\b',
+                      r'<filename role="special"> /.hgrc</filename>', line)
+        line = re.sub(r'\\item\[(?P<key>[^]]+)\]', r'\item \g<key>:', line)
+        line = re.sub(r'\\bug{(?P<id>\d+)}',
+                      r'<ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue\g<id>">issue \g<id></ulink>', line)
+        line = re.sub(r'\\cite{([^}]+)}', r'<citation>\1</citation>', line)
+        line = re.sub(r'\\hggopt{(?P<opt>[^}]+)}',
+                      r'<option role="hg-opt-global">\g<opt></option>', line)
+        line = re.sub(r'\\hgxopt{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}',
+                      r'<option role="hg-ext-\g<ext>-cmd-\g<cmd>-opt">\g<opt></option>', line)
+        line = re.sub(r'\\hgxcmd{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}',
+                      r'<command role="hg-ext-\g<ext>">\g<cmd></command>', line)
+        line = re.sub(r'\\hgext{(?P<ext>[^}]+)}',
+                      r'<literal role="hg-ext">\g<ext></literal>', line)
+        line = re.sub(r'\\hgopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}',
+                      r'<option role="hg-opt-\g<cmd>">\g<opt></option>',
+                      line)
+        line = re.sub(r'\\cmdopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}',
+                      r'<option role="cmd-opt-\g<cmd>">\g<opt></option>',
+                      line)
+        line = re.sub(r'\\hgcmd{(?P<cmd>[^}]+)}',
+                      r'<command role="hg-cmd">hg \g<cmd></command>', line)
+        line = re.sub(r'\\caption{(?P<text>[^}]+?)}',
+                      r'<caption><para>\g<text></para></caption>', line)
+        line = re.sub(r'\\grafix{(?P<name>[^}]+)}',
+                      r'<mediaobject><imageobject><imagedata fileref="\g<name>"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>', line)
+        line = re.sub(r'\\envar{(?P<name>[^}]+)}',
+                      r'<envar>\g<name></envar>', line)
+        line = re.sub(r'\\rcsection{(?P<sect>[^}]+)}',
+                      r'<literal role="rc-\g<sect>">\g<sect></literal>', line)
+        line = re.sub(r'\\rcitem{(?P<sect>[^}]+)}{(?P<name>[^}]+)}',
+                      r'<envar role="rc-item-\g<sect>">\g<name></envar>', line)
+        line = re.sub(r'\\dirname{(?P<dir>[^}]+?)}',
+                      r'<filename class="directory">\g<dir></filename>', line)
+        line = re.sub(r'\\filename{(?P<file>[^}]+?)}',
+                      r'<filename>\g<file></filename>', line)
+        line = re.sub(r'\\tildefile{(?P<file>[^}]+)}',
+                      r'<filename role="home">~/\g<file></filename>', line)
+        line = re.sub(r'\\sfilename{(?P<file>[^}]+)}',
+                      r'<filename role="special">\g<file></filename>', line)
+        line = re.sub(r'\\sdirname{(?P<dir>[^}]+)}',
+                      r'<filename role="special" class="directory">\g<dir></filename>', line)
+        line = re.sub(r'\\interaction{(?P<id>[^}]+)}',
+                      r'<!-- &interaction.\g<id>; -->', line)
+        line = re.sub(r'\\excode{(?P<id>[^}]+)}',
+                      r'<!-- &example.\g<id>; -->', line)
+        line = re.sub(r'\\pymod{(?P<mod>[^}]+)}',
+                      r'<literal role="py-mod">\g<mod></literal>', line)
+        line = re.sub(r'\\pymodclass{(?P<mod>[^}]+)}{(?P<class>[^}]+)}',
+                      r'<literal role="py-mod-\g<mod>">\g<class></literal>', line)
+        line = re.sub(r'\\url{(?P<url>[^}]+)}',
+                      r'<ulink url="\g<url>">\g<url></ulink>', line)
+        line = re.sub(r'\\href{(?P<url>[^}]+)}{(?P<text>[^}]+)}',
+                      r'<ulink url="\g<url>">\g<text></ulink>', line)
+        line = re.sub(r'\\command{(?P<cmd>[^}]+)}',
+                      r'<command>\g<cmd></command>', line)
+        line = re.sub(r'\\option{(?P<opt>[^}]+)}',
+                      r'<option>\g<opt></option>', line)
+        line = re.sub(r'\\ref{(?P<id>[^}]+)}', r'<xref linkend="\g<id>"/>', line)
+        line = re.sub(r'\\emph{(?P<txt>[^}]+)}',
+                      r'<emphasis>\g<txt></emphasis>', line)
+        line = re.sub(r'\\texttt{(?P<txt>[^}]+)}',
+                      r'<literal>\g<txt></literal>', line)
+        line = re.sub(r'\\textbf{(?P<txt>[^}]+)}',
+                      r'<emphasis role="bold">\g<txt></emphasis>', line)
+        line = re.sub(r'\\hook{(?P<name>[^}]+)}',
+                      r'<literal role="hook">\g<name></literal>', line)
+        line = re.sub(r'\\tplfilter{(?P<name>[^}]+)}',
+                      r'<literal role="template-filter">\g<name></literal>', line)
+        line = re.sub(r'\\tplkword{(?P<name>[^}]+)}',
+                      r'<literal role="template-keyword">\g<name></literal>', line)
+        line = re.sub(r'\\tplkwfilt{(?P<tpl>[^}]+)}{(?P<name>[^}]+)}',
+                      r'<literal role="template-kw-filt-\g<tpl>">\g<name></literal>', line)
+        line = re.sub(r'\\[vV]erb(.)(?P<txt>[^\1]+?)\1',
+                      r'<literal>\g<txt></literal>', line)
+        line = re.sub(r'\\package{(?P<name>[^}]+)}',
+                      r'<literal role="package">\g<name></literal>', line)
+        line = re.sub(r'\\hgcmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}',
+                      r'<command role="hg-cmd">hg \g<cmd> \g<args></command>',
+                      line)
+        line = re.sub(r'\\cmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}',
+                      r'<command>\g<cmd> \g<args></command>',
+                      line)
+        m = re.match(r'\\(chapter|section|subsection|subsubsection){(.*)}', line)
+        if m:
+            kind, content = m.groups()
+            sec = sections[kind]
+            while stack and stack[-1] >= sec:
+                close = stack.pop()
+                print >> ofp, '</%s>' % close
+            stack.append(sec)
+            print >> ofp, '<%s>\n<title>%s</title>' % (sec, content)
+        else:
+            m = re.match(r'\s*\\(begin|end){(?P<sect>[^}]+)}', line)
+            if m:
+                if not para:
+                    print >> ofp, '</para>'
+                    if inlist:
+                        ofp.write('</listitem>')
+                    para = True
+                state, env = m.groups()
+                env = envs[env]
+                if state == 'begin':
+                    ofp.write('<')
+                    if env in ('itemizedlist', 'orderedlist'):
+                        inlist = 1
+                else:
+                    ofp.write('</')
+                    if env in ('itemizedlist', 'orderedlist'):
+                        inlist = 0
+                print >> ofp, env + '>'
+            else:
+                if line.startswith('\\item '):
+                    if inlist > 1:
+                        print >> ofp, '</para>'
+                        print >> ofp, '</listitem>'
+                    else:
+                        inlist = 2
+                    para = True
+                    line = line[6:]
+                if line and para:
+                    if inlist:
+                        ofp.write('<listitem>')
+                    ofp.write('<para>')
+                    para = False
+                if not line and not para:
+                    print >> ofp, '</para>'
+                    if inlist:
+                        ofp.write('</listitem>')
+                    para = True
+                print >> ofp, line
+    while stack:
+        print >> ofp, '</%s>' % stack.pop()
+    ofp.write('\n'.join(['\n<!--',
+                         'local variables: ',
+                         'sgml-parent-document: ("00book.xml" "book" "chapter")',
+                         'end:',
+                         '-->']))
+
+
+if __name__ == '__main__':
+    for name in sys.argv[1:]:
+        if not name.endswith('.tex'):
+            continue
+        newname = name[:-3] + 'xml'
+        ofp = StringIO.StringIO()
+        process(open(name), ofp)
+        s = ofp.getvalue()
+        s = re.sub('\n+</para>', '</para>', s, re.M)
+        open(newname, 'w').write(s)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/sillybench.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+#
+# Silly benchmarking program, to give a vague idea of how fast a few
+# tools are on a handful of common operations.
+#
+# Use a fairly big and real source tarball to test with: Firefox
+# 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto
+# 4KB-blocksize ext3).
+
+import csv
+import os
+import shutil
+import sys
+import tempfile
+import time
+import urllib2
+
+url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2'
+
+class CommandFailure(Exception):
+    pass
+
+class rcs(object):
+    def __init__(self):
+        self.logfp = open(self.__class__.__name__ + '.csv', 'w')
+        self.csv = csv.writer(self.logfp)
+
+    def download(self):
+        name = url[url.rfind('/')+1:]
+        path = os.path.join(os.environ['HOME'], name)
+        if not os.path.isfile(path):
+            ofp = open(path + '.part', 'wb')
+            try:
+                ifp = urllib2.urlopen(url)
+                nbytes = ifp.info()['content-length']
+                sys.stdout.write('%s: %s bytes ' % (name, nbytes))
+                sys.stdout.flush()
+                while True:
+                    data = ifp.read(131072)
+                    if not data: break
+                    sys.stdout.write('.')
+                    sys.stdout.flush()
+                    ofp.write(data)
+                del ofp
+                os.rename(path + '.part', path)
+            except:
+                if os.path.exists(path + '.part'):
+                    os.unlink(path + '.part')
+                if os.path.exists(path):
+                    os.unlink(path)
+                raise
+        return path
+
+    def run(self, args, mustsucceed=True):
+        ret = os.spawnvp(os.P_WAIT, args[0], args)
+        if ret < 0:
+            msg = 'killed by signal %d' % (-ret)
+        if ret > 0:
+            msg = 'exited with status %d' % (ret)
+        if ret:
+            if mustsucceed:
+                raise CommandFailure('%s: %s' % (msg, ' '.join(args)))
+            print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args))
+
+    def time(self, *args, **kwargs):
+        start = time.time()
+        self.run(*args, **kwargs)
+        end = time.time()
+        return end - start
+        
+    def logtime(self, name, elapsed, rest=[]):
+        self.log('time:' + name, '%.3f' % elapsed, rest)
+
+    def log(self, name, value, rest=[]):
+        item = (name, value, repr(rest))
+        print ' '.join(item)
+        self.csv.writerow(item)
+        self.logfp.flush()
+
+    def unpack(self):
+        tarball = self.download()
+        t = self.time(['tar', '-C', self.wdir, '-jxf', tarball])
+        self.logtime('internal:untar', t)
+        for name in os.listdir(os.path.join(self.wdir, 'mozilla')):
+            os.rename(os.path.join(self.wdir, 'mozilla', name),
+                      os.path.join(self.wdir, name))
+
+    def cleanup(self):
+        pass
+
+    def add(self, paths):
+        pass
+
+    def commit(self, msg, paths):
+        pass
+
+    def status(self, path):
+        pass
+
+    def remove(self, path):
+        pass
+
+
+class subversion(rcs):
+    def __init__(self, root):
+        rcs.__init__(self)
+        self.repo = os.path.join(root, 'repo')
+        self.wdir = os.path.join(root, 'wc')
+        create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo])
+        self.logtime('svn:create', create)
+        co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir])
+        self.logtime('svn:co', co)
+        self.logtime('init', create + co)
+        os.chdir(self.wdir)
+
+    def dropmeta(self, names):
+        return [n for n in names if os.path.basename(n) != '.svn']
+
+    def add(self, paths):
+        t = self.time(['svn', 'add', '-q'] + paths)
+        self.logtime('add %r' % paths, t)
+
+    def commit(self, msg, paths=[]):
+        if paths:
+            t = self.time(['svn', 'ci', '-q', '-m', msg] + paths)
+        else:
+            t = self.time(['svn', 'ci', '-q', '-m', msg])
+        self.logtime('commit %r' % paths, t)
+
+
+class mercurial(rcs):
+    def __init__(self, root):
+        rcs.__init__(self)
+        self.repo = os.path.join(root, 'repo')
+        self.wdir = self.repo
+        init = self.time(['hg', 'init', self.repo])
+        self.logtime('init', init)
+        os.chdir(self.wdir)
+
+    def dropmeta(self, names):
+        return [n for n in names if os.path.basename(n) != '.hg']
+
+    def add(self, paths):
+        t = self.time(['hg', 'add', '-q'] + paths)
+        self.logtime('add %r' % paths, t)
+
+    def commit(self, msg, paths=[]):
+        if paths:
+            t = self.time(['hg', 'ci', '-q', '-m', msg] + paths)
+        else:
+            t = self.time(['hg', 'ci', '-q', '-m', msg])
+        self.logtime('commit %r' % paths, t)
+
+def benchmark(cls):
+    oldcwd = os.getcwd()
+    root = tempfile.mkdtemp(prefix='sillybench.')
+    try:
+        print 'root', root
+        inst = cls(root)
+        inst.unpack()
+        names = inst.dropmeta(os.listdir('.'))
+        dirs = [n for n in names if os.path.isdir(n)]
+        nondirs = [n for n in names if not os.path.isdir(n)]
+        dirs.sort(key=hash)
+        names.sort(key=hash)
+        for d in dirs[:len(dirs)/2]:
+            inst.add([d])
+            inst.commit('Add %r' % d, [d])
+        inst.add(dirs[len(dirs)/2:] + names)
+        inst.commit('Add remaining dirs and files')
+    finally:
+        print >> sys.stderr, '[cleaning up...]'
+        shutil.rmtree(root)
+        os.chdir(oldcwd)
+
+benchmark(mercurial)
+#benchmark(subversion)
--- a/en/00book.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-% 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}
-% 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{Distributed revision control with Mercurial} \author{Bryan
-  O'Sullivan}
-\date{Copyright \copyright\ 2006, 2007 Bryan O'Sullivan.\\
-  This material may be distributed only subject to the terms and
-  conditions set forth in version 1.0 of the Open Publication License.
-  Please refer to Appendix~\ref{cha:opl} for the license text.\\
-  This book was prepared from
-  \href{http://hg.serpentine.com/mercurial/book/}{rev~\input{build_id}}
-  using \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: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/00book.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
+[
+<!-- Below are references to files in this directory. -->
+
+<!-- Chapters. -->
+
+<!ENTITY ch00     SYSTEM "ch00-preface.xml">
+<!ENTITY ch01     SYSTEM "ch01-tour-basic.xml">
+<!ENTITY ch02     SYSTEM "ch02-tour-merge.xml">
+<!ENTITY ch03     SYSTEM "ch03-concepts.xml">
+<!ENTITY ch04     SYSTEM "ch04-daily.xml">
+<!ENTITY ch05     SYSTEM "ch05-collab.xml">
+<!ENTITY ch06     SYSTEM "ch06-filenames.xml">
+<!ENTITY ch07     SYSTEM "ch07-branch.xml">
+<!ENTITY ch08     SYSTEM "ch08-undo.xml">
+<!ENTITY ch09     SYSTEM "ch09-hook.xml">
+<!ENTITY ch10     SYSTEM "ch10-template.xml">
+<!ENTITY ch11     SYSTEM "ch11-mq.xml">
+<!ENTITY ch12     SYSTEM "ch12-mq-collab.xml">
+<!ENTITY ch13     SYSTEM "ch13-hgext.xml">
+<!ENTITY appA     SYSTEM "appA-cmdref.xml">
+<!ENTITY appB     SYSTEM "appB-mq-ref.xml">
+<!ENTITY appC     SYSTEM "appC-srcinstall.xml">
+<!ENTITY appD     SYSTEM "appD-license.xml">
+
+<!-- Include our standard shortcuts. -->
+
+<!ENTITY % SHORTCUTS SYSTEM "book-shortcuts.xml">
+%SHORTCUTS;
+
+<!-- Include automatically and manually generated code snippets. -->
+
+<!ENTITY % AUTOSNIPPETS SYSTEM "examples/auto-snippets.xml">
+%AUTOSNIPPETS;
+]>
+
+<book id="hg">
+  <title>Mercurial: The Definitive Guide</title>
+  
+  <!-- hg parents &#x2d;&#x2d;template '{node|short} ({date|shortdate})' 
+  <subtitle>Compiled from 8a1d3f1aff17 (2009-03-10)</subtitle>
+  -->
+  <subtitle>Compiled from $rev_id$</subtitle>
+  <bookinfo>
+    <edition>1</edition>
+    <isbn>9780596800673</isbn>
+    <authorgroup>
+      <author>
+        <firstname>Bryan</firstname>
+        <surname>O'Sullivan</surname>
+      </author>
+    </authorgroup>
+
+    <editor>
+      <firstname>Mike</firstname>
+      <surname>Loukides</surname>
+    </editor>
+
+    <copyright>
+      <year>2006</year>
+      <year>2007</year>
+      <year>2008</year>
+      <year>2009</year>
+      <holder>Bryan O'Sullivan</holder>
+    </copyright>
+  </bookinfo>
+
+  <!-- BEGIN ch00 -->
+  &ch00;
+  <!-- BEGIN ch01 -->
+  &ch01;
+  <!-- BEGIN ch02 -->
+  &ch02;
+  <!-- BEGIN ch03 -->
+  &ch03;
+  <!-- BEGIN ch04 -->
+  &ch04;
+  <!-- BEGIN ch05 -->
+  &ch05;
+  <!-- BEGIN ch06 -->
+  &ch06;
+  <!-- BEGIN ch07 -->
+  &ch07;
+  <!-- BEGIN ch08 -->
+  &ch08;
+  <!-- BEGIN ch09 -->
+  &ch09;
+  <!-- BEGIN ch10 -->
+  &ch10;
+  <!-- BEGIN ch11 -->
+  &ch11;
+  <!-- BEGIN ch12 -->
+  &ch12;
+  <!-- BEGIN ch13 -->
+  &ch13;
+  <!-- BEGIN appB -->
+  &appB;
+  <!-- BEGIN appC -->
+  &appC;
+  <!-- BEGIN appD -->
+  &appD;
+</book>
--- a/en/99book.bib	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-@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}},
-}
--- a/en/99defs.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-% 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}}
-
-\newcommand{\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}}
-
-%%% Local Variables:
-%%% mode: yatex
-%%% TeX-master: "00book"
-%%% End:
--- a/en/Makefile	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/Makefile	Tue Apr 21 00:36:40 2009 +0900
@@ -1,64 +1,26 @@
 # 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 := $(wildcard figs/*.dot figs/*.gif figs/*.png figs/*.svg)
 
-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
+xml-src-files := \
+	00book.xml \
+	app*.xml \
+	ch*.xml
 
 image-dot := $(filter %.dot,$(image-sources))
 image-svg := $(filter %.svg,$(image-sources))
-image-png := $(filter %.png,$(image-sources))
+image-oth := $(filter %.gif %.png,$(image-sources))
+
+obj-web := html
+obj-websup := $(obj-web)/support
+obj-web-read := $(obj-web)/read
 
-image-pdf := $(image-dot:%.dot=%.pdf) $(image-svg:%.svg=%.pdf) $(image-png)
-image-html := $(image-dot:%.dot=%.png) $(image-svg:%.svg=%.png) $(image-png)
-#image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png)
-image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png:%.png=%.eps)
+image-web := \
+	$(image-dot:%.dot=$(obj-web-read)/%.png) \
+	$(image-svg:%.svg=$(obj-web-read)/%.png) \
+	$(image-oth:%=$(obj-web-read)/%)
 
-example-sources := \
+example-sources-by-name := \
 	backout \
 	bisect \
 	branching \
@@ -90,6 +52,49 @@
 	tour \
 	tour-merge-conflict
 
+example-sources := \
+	$(example-sources-by-name:%=examples/%) \
+	$(wildcard examples/ch*/*)
+
+extras-web-base := \
+	$(obj-web)/index.html \
+	$(obj-web)/robots.txt \
+	$(obj-websup)/form-min.js \
+	$(obj-websup)/form.js \
+	$(obj-websup)/hsbook.js \
+	$(obj-websup)/jquery-min.js \
+	$(obj-websup)/jquery.js \
+	$(obj-websup)/styles.css
+
+extras-web := $(extras-web-base) $(extras-web-base:%=%.gz)
+
+xsltproc := xsltproc
+xsltproc-opts := --nonet --xinclude --path '$(xml-path)'
+
+xmllint := xmllint
+xmllint-opts := --noout --nonet --valid
+
+system-xsl-dir := $(firstword $(wildcard \
+	/usr/share/sgml/docbook/xsl-stylesheets \
+	/usr/share/xml/docbook/stylesheet/nwalsh \
+	))
+
+# Bletcherousness.
+
+ifneq ($(wildcard /usr/share/sgml/docbook/xml-dtd-4.4-*),)
+dtd-dir := $(wildcard /usr/share/sgml/docbook/xml-dtd-4.4-*)
+else
+ifneq ($(wildcard /usr/share/xml/docbook/schema/dtd/4.4),)
+dtd-dir := $(wildcard /usr/share/xml/docbook/schema/dtd/4.4)
+else
+$(error Do not know where to look for DocBook XML 4.4 DTD)
+endif
+endif
+
+ifeq ($(system-xsl-dir),)
+$(error add a suitable directory to system-xsl-dir)
+endif
+
 example-prereqs := \
 	/usr/bin/merge
 
@@ -98,11 +103,6 @@
 	../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')
@@ -110,132 +110,111 @@
 hg-version = $(shell hg version -q | \
 		     sed 's,.*(version \(unknown\|[a-f0-9+]*\)),\1,')
 
-all: dvi
-
-#dvi: $(sources) $(image-eps) examples
-dvi: $(sources) $(image-eps)
-	platex 00book.tex
+all: web complete.xml
 
-	cp 00book.aux hgbook.aux
-	bibtex hgbook
+../stylesheets/system-xsl: $(system-xsl-dir)
+	ln -s $< $@
 
-	platex 00book.tex
-	platex 00book.tex
-	platex 00book.tex
+web: ../stylesheets/system-xsl websup html
 
-
-
-
+html: $(obj-web-read)/index.html
 
-
-pdf: pdf/hgbook.pdf
-
-define pdf
-	mkdir -p $(dir $@)
-	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+../web/index-read.html.in: ../web/genindex.py $(xml-src-files)
+	cd ../web && ./genindex.py
 
-	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
+$(obj-web-read)/index.html: ../stylesheets/system-xsl .validated-00book.xml ../web/index-read.html.in
+	xsltproc $(xsltproc-opts) -o $(obj-web-read)/x ../stylesheets/chunk-stylesheet.xsl 00book.xml
+	python ../web/texpand.py ../web/index-read.html.in html/read/index.html
+	for i in $(obj-web-read)/*.html; do \
+	  gzip -9 -c $$i > $$i.gz; \
+	done
 
-#pdf/hgbook.pdf: $(sources) $(image-pdf) examples
-pdf/hgbook.pdf: $(sources) $(image-pdf)
-	$(call pdf)
-
-html: onepage split
-
-onepage: $(htlatex) html/onepage/hgbook.html html/onepage/hgbook.css $(image-html:%=html/onepage/%)
+websup: $(extras-web) $(image-web)
+	mkdir -p $(obj-websup)/figs $(obj-web-read)/figs
+	cp ../stylesheets/system-xsl/images/*.png $(obj-websup)/figs
+	cp -f ../web/icons/*.png $(obj-websup)/figs
 
-html/onepage/%: %
-	cp $< $@
-
-split: $(htlatex) html/split/hgbook.html html/split/hgbook.css $(image-html:%=html/split/%)
-
-html/split/%: %
-	cp $< $@
+complete.xml: .validated-00book.xml
+	$(xsltproc) $(xsltproc-opts) -o $@ ../stylesheets/dtd-profile.xsl 00book.xml
 
-# 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.
+all-ids.dat: ../stylesheets/all-ids.xsl $(xml-src-files)
+	$(xsltproc) $(xsltproc-opts) -o $@ ../stylesheets/all-ids.xsl 00book.xml
+
+web: websup
 
-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
+valid: .validated-00book.xml
 
-#html/onepage/hgbook.html: $(sources) $(image-html) examples bookhtml.cfg
-html/onepage/hgbook.html: $(sources) $(image-html) bookhtml.cfg
-	$(call htlatex,$@,$<)
-
-#html/split/hgbook.html: $(sources) examples bookhtml.cfg
-html/split/hgbook.html: $(sources) bookhtml.cfg
-	$(call htlatex,$@,$<,2)
+.validated-00book.xml: $(xml-src-files) examples/.run
+	$(xmllint) --path '$(dtd-dir):$(xml-path)' $(xmllint-opts) $<
+	touch $@
 
 # Produce 90dpi PNGs for the web.
 
-%.png: %.svg
-	inkscape -D -e $@ $<
-
-%.svg: %.dot
-	dot -Tsvg -o $@ $<
-
-# Produce eps & pdf for the pdf
+$(obj-web-read)/figs/%.png: $(obj-web-read)/figs/%.svg fixsvg
+	mkdir -p $(dir $@)
+	./fixsvg $<
+	inkscape -D -e $@ $<-tmp.svg
+	rm $<-tmp.svg
 
-%.pdf: %.eps
-	epstopdf $<
-
-%.eps: %.svg
-	inkscape -E $@ $<
+$(obj-web-read)/figs/%.png: figs/%.svg fixsvg
+	mkdir -p $(dir $@)
+	./fixsvg $<
+	inkscape -D -e $@ $<-tmp.svg
+	rm $<-tmp.svg
 
-%.eps: %.dot
-	dot -Tps -o $@ $<
+$(obj-web-read)/figs/%.gif: figs/%.gif
+	cp $< $@
 
-%.eps: %.png
-	convert $< ps:$@
+$(obj-web-read)/figs/%.png: figs/%.png
+	cp $< $@
+
+$(obj-web-read)/figs/%.svg: figs/%.dot
+	mkdir -p $(dir $@)
+	dot -Tsvg -o $@ $<
 
 examples: $(example-prereqs) examples/.run
 
-examples/.run: $(example-sources:%=examples/%.run)
-	touch examples/.run
+examples/.run: $(example-sources)
+	cd examples && ./run-example -a
 
 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
+	-rm -rf dist html $(image-dot:%.dot=%.pdf) $(image-dot:%.dot=%.png) \
+	  $(image-svg:%.svg=%.png) examples/*.{lxo,run} examples/.run
 
-install: pdf split $(dist-sources)
+install: html $(dist-sources)
 	rm -rf dist
 	mkdir -p dist
-	cp pdf/hgbook.pdf dist
-	cp html/split/*.{css,html,png} dist
+	cp html/*.{css,html,png} dist
 	cp $(dist-sources) dist
 
+rsync: install
+	rsync -avz --delete dist sp.red-bean.com:public_html/hgbook
+
+vpath %.css ../web
+vpath %.html.in ../web
+vpath %.js ../web/javascript
+
+$(obj-websup)/%.css: %.css
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-websup)/%.jpg: %.jpg
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-websup)/%.js: %.js
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-web)/%: ../web/%
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-web)/%.html: %.html.in
+	@mkdir -p $(dir $@)
+	python ../web/texpand.py $< $@
+
+%.gz: %
+	gzip -9 -c $< > $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/appA-cmdref.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,224 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<appendix id="cmdref">
+  <?dbhtml filename="command-reference.html"?>
+<title>Command reference</title>
+
+<para id="x_653">\cmdref{add}{add files at the next commit}
+\optref{add}{I}{include}
+\optref{add}{X}{exclude}
+\optref{add}{n}{dry-run}</para>
+
+<para id="x_654">\cmdref{diff}{print changes in history or working directory}</para>
+
+<para id="x_655">Show differences between revisions for the specified files or
+directories, using the unified diff format.  For a description of the
+unified diff format, see <xref linkend="sec:mq:patch"/>.</para>
+
+<para id="x_656">By default, this command does not print diffs for files that Mercurial
+considers to contain binary data.  To control this behavior, see the
+<option role="hg-opt-diff">-a</option> and <option role="hg-opt-diff">--git</option> options.</para>
+
+<sect2>
+<title>Options</title>
+x
+<para id="x_657">\loptref{diff}{nodates}</para>
+
+<para id="x_658">Omit date and time information when printing diff headers.</para>
+
+<para id="x_659">\optref{diff}{B}{ignore-blank-lines}</para>
+
+<para id="x_65a">Do not print changes that only insert or delete blank lines.  A line
+that contains only whitespace is not considered blank.
+</para>
+
+<para id="x_65b">\optref{diff}{I}{include}
+</para>
+
+<para id="x_65c">Include files and directories whose names match the given patterns.
+</para>
+
+<para id="x_65d">\optref{diff}{X}{exclude}
+</para>
+
+<para id="x_65e">Exclude files and directories whose names match the given patterns.
+</para>
+
+<para id="x_65f">\optref{diff}{a}{text}
+</para>
+
+<para id="x_660">If this option is not specified, <command role="hg-cmd">hg diff</command> will refuse to print
+diffs for files that it detects as binary. Specifying <option role="hg-opt-diff">-a</option>
+forces <command role="hg-cmd">hg diff</command> to treat all files as text, and generate diffs for
+all of them.
+</para>
+
+<para id="x_661">This option is useful for files that are <quote>mostly text</quote> 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.
+</para>
+
+<para id="x_662">\optref{diff}{b}{ignore-space-change}
+</para>
+
+<para id="x_663">Do not print a line if the only change to that line is in the amount
+of white space it contains.
+</para>
+
+<para id="x_664">\optref{diff}{g}{git}
+</para>
+
+<para id="x_665">Print <command>git</command>-compatible diffs.  XXX reference a format
+description.
+</para>
+
+<para id="x_666">\optref{diff}{p}{show-function}
+</para>
+
+<para id="x_667">Display the name of the enclosing function in a hunk header, using a
+simple heuristic.  This functionality is enabled by default, so the
+<option role="hg-opt-diff">-p</option> option has no effect unless you change the value of
+the <envar role="rc-item-diff">showfunc</envar> config item, as in the following example.</para>
+
+<!-- &interaction.cmdref.diff-p; -->
+
+<para id="x_668">\optref{diff}{r}{rev}
+</para>
+
+<para id="x_669">Specify one or more revisions to compare.  The <command role="hg-cmd">hg diff</command> command
+accepts up to two <option role="hg-opt-diff">-r</option> options to specify the revisions to
+compare.
+</para>
+
+<orderedlist>
+<listitem><para id="x_66a">Display the differences between the parent revision of the
+  working directory and the working directory.
+</para>
+</listitem>
+<listitem><para id="x_66b">Display the differences between the specified changeset and the
+  working directory.
+</para>
+</listitem>
+<listitem><para id="x_66c">Display the differences between the two specified changesets.
+</para>
+</listitem></orderedlist>
+
+<para id="x_66d">You can specify two revisions using either two <option role="hg-opt-diff">-r</option>
+options or revision range notation.  For example, the two revision
+specifications below are equivalent.
+</para>
+<programlisting>hg diff -r 10 -r 20
+hg diff -r10:20</programlisting>
+
+<para id="x_66e">When you provide two revisions, Mercurial treats the order of those
+revisions as significant.  Thus, <command role="hg-cmd">hg diff -r10:20</command> will
+produce a diff that will transform files from their contents as of
+revision 10 to their contents as of revision 20, while
+<command role="hg-cmd">hg diff -r20:10</command> 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.
+</para>
+
+<para id="x_66f">\optref{diff}{w}{ignore-all-space}
+</para>
+
+<para id="x_670">\cmdref{version}{print version and copyright information}
+</para>
+
+<para id="x_671">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.
+</para>
+<itemizedlist>
+<listitem><para id="x_672">The string <quote><literal>unknown</literal></quote>. This version of Mercurial was
+  not built in a Mercurial repository, and cannot determine its own
+  version.
+</para>
+</listitem>
+<listitem><para id="x_673">A short numeric string, such as <quote><literal>1.1</literal></quote>. 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.)
+</para>
+</listitem>
+<listitem><para id="x_674">A hexadecimal string, such as <quote><literal>875489e31abe</literal></quote>.  This
+  is a build of the given revision of Mercurial.
+</para>
+</listitem>
+<listitem><para id="x_675">A hexadecimal string followed by a date, such as
+  <quote><literal>875489e31abe+20070205</literal></quote>.  This is a build of the given
+  revision of Mercurial, where the build repository contained some
+  local changes that had not been committed.
+</para>
+</listitem></itemizedlist>
+
+</sect2>
+<sect2>
+<title>Tips and tricks</title>
+
+<sect3 id="cmdref:diff-vs-status">
+<title>Why do the results of <command role="hg-cmd">hg diff</command> and <command role="hg-cmd">hg status</command> differ?</title>
+
+<para id="x_676">When you run the <command role="hg-cmd">hg status</command> 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 <command role="hg-cmd">hg diff</command> command, you may notice that it
+prints diffs for only a <emphasis>subset</emphasis> of the files that <command role="hg-cmd">hg status</command>
+listed.  There are two possible reasons for this.
+</para>
+
+<para id="x_677">The first is that <command role="hg-cmd">hg status</command> prints some kinds of modifications
+that <command role="hg-cmd">hg diff</command> doesn't normally display.  The <command role="hg-cmd">hg diff</command> 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.
+</para>
+
+<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
+display <command>git</command>-compatible diffs that <emphasis>can</emphasis> display this
+extra information.
+</para>
+
+<para id="x_679">The second possible reason that <command role="hg-cmd">hg diff</command> might be printing diffs
+for a subset of the files displayed by <command role="hg-cmd">hg status</command> is that if you
+invoke it without any arguments, <command role="hg-cmd">hg diff</command> prints diffs against the
+first parent of the working directory.  If you have run <command role="hg-cmd">hg merge</command>
+to merge two changesets, but you haven't yet committed the results of
+the merge, your working directory has two parents (use <command role="hg-cmd">hg parents</command>
+to see them).  While <command role="hg-cmd">hg status</command> prints modifications relative to
+<emphasis>both</emphasis> parents after an uncommitted merge, <command role="hg-cmd">hg diff</command> 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
+<option role="hg-opt-diff">-r</option> option.  There is no way to print diffs relative to
+both parents.
+</para>
+
+</sect3>
+<sect3>
+<title>Generating safe binary diffs</title>
+
+<para id="x_67a">If you use the <option role="hg-opt-diff">-a</option> option to force Mercurial to print
+diffs of files that are either <quote>mostly text</quote> or contain lots of
+binary data, those diffs cannot subsequently be applied by either
+Mercurial's <command role="hg-cmd">hg import</command> command or the system's <command>patch</command>
+command.
+</para>
+
+<para id="x_67b">If you want to generate a diff of a binary file that is safe to use as
+input for <command role="hg-cmd">hg import</command>, use the <command role="hg-cmd">hg diff</command>{--git} option when you
+generate the patch.  The system <command>patch</command> command cannot handle
+binary patches at all.
+</para>
+
+</sect3>
+</sect2>
+</appendix>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "appendix")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/appB-mq-ref.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,570 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<appendix id="chap:mqref">
+  <?dbhtml filename="mercurial-queues-reference.html"?>
+  <title>Mercurial Queues reference</title>
+
+  <sect1 id="sec:mqref:cmdref">
+    <title>MQ command reference</title>
+
+    <para id="x_5e8">For an overview of the commands provided by MQ, use the
+      command <command role="hg-cmd">hg help mq</command>.</para>
+
+    <sect2>
+      <title><command role="hg-ext-mq">qapplied</command>&emdash;print
+	applied patches</title>
+
+      <para id="x_5e9">The <command role="hg-ext-mq">qapplied</command> command
+	prints the current stack of applied patches.  Patches are
+	printed in oldest-to-newest order, so the last patch in the
+	list is the <quote>top</quote> patch.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qcommit</command>&emdash;commit
+	changes in the queue repository</title>
+
+      <para id="x_5ea">The <command role="hg-ext-mq">qcommit</command> command
+	commits any outstanding changes in the <filename
+	  role="special" class="directory">.hg/patches</filename>
+	repository.  This command only works if the <filename
+	  role="special" class="directory">.hg/patches</filename>
+	directory is a repository, i.e. you created the directory
+	using <command role="hg-cmd">hg qinit <option
+	    role="hg-ext-mq-cmd-qinit-opt">-c</option></command> or
+	ran <command role="hg-cmd">hg init</command> in the directory
+	after running <command
+	  role="hg-ext-mq">qinit</command>.</para>
+
+      <para id="x_5eb">This command is shorthand for <command role="hg-cmd">hg
+	  commit --cwd .hg/patches</command>.</para>
+    </sect2>
+    <sect2>
+	<title><command
+	  role="hg-ext-mq">qdelete</command>&emdash;delete a patch
+	from the <filename role="special">series</filename>
+	file</title>
+
+      <para id="x_5ec">The <command role="hg-ext-mq">qdelete</command> command
+	removes the entry for a patch from the <filename
+	  role="special">series</filename> file in the <filename
+	  role="special" class="directory">.hg/patches</filename>
+	directory.  It does not pop the patch if the patch is already
+	applied.  By default, it does not delete the patch file; use
+	the <option role="hg-ext-mq-cmd-qdel-opt">-f</option> option
+	to do that.</para>
+
+      <para id="x_5ed">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_5ee"><option
+	      role="hg-ext-mq-cmd-qdel-opt">-f</option>: Delete the
+	    patch file.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qdiff</command>&emdash;print a
+	diff of the topmost applied patch</title>
+
+      <para id="x_5ef">The <command role="hg-ext-mq">qdiff</command> command
+	prints a diff of the topmost applied patch. It is equivalent
+	to <command role="hg-cmd">hg diff -r-2:-1</command>.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qfold</command>&emdash;merge
+	(<quote>fold</quote>) several patches into one</title>
+
+      <para id="x_5f0">The <command role="hg-ext-mq">qfold</command> command
+	merges multiple patches into the topmost applied patch, so
+	that the topmost applied patch makes the union of all of the
+	changes in the patches in question.</para>
+
+      <para id="x_5f1">The patches to fold must not be applied; <command
+	  role="hg-ext-mq">qfold</command> will exit with an error if
+	any is.  The order in which patches are folded is significant;
+	<command role="hg-cmd">hg qfold a b</command> means
+	<quote>apply the current topmost patch, followed by
+	  <literal>a</literal>, followed by
+	  <literal>b</literal></quote>.</para>
+
+      <para id="x_5f2">The comments from the folded patches are appended to the
+	comments of the destination patch, with each block of comments
+	separated by three asterisk
+	(<quote><literal>*</literal></quote>) characters.  Use the
+	<option role="hg-ext-mq-cmd-qfold-opt">-e</option> option to
+	edit the commit message for the combined patch/changeset after
+	the folding has completed.</para>
+
+      <para id="x_5f3">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_5f4"><option
+	      role="hg-ext-mq-cmd-qfold-opt">-e</option>: Edit the
+	    commit message and patch description for the newly folded
+	    patch.</para>
+	</listitem>
+	<listitem><para id="x_5f5"><option
+	      role="hg-ext-mq-cmd-qfold-opt">-l</option>: Use the
+	    contents of the given file as the new commit message and
+	    patch description for the folded patch.</para>
+	</listitem>
+	<listitem><para id="x_5f6"><option
+	      role="hg-ext-mq-cmd-qfold-opt">-m</option>: Use the
+	    given text as the new commit message and patch description
+	    for the folded patch.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title><command
+	  role="hg-ext-mq">qheader</command>&emdash;display the
+	header/description of a patch</title>
+
+      <para id="x_5f7">The <command role="hg-ext-mq">qheader</command> command
+	prints the header, or description, of a patch.  By default, it
+	prints the header of the topmost applied patch. Given an
+	argument, it prints the header of the named patch.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qimport</command>&emdash;import
+	a third-party patch into the queue</title>
+
+      <para id="x_5f8">The <command role="hg-ext-mq">qimport</command> command
+	adds an entry for an external patch to the <filename
+	  role="special">series</filename> file, and copies the patch
+	into the <filename role="special"
+	  class="directory">.hg/patches</filename> directory.  It adds
+	the entry immediately after the topmost applied patch, but
+	does not push the patch.</para>
+
+      <para id="x_5f9">If the <filename role="special"
+	  class="directory">.hg/patches</filename> directory is a
+	repository, <command role="hg-ext-mq">qimport</command>
+	automatically does an <command role="hg-cmd">hg add</command>
+	of the imported patch.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qinit</command>&emdash;prepare
+	a repository to work with MQ</title>
+
+      <para id="x_5fa">The <command role="hg-ext-mq">qinit</command> command
+	prepares a repository to work with MQ.  It creates a directory
+	called <filename role="special"
+	  class="directory">.hg/patches</filename>.</para>
+
+      <para id="x_5fb">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_5fc"><option
+	      role="hg-ext-mq-cmd-qinit-opt">-c</option>: Create
+	    <filename role="special"
+	      class="directory">.hg/patches</filename> as a repository
+	    in its own right.  Also creates a <filename
+	      role="special">.hgignore</filename> file that will
+	    ignore the <filename role="special">status</filename>
+	    file.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_5fd">When the <filename role="special"
+	  class="directory">.hg/patches</filename> directory is a
+	repository, the <command role="hg-ext-mq">qimport</command>
+	and <command role="hg-ext-mq">qnew</command> commands
+	automatically <command role="hg-cmd">hg add</command> new
+	patches.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qnew</command>&emdash;create a
+	new patch</title>
+
+      <para id="x_5fe">The <command role="hg-ext-mq">qnew</command> command
+	creates a new patch.  It takes one mandatory argument, the
+	name to use for the patch file.  The newly created patch is
+	created empty by default.  It is added to the <filename
+	  role="special">series</filename> file after the current
+	topmost applied patch, and is immediately pushed on top of
+	that patch.</para>
+
+      <para id="x_5ff">If <command role="hg-ext-mq">qnew</command> finds modified
+	files in the working directory, it will refuse to create a new
+	patch unless the <option
+	  role="hg-ext-mq-cmd-qnew-opt">-f</option> option is used
+	(see below).  This behavior allows you to <command
+	  role="hg-ext-mq">qrefresh</command> your topmost applied
+	patch before you apply a new patch on top of it.</para>
+
+      <para id="x_600">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_601"><option
+	      role="hg-ext-mq-cmd-qnew-opt">-f</option>: Create a new
+	    patch if the contents of the working directory are
+	    modified.  Any outstanding modifications are added to the
+	    newly created patch, so after this command completes, the
+	    working directory will no longer be modified.</para>
+	</listitem>
+	<listitem><para id="x_602"><option
+	      role="hg-ext-mq-cmd-qnew-opt">-m</option>: Use the given
+	    text as the commit message. This text will be stored at
+	    the beginning of the patch file, before the patch
+	    data.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qnext</command>&emdash;print
+	the name of the next patch</title>
+
+      <para id="x_603">The <command role="hg-ext-mq">qnext</command> command
+	prints the name name of the next patch in the <filename
+	  role="special">series</filename> file after the topmost
+	applied patch.  This patch will become the topmost applied
+	patch if you run <command
+	  role="hg-ext-mq">qpush</command>.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qpop</command>&emdash;pop
+	patches off the stack</title>
+
+      <para id="x_604">The <command role="hg-ext-mq">qpop</command> command
+	removes applied patches from the top of the stack of applied
+	patches.  By default, it removes only one patch.</para>
+
+      <para id="x_605">This command removes the changesets that represent the
+	popped patches from the repository, and updates the working
+	directory to undo the effects of the patches.</para>
+
+      <para id="x_606">This command takes an optional argument, which it uses as
+	the name or index of the patch to pop to.  If given a name, it
+	will pop patches until the named patch is the topmost applied
+	patch.  If given a number, <command
+	  role="hg-ext-mq">qpop</command> treats the number as an
+	index into the entries in the series file, counting from zero
+	(empty lines and lines containing only comments do not count).
+	It pops patches until the patch identified by the given index
+	is the topmost applied patch.</para>
+
+      <para id="x_607">The <command role="hg-ext-mq">qpop</command> command does
+	not read or write patches or the <filename
+	  role="special">series</filename> file.  It is thus safe to
+	<command role="hg-ext-mq">qpop</command> a patch that you have
+	removed from the <filename role="special">series</filename>
+	file, or a patch that you have renamed or deleted entirely.
+	In the latter two cases, use the name of the patch as it was
+	when you applied it.</para>
+
+      <para id="x_608">By default, the <command role="hg-ext-mq">qpop</command>
+	command will not pop any patches if the working directory has
+	been modified.  You can override this behavior using the
+	<option role="hg-ext-mq-cmd-qpop-opt">-f</option> option,
+	which reverts all modifications in the working
+	directory.</para>
+
+      <para id="x_609">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_60a"><option
+	      role="hg-ext-mq-cmd-qpop-opt">-a</option>: Pop all
+	    applied patches.  This returns the repository to its state
+	    before you applied any patches.</para>
+	</listitem>
+	<listitem><para id="x_60b"><option
+	      role="hg-ext-mq-cmd-qpop-opt">-f</option>: Forcibly
+	    revert any modifications to the working directory when
+	    popping.</para>
+	</listitem>
+	<listitem><para id="x_60c"><option
+	      role="hg-ext-mq-cmd-qpop-opt">-n</option>: Pop a patch
+	    from the named queue.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_60d">The <command role="hg-ext-mq">qpop</command> command
+	removes one line from the end of the <filename
+	  role="special">status</filename> file for each patch that it
+	pops.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qprev</command>&emdash;print
+	the name of the previous patch</title>
+
+      <para id="x_60e">The <command role="hg-ext-mq">qprev</command> command
+	prints the name of the patch in the <filename
+	  role="special">series</filename> file that comes before the
+	topmost applied patch. This will become the topmost applied
+	patch if you run <command
+	  role="hg-ext-mq">qpop</command>.</para>
+
+    </sect2>
+    <sect2 id="sec:mqref:cmd:qpush">
+      <title><command role="hg-ext-mq">qpush</command>&emdash;push
+	patches onto the stack</title>
+
+      <para id="x_60f">The <command role="hg-ext-mq">qpush</command> command adds
+	patches onto the applied stack.  By default, it adds only one
+	patch.</para>
+
+      <para id="x_610">This command creates a new changeset to represent each
+	applied patch, and updates the working directory to apply the
+	effects of the patches.</para>
+
+      <para id="x_611">The default data used when creating a changeset are as
+	follows:</para>
+      <itemizedlist>
+	<listitem><para id="x_612">The commit date and time zone are the current
+	    date and time zone.  Because these data are used to
+	    compute the identity of a changeset, this means that if
+	    you <command role="hg-ext-mq">qpop</command> a patch and
+	    <command role="hg-ext-mq">qpush</command> it again, the
+	    changeset that you push will have a different identity
+	    than the changeset you popped.</para>
+	</listitem>
+	<listitem><para id="x_613">The author is the same as the default used by
+	    the <command role="hg-cmd">hg commit</command>
+	    command.</para>
+	</listitem>
+	<listitem><para id="x_614">The commit message is any text from the patch
+	    file that comes before the first diff header.  If there is
+	    no such text, a default commit message is used that
+	    identifies the name of the patch.</para>
+	</listitem></itemizedlist>
+      <para id="x_615">If a patch contains a Mercurial patch header (XXX add
+	link), the information in the patch header overrides these
+	defaults.</para>
+
+      <para id="x_616">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_617"><option
+	      role="hg-ext-mq-cmd-qpush-opt">-a</option>: Push all
+	    unapplied patches from the <filename
+	      role="special">series</filename> file until there are
+	    none left to push.</para>
+	</listitem>
+	<listitem><para id="x_618"><option
+	      role="hg-ext-mq-cmd-qpush-opt">-l</option>: Add the name
+	    of the patch to the end of the commit message.</para>
+	</listitem>
+	<listitem><para id="x_619"><option
+	      role="hg-ext-mq-cmd-qpush-opt">-m</option>: If a patch
+	    fails to apply cleanly, use the entry for the patch in
+	    another saved queue to compute the parameters for a
+	    three-way merge, and perform a three-way merge using the
+	    normal Mercurial merge machinery.  Use the resolution of
+	    the merge as the new patch content.</para>
+	</listitem>
+	<listitem><para id="x_61a"><option
+	      role="hg-ext-mq-cmd-qpush-opt">-n</option>: Use the
+	    named queue if merging while pushing.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_61b">The <command role="hg-ext-mq">qpush</command> command
+	reads, but does not modify, the <filename
+	  role="special">series</filename> file.  It appends one line
+	to the <command role="hg-cmd">hg status</command> file for
+	each patch that it pushes.</para>
+
+    </sect2>
+    <sect2>
+      <title><command
+	  role="hg-ext-mq">qrefresh</command>&emdash;update the
+	topmost applied patch</title>
+
+      <para id="x_61c">The <command role="hg-ext-mq">qrefresh</command> command
+	updates the topmost applied patch.  It modifies the patch,
+	removes the old changeset that represented the patch, and
+	creates a new changeset to represent the modified
+	patch.</para>
+
+      <para id="x_61d">The <command role="hg-ext-mq">qrefresh</command> command
+	looks for the following modifications:</para>
+      <itemizedlist>
+	<listitem><para id="x_61e">Changes to the commit message, i.e. the text
+	    before the first diff header in the patch file, are
+	    reflected in the new changeset that represents the
+	    patch.</para>
+	</listitem>
+	<listitem><para id="x_61f">Modifications to tracked files in the working
+	    directory are added to the patch.</para>
+	</listitem>
+	<listitem><para id="x_620">Changes to the files tracked using <command
+	      role="hg-cmd">hg add</command>, <command
+	      role="hg-cmd">hg copy</command>, <command
+	      role="hg-cmd">hg remove</command>, or <command
+	      role="hg-cmd">hg rename</command>.  Added files and copy
+	    and rename destinations are added to the patch, while
+	    removed files and rename sources are removed.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_621">Even if <command role="hg-ext-mq">qrefresh</command>
+	detects no changes, it still recreates the changeset that
+	represents the patch.  This causes the identity of the
+	changeset to differ from the previous changeset that
+	identified the patch.</para>
+
+      <para id="x_622">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_623"><option
+	      role="hg-ext-mq-cmd-qrefresh-opt">-e</option>: Modify
+	    the commit and patch description, using the preferred text
+	    editor.</para>
+	</listitem>
+	<listitem><para id="x_624"><option
+	      role="hg-ext-mq-cmd-qrefresh-opt">-m</option>: Modify
+	    the commit message and patch description, using the given
+	    text.</para>
+	</listitem>
+	<listitem><para id="x_625"><option
+	      role="hg-ext-mq-cmd-qrefresh-opt">-l</option>: Modify
+	    the commit message and patch description, using text from
+	    the given file.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qrename</command>&emdash;rename
+	a patch</title>
+
+      <para id="x_626">The <command role="hg-ext-mq">qrename</command> command
+	renames a patch, and changes the entry for the patch in the
+	<filename role="special">series</filename> file.</para>
+
+      <para id="x_627">With a single argument, <command
+	  role="hg-ext-mq">qrename</command> renames the topmost
+	applied patch.  With two arguments, it renames its first
+	argument to its second.</para>
+
+    </sect2>
+    <sect2>
+      <title><command
+	  role="hg-ext-mq">qrestore</command>&emdash;restore saved
+	queue state</title>
+
+      <para id="x_628">XXX No idea what this does.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qsave</command>&emdash;save
+	current queue state</title>
+
+      <para id="x_629">XXX Likewise.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qseries</command>&emdash;print
+	the entire patch series</title>
+
+      <para id="x_62a">The <command role="hg-ext-mq">qseries</command> command
+	prints the entire patch series from the <filename
+	  role="special">series</filename> file.  It prints only patch
+	names, not empty lines or comments.  It prints in order from
+	first to be applied to last.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-ext-mq">qtop</command>&emdash;print the
+	name of the current patch</title>
+
+      <para id="x_62b">The <command role="hg-ext-mq">qtop</command> prints the
+	name of the topmost currently applied patch.</para>
+
+    </sect2>
+    <sect2>
+      <title><command
+	  role="hg-ext-mq">qunapplied</command>&emdash;print patches
+	not yet applied</title>
+
+      <para id="x_62c">The <command role="hg-ext-mq">qunapplied</command> command
+	prints the names of patches from the <filename
+	  role="special">series</filename> file that are not yet
+	applied.  It prints them in order from the next patch that
+	will be pushed to the last.</para>
+
+    </sect2>
+    <sect2>
+      <title><command role="hg-cmd">hg strip</command>&emdash;remove a
+	revision and descendants</title>
+
+      <para id="x_62d">The <command role="hg-cmd">hg strip</command> command
+	removes a revision, and all of its descendants, from the
+	repository.  It undoes the effects of the removed revisions
+	from the repository, and updates the working directory to the
+	first parent of the removed revision.</para>
+
+      <para id="x_62e">The <command role="hg-cmd">hg strip</command> command
+	saves a backup of the removed changesets in a bundle, so that
+	they can be reapplied if removed in error.</para>
+
+      <para id="x_62f">Options:</para>
+      <itemizedlist>
+	<listitem><para id="x_630"><option role="hg-opt-strip">-b</option>: Save
+	    unrelated changesets that are intermixed with the stripped
+	    changesets in the backup bundle.</para>
+	</listitem>
+	<listitem><para id="x_631"><option role="hg-opt-strip">-f</option>: If a
+	    branch has multiple heads, remove all heads. XXX This
+	    should be renamed, and use <literal>-f</literal> to strip
+	    revs when there are pending changes.</para>
+	</listitem>
+	<listitem><para id="x_632"><option role="hg-opt-strip">-n</option>: Do
+	    not save a backup bundle.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>MQ file reference</title>
+
+    <sect2>
+      <title>The <filename role="special">series</filename>
+	file</title>
+
+      <para id="x_633">The <filename role="special">series</filename> file
+	contains a list of the names of all patches that MQ can apply.
+	It is represented as a list of names, with one name saved per
+	line.  Leading and trailing white space in each line are
+	ignored.</para>
+
+      <para id="x_634">Lines may contain comments.  A comment begins with the
+	<quote><literal>#</literal></quote> character, and extends to
+	the end of the line.  Empty lines, and lines that contain only
+	comments, are ignored.</para>
+
+      <para id="x_635">You will often need to edit the <filename
+	  role="special">series</filename> file by hand, hence the
+	support for comments and empty lines noted above.  For
+	example, you can comment out a patch temporarily, and <command
+	  role="hg-ext-mq">qpush</command> will skip over that patch
+	when applying patches.  You can also change the order in which
+	patches are applied by reordering their entries in the
+	<filename role="special">series</filename> file.</para>
+
+      <para id="x_636">Placing the <filename role="special">series</filename>
+	file under revision control is also supported; it is a good
+	idea to place all of the patches that it refers to under
+	revision control, as well.  If you create a patch directory
+	using the <option role="hg-ext-mq-cmd-qinit-opt">-c</option>
+	option to <command role="hg-ext-mq">qinit</command>, this will
+	be done for you automatically.</para>
+
+    </sect2>
+    <sect2>
+      <title>The <filename role="special">status</filename>
+	file</title>
+
+      <para id="x_637">The <filename role="special">status</filename> file
+	contains the names and changeset hashes of all patches that MQ
+	currently has applied.  Unlike the <filename
+	  role="special">series</filename> file, this file is not
+	intended for editing.  You should not place this file under
+	revision control, or modify it in any way.  It is used by MQ
+	strictly for internal book-keeping.</para>
+
+    </sect2>
+  </sect1>
+</appendix>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "appendix")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/appC-srcinstall.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,66 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<appendix id="chap:srcinstall">
+  <?dbhtml filename="installing-mercurial-from-source.html"?>
+  <title>Installing Mercurial from source</title>
+
+  <sect1 id="sec:srcinstall:unixlike">
+    <title>On a Unix-like system</title>
+
+    <para id="x_5e0">If you are using a Unix-like system that has a sufficiently
+      recent version of Python (2.3 or newer) available, it is easy to
+      install Mercurial from source.</para>
+    <orderedlist>
+      <listitem><para id="x_5e1">Download a recent source tarball from <ulink
+	    url="http://www.selenic.com/mercurial/download">http://www.selenic.com/mercurial/download</ulink>.</para>
+      </listitem>
+      <listitem><para id="x_5e2">Unpack the tarball:</para>
+	<programlisting>gzip -dc mercurial-MYVERSION.tar.gz | tar xf -</programlisting>
+      </listitem>
+      <listitem><para id="x_5e3">Go into the source directory and run the
+	  installer script.  This will build Mercurial and install it
+	  in your home directory.</para>
+	<programlisting>cd mercurial-MYVERSION
+python setup.py install --force --home=$HOME</programlisting>
+      </listitem>
+    </orderedlist>
+    <para id="x_5e4">Once the install finishes, Mercurial will be in the
+      <literal>bin</literal> subdirectory of your home directory.
+      Don't forget to make sure that this directory is present in your
+      shell's search path.</para>
+
+    <para id="x_5e5">You will probably need to set the <envar>PYTHONPATH</envar>
+      environment variable so that the Mercurial executable can find
+      the rest of the Mercurial packages.  For example, on my laptop,
+      I have set it to <literal>/home/bos/lib/python</literal>.  The
+      exact path that you will need to use depends on how Python was
+      built for your system, but should be easy to figure out.  If
+      you're uncertain, look through the output of the installer
+      script above, and see where the contents of the
+      <literal>mercurial</literal> directory were installed to.</para>
+
+  </sect1>
+  <sect1>
+    <title>On Windows</title>
+
+    <para id="x_5e6">Building and installing Mercurial on Windows requires a
+      variety of tools, a fair amount of technical knowledge, and
+      considerable patience.  I very much <emphasis>do not
+	recommend</emphasis> this route if you are a <quote>casual
+	user</quote>.  Unless you intend to hack on Mercurial, I
+      strongly suggest that you use a binary package instead.</para>
+
+    <para id="x_5e7">If you are intent on building Mercurial from source on
+      Windows, follow the <quote>hard way</quote> directions on the
+      Mercurial wiki at <ulink
+	url="http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall">http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, 
+      and expect the process to involve a lot of fiddly work.</para>
+
+  </sect1>
+</appendix>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "appendix")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/appD-license.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,179 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<appendix id="cha:opl">
+  <?dbhtml filename="open-publication-license.html"?>
+  <title>Open Publication License</title>
+
+  <para id="x_638">Version 1.0, 8 June 1999</para>
+
+  <sect1>
+    <title>Requirements on both unmodified and modified
+      versions</title>
+
+    <para id="x_639">The Open Publication works may be reproduced and distributed
+      in whole or in part, in any medium physical or electronic,
+      provided that the terms of this license are adhered to, and that
+      this license or an incorporation of it by reference (with any
+      options elected by the author(s) and/or publisher) is displayed
+      in the reproduction.</para>
+
+    <para id="x_63a">Proper form for an incorporation by reference is as
+      follows:</para>
+
+    <blockquote>
+      <para id="x_63b">  Copyright (c) <emphasis>year</emphasis> by
+	<emphasis>author's name or designee</emphasis>. This material
+	may be distributed only subject to the terms and conditions
+	set forth in the Open Publication License,
+	v<emphasis>x.y</emphasis> or later (the latest version is
+	presently available at <ulink
+	  url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).</para>
+    </blockquote>
+
+    <para id="x_63c">The reference must be immediately followed with any options
+      elected by the author(s) and/or publisher of the document (see
+      <xref linkend="sec:opl:options"/>).</para>
+
+    <para id="x_63d">Commercial redistribution of Open Publication-licensed
+      material is permitted.</para>
+
+    <para id="x_63e">Any publication in standard (paper) book form shall require
+      the citation of the original publisher and author. The publisher
+      and author's names shall appear on all outer surfaces of the
+      book. On all outer surfaces of the book the original publisher's
+      name shall be as large as the title of the work and cited as
+      possessive with respect to the title.</para>
+
+  </sect1>
+  <sect1>
+    <title>Copyright</title>
+
+    <para id="x_63f">The copyright to each Open Publication is owned by its
+      author(s) or designee.</para>
+
+  </sect1>
+  <sect1>
+    <title>Scope of license</title>
+
+    <para id="x_640">The following license terms apply to all Open Publication
+      works, unless otherwise explicitly stated in the
+      document.</para>
+
+    <para id="x_641">Mere aggregation of Open Publication works or a portion of
+      an Open Publication work with other works or programs on the
+      same media shall not cause this license to apply to those other
+      works. The aggregate work shall contain a notice specifying the
+      inclusion of the Open Publication material and appropriate
+      copyright notice.</para>
+
+    <para id="x_642"><emphasis role="bold">Severability</emphasis>. If any part
+      of this license is found to be unenforceable in any
+      jurisdiction, the remaining portions of the license remain in
+      force.</para>
+
+    <para id="x_643"><emphasis role="bold">No warranty</emphasis>. Open
+      Publication works are licensed and provided <quote>as is</quote>
+      without warranty of any kind, express or implied, including, but
+      not limited to, the implied warranties of merchantability and
+      fitness for a particular purpose or a warranty of
+      non-infringement.</para>
+
+  </sect1>
+  <sect1>
+    <title>Requirements on modified works</title>
+
+    <para id="x_644">All modified versions of documents covered by this license,
+      including translations, anthologies, compilations and partial
+      documents, must meet the following requirements:</para>
+
+    <orderedlist>
+      <listitem><para id="x_645">The modified version must be labeled as
+	  such.</para>
+      </listitem>
+      <listitem><para id="x_646">The person making the modifications must be
+	  identified and the modifications dated.</para>
+      </listitem>
+      <listitem><para id="x_647">Acknowledgement of the original author and
+	  publisher if applicable must be retained according to normal
+	  academic citation practices.</para>
+      </listitem>
+      <listitem><para id="x_648">The location of the original unmodified document
+	  must be identified.</para>
+      </listitem>
+      <listitem><para id="x_649">The original author's (or authors') name(s) may
+	  not be used to assert or imply endorsement of the resulting
+	  document without the original author's (or authors')
+	  permission.</para>
+      </listitem></orderedlist>
+
+  </sect1>
+  <sect1>
+    <title>Good-practice recommendations</title>
+
+    <para id="x_64a">In addition to the requirements of this license, it is
+      requested from and strongly recommended of redistributors
+      that:</para>
+
+    <orderedlist>
+      <listitem><para id="x_64b">If you are distributing Open Publication works
+	  on hardcopy or CD-ROM, you provide email notification to the
+	  authors of your intent to redistribute at least thirty days
+	  before your manuscript or media freeze, to give the authors
+	  time to provide updated documents. This notification should
+	  describe modifications, if any, made to the document.</para>
+      </listitem>
+      <listitem><para id="x_64c">All substantive modifications (including
+	  deletions) be either clearly marked up in the document or
+	  else described in an attachment to the document.</para>
+      </listitem>
+      <listitem><para id="x_64d">Finally, while it is not mandatory under this
+	  license, it is considered good form to offer a free copy of
+	  any hardcopy and CD-ROM expression of an Open
+	  Publication-licensed work to its author(s).</para>
+      </listitem></orderedlist>
+
+  </sect1>
+  <sect1 id="sec:opl:options">
+    <title>License options</title>
+
+    <para id="x_64e">The author(s) and/or publisher of an Open
+      Publication-licensed document may elect certain options by
+      appending language to the reference to or copy of the license.
+      These options are considered part of the license instance and
+      must be included with the license (or its incorporation by
+      reference) in derived works.</para>
+
+    <orderedlist>
+      <listitem><para id="x_64f">To prohibit distribution of substantively
+	  modified versions without the explicit permission of the
+	  author(s). <quote>Substantive modification</quote> is
+	  defined as a change to the semantic content of the document,
+	  and excludes mere changes in format or typographical
+	  corrections.</para>
+      </listitem>
+      <listitem><para id="x_650">  To accomplish this, add the phrase
+	  <quote>Distribution of substantively modified versions of
+	    this document is prohibited without the explicit
+	    permission of the copyright holder.</quote> to the license
+	  reference or copy.</para>
+      </listitem>
+      <listitem><para id="x_651">To prohibit any publication of this work or
+	  derivative works in whole or in part in standard (paper)
+	  book form for commercial purposes is prohibited unless prior
+	  permission is obtained from the copyright holder.</para>
+      </listitem>
+      <listitem><para id="x_652">To accomplish this, add the phrase
+	  <quote>Distribution of the work or derivative of the work in
+	    any standard (paper) book form is prohibited unless prior
+	    permission is obtained from the copyright holder.</quote>
+	  to the license reference or copy.</para>
+      </listitem></orderedlist>
+
+  </sect1>
+</appendix>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "appendix")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/autoid.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# Add unique ID attributes to para tags.  This script should only be
+# run by one person, since otherwise it introduces the possibility of
+# chaotic conflicts among tags.
+
+import glob, os, re, sys
+
+tagged = re.compile('<para[^>]* id="x_([0-9a-f]+)"[^>]*>', re.M)
+untagged = re.compile('<para>')
+
+names = glob.glob('ch*.xml') + glob.glob('app*.xml')
+
+# First pass: find the highest-numbered paragraph ID.
+
+biggest_id = 0
+seen = set()
+errs = 0
+
+for name in names:
+    for m in tagged.finditer(open(name).read()):
+        i = int(m.group(1),16)
+        if i in seen:
+            print >> sys.stderr, '%s: duplication of ID %s' % (name, i)
+            errs += 1
+        seen.add(i)
+        if i > biggest_id:
+            biggest_id = i
+
+def retag(s):
+    global biggest_id
+    biggest_id += 1
+    return '<para id="x_%x">' % biggest_id
+
+# Second pass: add IDs to paragraphs that currently lack them.
+
+for name in names:
+    f = open(name).read()
+    f1 = untagged.sub(retag, f)
+    if f1 != f:
+        tmpname = name + '.tmp'
+        fp = open(tmpname, 'w')
+        fp.write(f1)
+        fp.close()
+        os.rename(tmpname, name)
+
+sys.exit(errs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/book-shortcuts.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,3 @@
+<!-- Please keep the contents of this file sorted. -->
+
+<!ENTITY emdash "&#8212;">
--- a/en/bookhtml.cfg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-% -*- 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
--- a/en/branch.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-\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}
-We can no longer update from \texttt{foo} to \texttt{bar} without
-going ``sideways'' in history, so Mercurial forces us to provide the
-\hgopt{update}{-C} option to \hgcmd{update}.
-\interaction{branch-named.update-bar}
-
-\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: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch00-preface.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,757 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<preface id="chap:preface">
+  <?dbhtml filename="preface.html"?>
+  <title>Preface</title>
+
+  <sect1>
+    <title>Why revision control? Why Mercurial?</title>
+
+    <para id="x_6d">Revision control is the process of managing multiple
+      versions of a piece of information.  In its simplest form, this
+      is something that many people do by hand: every time you modify
+      a file, save it under a new name that contains a number, each
+      one higher than the number of the preceding version.</para>
+
+    <para id="x_6e">Manually managing multiple versions of even a single file is
+      an error-prone task, though, so software tools to help automate
+      this process have long been available.  The earliest automated
+      revision control tools were intended to help a single user to
+      manage revisions of a single file.  Over the past few decades,
+      the scope of revision control tools has expanded greatly; they
+      now manage multiple files, and help multiple people to work
+      together.  The best modern revision control tools have no
+      problem coping with thousands of people working together on
+      projects that consist of hundreds of thousands of files.</para>
+
+    <para id="x_6f">The arrival of distributed revision control is relatively
+      recent, and so far this new field has grown due to people's
+      willingness to explore ill-charted territory.</para>
+
+    <para id="x_70">I am writing a book about distributed revision control
+      because I believe that it is an important subject that deserves
+      a field guide. I chose to write about Mercurial because it is
+      the easiest tool to learn the terrain with, and yet it scales to
+      the demands of real, challenging environments where many other
+      revision control tools buckle.</para>
+
+    <sect2>
+      <title>Why use revision control?</title>
+
+      <para id="x_71">There are a number of reasons why you or your team might
+	want to use an automated revision control tool for a
+	project.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_72">It will track the history and evolution of
+	    your project, so you don't have to.  For every change,
+	    you'll have a log of <emphasis>who</emphasis> made it;
+	    <emphasis>why</emphasis> they made it;
+	    <emphasis>when</emphasis> they made it; and
+	    <emphasis>what</emphasis> the change
+	    was.</para></listitem>
+	<listitem><para id="x_73">When you're working with other people,
+	    revision control software makes it easier for you to
+	    collaborate.  For example, when people more or less
+	    simultaneously make potentially incompatible changes, the
+	    software will help you to identify and resolve those
+	    conflicts.</para></listitem>
+	<listitem><para id="x_74">It can help you to recover from mistakes.  If
+	    you make a change that later turns out to be in error, you
+	    can revert to an earlier version of one or more files.  In
+	    fact, a <emphasis>really</emphasis> good revision control
+	    tool will even help you to efficiently figure out exactly
+	    when a problem was introduced (see <xref
+	      linkend="sec:undo:bisect"/> for details).</para></listitem>
+	<listitem><para id="x_75">It will help you to work simultaneously on,
+	    and manage the drift between, multiple versions of your
+	    project.</para></listitem>
+      </itemizedlist>
+
+      <para id="x_76">Most of these reasons are equally
+	valid&emdash;at least in theory&emdash;whether you're working
+	on a project by yourself, or with a hundred other
+	people.</para>
+
+      <para id="x_77">A key question about the practicality of revision control
+	at these two different scales (<quote>lone hacker</quote> and
+	<quote>huge team</quote>) is how its
+	<emphasis>benefits</emphasis> compare to its
+	<emphasis>costs</emphasis>.  A revision control tool that's
+	difficult to understand or use is going to impose a high
+	cost.</para>
+
+      <para id="x_78">A five-hundred-person project is likely to collapse under
+	its own weight almost immediately without a revision control
+	tool and process. In this case, the cost of using revision
+	control might hardly seem worth considering, since
+	<emphasis>without</emphasis> it, failure is almost
+	guaranteed.</para>
+
+      <para id="x_79">On the other hand, a one-person <quote>quick hack</quote>
+	might seem like a poor place to use a revision control tool,
+	because surely the cost of using one must be close to the
+	overall cost of the project.  Right?</para>
+
+      <para id="x_7a">Mercurial uniquely supports <emphasis>both</emphasis> of
+	these scales of development.  You can learn the basics in just
+	a few minutes, and due to its low overhead, you can apply
+	revision control to the smallest of projects with ease.  Its
+	simplicity means you won't have a lot of abstruse concepts or
+	command sequences competing for mental space with whatever
+	you're <emphasis>really</emphasis> trying to do.  At the same
+	time, Mercurial's high performance and peer-to-peer nature let
+	you scale painlessly to handle large projects.</para>
+
+      <para id="x_7b">No revision control tool can rescue a poorly run project,
+	but a good choice of tools can make a huge difference to the
+	fluidity with which you can work on a project.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>The many names of revision control</title>
+
+      <para id="x_7c">Revision control is a diverse field, so much so that it is
+	referred to by many names and acronyms.  Here are a few of the
+	more common variations you'll encounter:</para>
+      <itemizedlist>
+	<listitem><para id="x_7d">Revision control (RCS)</para></listitem>
+	<listitem><para id="x_7e">Software configuration management (SCM), or
+	    configuration management</para></listitem>
+	<listitem><para id="x_7f">Source code management</para></listitem>
+	<listitem><para id="x_80">Source code control, or source
+	    control</para></listitem>
+	<listitem><para id="x_81">Version control
+	    (VCS)</para></listitem></itemizedlist>
+      <para id="x_82">Some people claim that these terms actually have different
+	meanings, but in practice they overlap so much that there's no
+	agreed or even useful way to tease them apart.</para>
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>This book is a work in progress</title>
+
+    <para id="x_83">I am releasing this book while I am still writing it, in the
+      hope that it will prove useful to others.  I am writing under an
+      open license in the hope that you, my readers, will contribute
+      feedback and perhaps content of your own.</para>
+
+  </sect1>
+  <sect1>
+    <title>About the examples in this book</title>
+
+    <para id="x_84">This book takes an unusual approach to code samples.  Every
+      example is <quote>live</quote>&emdash;each one is actually the result
+      of a shell script that executes the Mercurial commands you see.
+      Every time an image of the book is built from its sources, all
+      the example scripts are automatically run, and their current
+      results compared against their expected results.</para>
+
+    <para id="x_85">The advantage of this approach is that the examples are
+      always accurate; they describe <emphasis>exactly</emphasis> the
+      behavior of the version of Mercurial that's mentioned at the
+      front of the book.  If I update the version of Mercurial that
+      I'm documenting, and the output of some command changes, the
+      build fails.</para>
+
+    <para id="x_86">There is a small disadvantage to this approach, which is
+      that the dates and times you'll see in examples tend to be
+      <quote>squashed</quote> together in a way that they wouldn't be
+      if the same commands were being typed by a human.  Where a human
+      can issue no more than one command every few seconds, with any
+      resulting timestamps correspondingly spread out, my automated
+      example scripts run many commands in one second.</para>
+
+    <para id="x_87">As an instance of this, several consecutive commits in an
+      example can show up as having occurred during the same second.
+      You can see this occur in the <literal
+	role="hg-ext">bisect</literal> example in <xref
+	linkend="sec:undo:bisect"/>, for instance.</para>
+
+    <para id="x_88">So when you're reading examples, don't place too much weight
+      on the dates or times you see in the output of commands.  But
+      <emphasis>do</emphasis> be confident that the behavior you're
+      seeing is consistent and reproducible.</para>
+
+  </sect1>
+
+  <sect1>
+    <title>Trends in the field</title>
+
+    <para id="x_89">There has been an unmistakable trend in the development and
+      use of revision control tools over the past four decades, as
+      people have become familiar with the capabilities of their tools
+      and constrained by their limitations.</para>
+
+    <para id="x_8a">The first generation began by managing single files on
+      individual computers.  Although these tools represented a huge
+      advance over ad-hoc manual revision control, their locking model
+      and reliance on a single computer limited them to small,
+      tightly-knit teams.</para>
+
+    <para id="x_8b">The second generation loosened these constraints by moving
+      to network-centered architectures, and managing entire projects
+      at a time.  As projects grew larger, they ran into new problems.
+      With clients needing to talk to servers very frequently, server
+      scaling became an issue for large projects.  An unreliable
+      network connection could prevent remote users from being able to
+      talk to the server at all.  As open source projects started
+      making read-only access available anonymously to anyone, people
+      without commit privileges found that they could not use the
+      tools to interact with a project in a natural way, as they could
+      not record their changes.</para>
+
+    <para id="x_8c">The current generation of revision control tools is
+      peer-to-peer in nature.  All of these systems have dropped the
+      dependency on a single central server, and allow people to
+      distribute their revision control data to where it's actually
+      needed.  Collaboration over the Internet has moved from
+      constrained by technology to a matter of choice and consensus.
+      Modern tools can operate offline indefinitely and autonomously,
+      with a network connection only needed when syncing changes with
+      another repository.</para>
+
+  </sect1>
+  <sect1>
+    <title>A few of the advantages of distributed revision
+      control</title>
+
+    <para id="x_8d">Even though distributed revision control tools have for
+      several years been as robust and usable as their
+      previous-generation counterparts, people using older tools have
+      not yet necessarily woken up to their advantages.  There are a
+      number of ways in which distributed tools shine relative to
+      centralised ones.</para>
+
+    <para id="x_8e">For an individual developer, distributed tools are almost
+      always much faster than centralised tools.  This is for a simple
+      reason: a centralised tool needs to talk over the network for
+      many common operations, because most metadata is stored in a
+      single copy on the central server.  A distributed tool stores
+      all of its metadata locally.  All else being equal, talking over
+      the network adds overhead to a centralised tool.  Don't
+      underestimate the value of a snappy, responsive tool: you're
+      going to spend a lot of time interacting with your revision
+      control software.</para>
+
+    <para id="x_8f">Distributed tools are indifferent to the vagaries of your
+      server infrastructure, again because they replicate metadata to
+      so many locations.  If you use a centralised system and your
+      server catches fire, you'd better hope that your backup media
+      are reliable, and that your last backup was recent and actually
+      worked.  With a distributed tool, you have many backups
+      available on every contributor's computer.</para>
+
+    <para id="x_90">The reliability of your network will affect distributed
+      tools far less than it will centralised tools.  You can't even
+      use a centralised tool without a network connection, except for
+      a few highly constrained commands.  With a distributed tool, if
+      your network connection goes down while you're working, you may
+      not even notice.  The only thing you won't be able to do is talk
+      to repositories on other computers, something that is relatively
+      rare compared with local operations.  If you have a far-flung
+      team of collaborators, this may be significant.</para>
+
+    <sect2>
+      <title>Advantages for open source projects</title>
+
+      <para id="x_91">If you take a shine to an open source project and decide
+	that you would like to start hacking on it, and that project
+	uses a distributed revision control tool, you are at once a
+	peer with the people who consider themselves the
+	<quote>core</quote> of that project.  If they publish their
+	repositories, you can immediately copy their project history,
+	start making changes, and record your work, using the same
+	tools in the same ways as insiders.  By contrast, with a
+	centralised tool, you must use the software in a <quote>read
+	  only</quote> mode unless someone grants you permission to
+	commit changes to their central server.  Until then, you won't
+	be able to record changes, and your local modifications will
+	be at risk of corruption any time you try to update your
+	client's view of the repository.</para>
+
+      <sect3>
+	<title>The forking non-problem</title>
+
+	<para id="x_92">It has been suggested that distributed revision control
+	  tools pose some sort of risk to open source projects because
+	  they make it easy to <quote>fork</quote> the development of
+	  a project.  A fork happens when there are differences in
+	  opinion or attitude between groups of developers that cause
+	  them to decide that they can't work together any longer.
+	  Each side takes a more or less complete copy of the
+	  project's source code, and goes off in its own
+	  direction.</para>
+
+	<para id="x_93">Sometimes the camps in a fork decide to reconcile their
+	  differences. With a centralised revision control system, the
+	  <emphasis>technical</emphasis> process of reconciliation is
+	  painful, and has to be performed largely by hand.  You have
+	  to decide whose revision history is going to
+	  <quote>win</quote>, and graft the other team's changes into
+	  the tree somehow. This usually loses some or all of one
+	  side's revision history.</para>
+
+	<para id="x_94">What distributed tools do with respect to forking is
+	  they make forking the <emphasis>only</emphasis> way to
+	  develop a project.  Every single change that you make is
+	  potentially a fork point.  The great strength of this
+	  approach is that a distributed revision control tool has to
+	  be really good at <emphasis>merging</emphasis> forks,
+	  because forks are absolutely fundamental: they happen all
+	  the time.</para>
+
+	<para id="x_95">If every piece of work that everybody does, all the
+	  time, is framed in terms of forking and merging, then what
+	  the open source world refers to as a <quote>fork</quote>
+	  becomes <emphasis>purely</emphasis> a social issue.  If
+	  anything, distributed tools <emphasis>lower</emphasis> the
+	  likelihood of a fork:</para>
+	<itemizedlist>
+	  <listitem><para id="x_96">They eliminate the social distinction that
+	      centralised tools impose: that between insiders (people
+	      with commit access) and outsiders (people
+	      without).</para></listitem>
+	  <listitem><para id="x_97">They make it easier to reconcile after a
+	      social fork, because all that's involved from the
+	      perspective of the revision control software is just
+	      another merge.</para></listitem></itemizedlist>
+
+	<para id="x_98">Some people resist distributed tools because they want
+	  to retain tight control over their projects, and they
+	  believe that centralised tools give them this control.
+	  However, if you're of this belief, and you publish your CVS
+	  or Subversion repositories publicly, there are plenty of
+	  tools available that can pull out your entire project's
+	  history (albeit slowly) and recreate it somewhere that you
+	  don't control.  So while your control in this case is
+	  illusory, you are forgoing the ability to fluidly
+	  collaborate with whatever people feel compelled to mirror
+	  and fork your history.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Advantages for commercial projects</title>
+
+      <para id="x_99">Many commercial projects are undertaken by teams that are
+	scattered across the globe.  Contributors who are far from a
+	central server will see slower command execution and perhaps
+	less reliability.  Commercial revision control systems attempt
+	to ameliorate these problems with remote-site replication
+	add-ons that are typically expensive to buy and cantankerous
+	to administer.  A distributed system doesn't suffer from these
+	problems in the first place.  Better yet, you can easily set
+	up multiple authoritative servers, say one per site, so that
+	there's no redundant communication between repositories over
+	expensive long-haul network links.</para>
+
+      <para id="x_9a">Centralised revision control systems tend to have
+	relatively low scalability.  It's not unusual for an expensive
+	centralised system to fall over under the combined load of
+	just a few dozen concurrent users.  Once again, the typical
+	response tends to be an expensive and clunky replication
+	facility.  Since the load on a central server&emdash;if you have
+	one at all&emdash;is many times lower with a distributed tool
+	(because all of the data is replicated everywhere), a single
+	cheap server can handle the needs of a much larger team, and
+	replication to balance load becomes a simple matter of
+	scripting.</para>
+
+      <para id="x_9b">If you have an employee in the field, troubleshooting a
+	problem at a customer's site, they'll benefit from distributed
+	revision control. The tool will let them generate custom
+	builds, try different fixes in isolation from each other, and
+	search efficiently through history for the sources of bugs and
+	regressions in the customer's environment, all without needing
+	to connect to your company's network.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Why choose Mercurial?</title>
+
+    <para id="x_9c">Mercurial has a unique set of properties that make it a
+      particularly good choice as a revision control system.</para>
+    <itemizedlist>
+      <listitem><para id="x_9d">It is easy to learn and use.</para></listitem>
+      <listitem><para id="x_9e">It is lightweight.</para></listitem>
+      <listitem><para id="x_9f">It scales excellently.</para></listitem>
+      <listitem><para id="x_a0">It is easy to
+	  customise.</para></listitem></itemizedlist>
+
+    <para id="x_a1">If you are at all familiar with revision control systems,
+      you should be able to get up and running with Mercurial in less
+      than five minutes.  Even if not, it will take no more than a few
+      minutes longer.  Mercurial's command and feature sets are
+      generally uniform and consistent, so you can keep track of a few
+      general rules instead of a host of exceptions.</para>
+
+    <para id="x_a2">On a small project, you can start working with Mercurial in
+      moments. Creating new changes and branches; transferring changes
+      around (whether locally or over a network); and history and
+      status operations are all fast.  Mercurial attempts to stay
+      nimble and largely out of your way by combining low cognitive
+      overhead with blazingly fast operations.</para>
+
+    <para id="x_a3">The usefulness of Mercurial is not limited to small
+      projects: it is used by projects with hundreds to thousands of
+      contributors, each containing tens of thousands of files and
+      hundreds of megabytes of source code.</para>
+
+    <para id="x_a4">If the core functionality of Mercurial is not enough for
+      you, it's easy to build on.  Mercurial is well suited to
+      scripting tasks, and its clean internals and implementation in
+      Python make it easy to add features in the form of extensions.
+      There are a number of popular and useful extensions already
+      available, ranging from helping to identify bugs to improving
+      performance.</para>
+
+  </sect1>
+  <sect1>
+    <title>Mercurial compared with other tools</title>
+
+    <para id="x_a5">Before you read on, please understand that this section
+      necessarily reflects my own experiences, interests, and (dare I
+      say it) biases.  I have used every one of the revision control
+      tools listed below, in most cases for several years at a
+      time.</para>
+
+
+    <sect2>
+      <title>Subversion</title>
+
+      <para id="x_a6">Subversion is a popular revision control tool, developed
+	to replace CVS.  It has a centralised client/server
+	architecture.</para>
+
+      <para id="x_a7">Subversion and Mercurial have similarly named commands for
+	performing the same operations, so if you're familiar with
+	one, it is easy to learn to use the other.  Both tools are
+	portable to all popular operating systems.</para>
+
+      <para id="x_a8">Prior to version 1.5, Subversion had no useful support for
+	merges. At the time of writing, its merge tracking capability
+	is new, and known to be <ulink
+	  url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 
+	  and buggy</ulink>.</para>
+
+      <para id="x_a9">Mercurial has a substantial performance advantage over
+	Subversion on every revision control operation I have
+	benchmarked.  I have measured its advantage as ranging from a
+	factor of two to a factor of six when compared with Subversion
+	1.4.3's <emphasis>ra_local</emphasis> file store, which is the
+	fastest access method available.  In more realistic
+	deployments involving a network-based store, Subversion will
+	be at a substantially larger disadvantage.  Because many
+	Subversion commands must talk to the server and Subversion
+	does not have useful replication facilities, server capacity
+	and network bandwidth become bottlenecks for modestly large
+	projects.</para>
+
+      <para id="x_aa">Additionally, Subversion incurs substantial storage
+	overhead to avoid network transactions for a few common
+	operations, such as finding modified files
+	(<literal>status</literal>) and displaying modifications
+	against the current revision (<literal>diff</literal>).  As a
+	result, a Subversion working copy is often the same size as,
+	or larger than, a Mercurial repository and working directory,
+	even though the Mercurial repository contains a complete
+	history of the project.</para>
+
+      <para id="x_ab">Subversion is widely supported by third party tools.
+	Mercurial currently lags considerably in this area.  This gap
+	is closing, however, and indeed some of Mercurial's GUI tools
+	now outshine their Subversion equivalents.  Like Mercurial,
+	Subversion has an excellent user manual.</para>
+
+      <para id="x_ac">Because Subversion doesn't store revision history on the
+	client, it is well suited to managing projects that deal with
+	lots of large, opaque binary files.  If you check in fifty
+	revisions to an incompressible 10MB file, Subversion's
+	client-side space usage stays constant The space used by any
+	distributed SCM will grow rapidly in proportion to the number
+	of revisions, because the differences between each revision
+	are large.</para>
+
+      <para id="x_ad">In addition, it's often difficult or, more usually,
+	impossible to merge different versions of a binary file.
+	Subversion's ability to let a user lock a file, so that they
+	temporarily have the exclusive right to commit changes to it,
+	can be a significant advantage to a project where binary files
+	are widely used.</para>
+
+      <para id="x_ae">Mercurial can import revision history from a Subversion
+	repository. It can also export revision history to a
+	Subversion repository.  This makes it easy to <quote>test the
+	  waters</quote> and use Mercurial and Subversion in parallel
+	before deciding to switch.  History conversion is incremental,
+	so you can perform an initial conversion, then small
+	additional conversions afterwards to bring in new
+	changes.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Git</title>
+
+      <para id="x_af">Git is a distributed revision control tool that was
+	developed for managing the Linux kernel source tree.  Like
+	Mercurial, its early design was somewhat influenced by
+	Monotone.</para>
+
+      <para id="x_b0">Git has a very large command set, with version 1.5.0
+	providing 139 individual commands.  It has something of a
+	reputation for being difficult to learn.  Compared to Git,
+	Mercurial has a strong focus on simplicity.</para>
+
+      <para id="x_b1">In terms of performance, Git is extremely fast.  In
+	several cases, it is faster than Mercurial, at least on Linux,
+	while Mercurial performs better on other operations.  However,
+	on Windows, the performance and general level of support that
+	Git provides is, at the time of writing, far behind that of
+	Mercurial.</para>
+
+      <para id="x_b2">While a Mercurial repository needs no maintenance, a Git
+	repository requires frequent manual <quote>repacks</quote> of
+	its metadata.  Without these, performance degrades, while
+	space usage grows rapidly.  A server that contains many Git
+	repositories that are not rigorously and frequently repacked
+	will become heavily disk-bound during backups, and there have
+	been instances of daily backups taking far longer than 24
+	hours as a result.  A freshly packed Git repository is
+	slightly smaller than a Mercurial repository, but an unpacked
+	repository is several orders of magnitude larger.</para>
+
+      <para id="x_b3">The core of Git is written in C.  Many Git commands are
+	implemented as shell or Perl scripts, and the quality of these
+	scripts varies widely. I have encountered several instances
+	where scripts charged along blindly in the presence of errors
+	that should have been fatal.</para>
+
+      <para id="x_b4">Mercurial can import revision history from a Git
+	repository.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>CVS</title>
+
+      <para id="x_b5">CVS is probably the most widely used revision control tool
+	in the world.  Due to its age and internal untidiness, it has
+	been only lightly maintained for many years.</para>
+
+      <para id="x_b6">It has a centralised client/server architecture.  It does
+	not group related file changes into atomic commits, making it
+	easy for people to <quote>break the build</quote>: one person
+	can successfully commit part of a change and then be blocked
+	by the need for a merge, causing other people to see only a
+	portion of the work they intended to do.  This also affects
+	how you work with project history.  If you want to see all of
+	the modifications someone made as part of a task, you will
+	need to manually inspect the descriptions and timestamps of
+	the changes made to each file involved (if you even know what
+	those files were).</para>
+
+      <para id="x_b7">CVS has a muddled notion of tags and branches that I will
+	not attempt to even describe.  It does not support renaming of
+	files or directories well, making it easy to corrupt a
+	repository.  It has almost no internal consistency checking
+	capabilities, so it is usually not even possible to tell
+	whether or how a repository is corrupt.  I would not recommend
+	CVS for any project, existing or new.</para>
+
+      <para id="x_b8">Mercurial can import CVS revision history.  However, there
+	are a few caveats that apply; these are true of every other
+	revision control tool's CVS importer, too.  Due to CVS's lack
+	of atomic changes and unversioned filesystem hierarchy, it is
+	not possible to reconstruct CVS history completely accurately;
+	some guesswork is involved, and renames will usually not show
+	up.  Because a lot of advanced CVS administration has to be
+	done by hand and is hence error-prone, it's common for CVS
+	importers to run into multiple problems with corrupted
+	repositories (completely bogus revision timestamps and files
+	that have remained locked for over a decade are just two of
+	the less interesting problems I can recall from personal
+	experience).</para>
+
+      <para id="x_b9">Mercurial can import revision history from a CVS
+	repository.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Commercial tools</title>
+
+      <para id="x_ba">Perforce has a centralised client/server architecture,
+	with no client-side caching of any data.  Unlike modern
+	revision control tools, Perforce requires that a user run a
+	command to inform the server about every file they intend to
+	edit.</para>
+
+      <para id="x_bb">The performance of Perforce is quite good for small teams,
+	but it falls off rapidly as the number of users grows beyond a
+	few dozen. Modestly large Perforce installations require the
+	deployment of proxies to cope with the load their users
+	generate.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Choosing a revision control tool</title>
+
+      <para id="x_bc">With the exception of CVS, all of the tools listed above
+	have unique strengths that suit them to particular styles of
+	work.  There is no single revision control tool that is best
+	in all situations.</para>
+
+      <para id="x_bd">As an example, Subversion is a good choice for working
+	with frequently edited binary files, due to its centralised
+	nature and support for file locking.</para>
+
+      <para id="x_be">I personally find Mercurial's properties of simplicity,
+	performance, and good merge support to be a compelling
+	combination that has served me well for several years.</para>
+
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Switching from another tool to Mercurial</title>
+
+    <para id="x_bf">Mercurial is bundled with an extension named <literal
+	role="hg-ext">convert</literal>, which can incrementally
+      import revision history from several other revision control
+      tools.  By <quote>incremental</quote>, I mean that you can
+      convert all of a project's history to date in one go, then rerun
+      the conversion later to obtain new changes that happened after
+      the initial conversion.</para>
+
+    <para id="x_c0">The revision control tools supported by <literal
+	role="hg-ext">convert</literal> are as follows:</para>
+    <itemizedlist>
+      <listitem><para id="x_c1">Subversion</para></listitem>
+      <listitem><para id="x_c2">CVS</para></listitem>
+      <listitem><para id="x_c3">Git</para></listitem>
+      <listitem><para id="x_c4">Darcs</para></listitem></itemizedlist>
+
+    <para id="x_c5">In addition, <literal role="hg-ext">convert</literal> can
+      export changes from Mercurial to Subversion.  This makes it
+      possible to try Subversion and Mercurial in parallel before
+      committing to a switchover, without risking the loss of any
+      work.</para>
+
+    <para id="x_c6">The <command role="hg-ext-convert">convert</command> command
+      is easy to use.  Simply point it at the path or URL of the
+      source repository, optionally give it the name of the
+      destination repository, and it will start working.  After the
+      initial conversion, just run the same command again to import
+      new changes.</para>
+  </sect1>
+
+  <sect1>
+    <title>A short history of revision control</title>
+
+    <para id="x_c7">The best known of the old-time revision control tools is
+      SCCS (Source Code Control System), which Marc Rochkind wrote at
+      Bell Labs, in the early 1970s.  SCCS operated on individual
+      files, and required every person working on a project to have
+      access to a shared workspace on a single system.  Only one
+      person could modify a file at any time; arbitration for access
+      to files was via locks.  It was common for people to lock files,
+      and later forget to unlock them, preventing anyone else from
+      modifying those files without the help of an
+      administrator.</para>
+
+    <para id="x_c8">Walter Tichy developed a free alternative to SCCS in the
+      early 1980s; he called his program RCS (Revision Control System).
+      Like SCCS, RCS required developers to work in a single shared
+      workspace, and to lock files to prevent multiple people from
+      modifying them simultaneously.</para>
+
+    <para id="x_c9">Later in the 1980s, Dick Grune used RCS as a building block
+      for a set of shell scripts he initially called cmt, but then
+      renamed to CVS (Concurrent Versions System).  The big innovation
+      of CVS was that it let developers work simultaneously and
+      somewhat independently in their own personal workspaces.  The
+      personal workspaces prevented developers from stepping on each
+      other's toes all the time, as was common with SCCS and RCS. Each
+      developer had a copy of every project file, and could modify
+      their copies independently.  They had to merge their edits prior
+      to committing changes to the central repository.</para>
+
+    <para id="x_ca">Brian Berliner took Grune's original scripts and rewrote
+      them in C, releasing in 1989 the code that has since developed
+      into the modern version of CVS.  CVS subsequently acquired the
+      ability to operate over a network connection, giving it a
+      client/server architecture.  CVS's architecture is centralised;
+      only the server has a copy of the history of the project. Client
+      workspaces just contain copies of recent versions of the
+      project's files, and a little metadata to tell them where the
+      server is.  CVS has been enormously successful; it is probably
+      the world's most widely used revision control system.</para>
+
+    <para id="x_cb">In the early 1990s, Sun Microsystems developed an early
+      distributed revision control system, called TeamWare.  A
+      TeamWare workspace contains a complete copy of the project's
+      history.  TeamWare has no notion of a central repository.  (CVS
+      relied upon RCS for its history storage; TeamWare used
+      SCCS.)</para>
+
+    <para id="x_cc">As the 1990s progressed, awareness grew of a number of
+      problems with CVS.  It records simultaneous changes to multiple
+      files individually, instead of grouping them together as a
+      single logically atomic operation.  It does not manage its file
+      hierarchy well; it is easy to make a mess of a repository by
+      renaming files and directories.  Worse, its source code is
+      difficult to read and maintain, which made the <quote>pain
+	level</quote> of fixing these architectural problems
+      prohibitive.</para>
+
+    <para id="x_cd">In 2001, Jim Blandy and Karl Fogel, two developers who had
+      worked on CVS, started a project to replace it with a tool that
+      would have a better architecture and cleaner code.  The result,
+      Subversion, does not stray from CVS's centralised client/server
+      model, but it adds multi-file atomic commits, better namespace
+      management, and a number of other features that make it a
+      generally better tool than CVS. Since its initial release, it
+      has rapidly grown in popularity.</para>
+
+    <para id="x_ce">More or less simultaneously, Graydon Hoare began working on
+      an ambitious distributed revision control system that he named
+      Monotone. While Monotone addresses many of CVS's design flaws
+      and has a peer-to-peer architecture, it goes beyond earlier (and
+      subsequent) revision control tools in a number of innovative
+      ways.  It uses cryptographic hashes as identifiers, and has an
+      integral notion of <quote>trust</quote> for code from different
+      sources.</para>
+
+    <para id="x_cf">Mercurial began life in 2005.  While a few aspects of its
+      design are influenced by Monotone, Mercurial focuses on ease of
+      use, high performance, and scalability to very large
+      projects.</para>
+
+  </sect1>
+
+  <sect1>
+    <title>Colophon&emdash;this book is Free</title>
+
+    <para id="x_d0">This book is licensed under the Open Publication License,
+      and is produced entirely using Free Software tools.  It is
+      typeset with DocBook XML.  Illustrations are drawn and rendered with
+      <ulink url="http://www.inkscape.org/">Inkscape</ulink>.</para>
+
+    <para id="x_d1">The complete source code for this book is published as a
+      Mercurial repository, at <ulink
+	url="http://hg.serpentine.com/mercurial/book">http://hg.serpentine.com/mercurial/book</ulink>.</para>
+
+  </sect1>
+</preface>
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "preface")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch01-tour-basic.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,930 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:tour-basic">
+  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
+  <title>A tour of Mercurial: the basics</title>
+
+  <sect1 id="sec:tour:install">
+    <title>Installing Mercurial on your system</title>
+
+    <para id="x_1">Prebuilt binary packages of Mercurial are available for
+      every popular operating system.  These make it easy to start
+      using Mercurial on your computer immediately.</para>
+
+    <sect2>
+      <title>Windows</title>
+
+      <para id="x_c">The best version of Mercurial for Windows is
+	TortoiseHg, which can be found at <ulink
+	  url="http://bitbucket.org/tortoisehg/stable/wiki/Home">http://bitbucket.org/tortoisehg/stable/wiki/Home</ulink>. 
+	This package has no external dependencies; it <quote>just
+	  works</quote>.  It provides both command line and graphical
+	user interfaces.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>Mac OS X</title>
+
+      <para id="x_a">Lee Cantey publishes an installer of Mercurial
+	for Mac OS X at <ulink
+	  url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Linux</title>
+
+      <para id="x_2">Because each Linux distribution has its own packaging
+	tools, policies, and rate of development, it's difficult to
+	give a comprehensive set of instructions on how to install
+	Mercurial binaries.  The version of Mercurial that you will
+	end up with can vary depending on how active the person is who
+	maintains the package for your distribution.</para>
+
+      <para id="x_3">To keep things simple, I will focus on installing
+	Mercurial from the command line under the most popular Linux
+	distributions.  Most of these distributions provide graphical
+	package managers that will let you install Mercurial with a
+	single click; the package name to look for is
+	<literal>mercurial</literal>.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_4">Ubuntu and Debian:</para>
+	  <programlisting>apt-get install mercurial</programlisting></listitem>
+	<listitem><para id="x_5">Fedora and OpenSUSE:</para>
+	  <programlisting>yum install mercurial</programlisting></listitem>
+	<listitem><para id="x_6">Gentoo:</para>
+	  <programlisting>emerge mercurial</programlisting></listitem>
+      </itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Solaris</title>
+
+      <para id="x_9">SunFreeWare, at <ulink
+	  url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 
+	provides prebuilt packages of Mercurial.</para>
+
+    </sect2>
+
+  </sect1>
+
+  <sect1>
+    <title>Getting started</title>
+
+    <para id="x_e">To begin, we'll use the <command role="hg-cmd">hg
+	version</command> command to find out whether Mercurial is
+      actually installed properly.  The actual version information
+      that it prints isn't so important; it's whether it prints
+      anything at all that we care about.</para>
+
+    &interaction.tour.version;
+
+    <sect2>
+      <title>Built-in help</title>
+
+      <para id="x_f">Mercurial provides a built-in help system.  This is
+	  invaluable for those times when you find yourself stuck
+	  trying to remember how to run a command.  If you are
+	  completely stuck, simply run <command role="hg-cmd">hg
+	    help</command>; it will print a brief list of commands,
+	  along with a description of what each does.  If you ask for
+	  help on a specific command (as below), it prints more
+	  detailed information.</para>
+
+	&interaction.tour.help;
+
+	<para id="x_10">For a more impressive level of detail (which you won't
+	  usually need) run <command role="hg-cmd">hg help <option
+	      role="hg-opt-global">-v</option></command>.  The <option
+	    role="hg-opt-global">-v</option> option is short for
+	  <option role="hg-opt-global">--verbose</option>, and tells
+	  Mercurial to print more information than it usually
+	  would.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Working with a repository</title>
+
+    <para id="x_11">In Mercurial, everything happens inside a
+      <emphasis>repository</emphasis>.  The repository for a project
+      contains all of the files that <quote>belong to</quote> that
+      project, along with a historical record of the project's
+      files.</para>
+
+    <para id="x_12">There's nothing particularly magical about a repository; it
+      is simply a directory tree in your filesystem that Mercurial
+      treats as special. You can rename or delete a repository any
+      time you like, using either the command line or your file
+      browser.</para>
+
+    <sect2>
+      <title>Making a local copy of a repository</title>
+
+      <para id="x_13"><emphasis>Copying</emphasis> a repository is just a little
+	bit special.  While you could use a normal file copying
+	command to make a copy of a repository, it's best to use a
+	built-in command that Mercurial provides.  This command is
+	called <command role="hg-cmd">hg clone</command>, because it
+	makes an identical copy of an existing repository.</para>
+
+      &interaction.tour.clone;
+
+      <para id="x_67c">One advantage of using <command role="hg-cmd">hg
+	  clone</command> is that, as we can see above, it lets us clone
+	repositories over the network.  Another is that it remembers
+	where we cloned from, which we'll find useful soon when we
+	want to fetch new changes from another repository.</para>
+
+      <para id="x_14">If our clone succeeded, we should now have a local
+	directory called <filename class="directory">hello</filename>.
+	This directory will contain some files.</para>
+
+      &interaction.tour.ls;
+
+      <para id="x_15">These files have the same contents and history in our
+	repository as they do in the repository we cloned.</para>
+
+      <para id="x_16">Every Mercurial repository is complete,
+	self-contained, and independent.  It contains its own private
+	copy of a project's files and history.  As we just mentioned,
+	a cloned repository remembers the location of the repository
+	it was cloned from, but Mercurial will not communicate with
+	that repository, or any other, unless you tell it to.</para>
+
+      <para id="x_17">What this means for now is that we're free to experiment
+	with our repository, safe in the knowledge that it's a private
+	<quote>sandbox</quote> that won't affect anyone else.</para>
+
+    </sect2>
+    <sect2>
+      <title>What's in a repository?</title>
+
+      <para id="x_18">When we take a more detailed look inside a repository, we
+	can see that it contains a directory named <filename
+	  class="directory">.hg</filename>.  This is where Mercurial
+	keeps all of its metadata for the repository.</para>
+
+      &interaction.tour.ls-a;
+
+      <para id="x_19">The contents of the <filename
+	  class="directory">.hg</filename> directory and its
+	subdirectories are private to Mercurial.  Every other file and
+	directory in the repository is yours to do with as you
+	please.</para>
+
+      <para id="x_1a">To introduce a little terminology, the <filename
+	  class="directory">.hg</filename> directory is the
+	<quote>real</quote> repository, and all of the files and
+	directories that coexist with it are said to live in the
+	<emphasis>working directory</emphasis>.  An easy way to
+	remember the distinction is that the
+	<emphasis>repository</emphasis> contains the
+	<emphasis>history</emphasis> of your project, while the
+	<emphasis>working directory</emphasis> contains a
+	<emphasis>snapshot</emphasis> of your project at a particular
+	point in history.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>A tour through history</title>
+
+    <para id="x_1b">One of the first things we might want to do with a new,
+      unfamiliar repository is understand its history.  The <command
+	role="hg-cmd">hg log</command> command gives us a view of
+      the history of changes in the repository.</para>
+
+    &interaction.tour.log;
+
+    <para id="x_1c">By default, this command prints a brief paragraph of output
+      for each change to the project that was recorded.  In Mercurial
+      terminology, we call each of these recorded events a
+      <emphasis>changeset</emphasis>, because it can contain a record
+      of changes to several files.</para>
+
+    <para id="x_1d">The fields in a record of output from <command
+	role="hg-cmd">hg log</command> are as follows.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_1e"><literal>changeset</literal>: This
+	  field has the format of a number, followed by a colon,
+	  followed by a hexadecimal (or <emphasis>hex</emphasis>)
+	  string.  These are <emphasis>identifiers</emphasis> for the
+	  changeset.  The hex string is a unique identifier: the same
+	  hex string will always refer to the same changeset. The
+	  number is shorter and easier to type than the hex string,
+	  but it isn't unique: the same number in two different clones
+	  of a repository may identify different changesets.  Why
+	  provide the number at all, then?  For local
+	  convenience.</para>
+      </listitem>
+      <listitem><para id="x_1f"><literal>user</literal>: The identity of the
+	  person who created the changeset.  This is a free-form
+	  field, but it most often contains a person's name and email
+	  address.</para></listitem>
+      <listitem><para id="x_20"><literal>date</literal>: The date and time on
+	  which the changeset was created, and the timezone in which
+	  it was created.  (The date and time are local to that
+	  timezone; they display what time and date it was for the
+	  person who created the changeset.)</para></listitem>
+      <listitem><para id="x_21"><literal>summary</literal>: The first line of
+	  the text message that the creator of the changeset entered
+	  to describe the changeset.</para></listitem>
+      <listitem>
+	<para id="x_67d">Some changesets, such as the first in the list above,
+	  have a <literal>tag</literal> field.  A tag is another way
+	  to identify a changeset, by giving it an easy-to-remember
+	  name. (The tag named <literal>tip</literal> is special: it
+	  always refers to the newest change in a repository.)</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_22">The default output printed by <command
+	role="hg-cmd">hg log</command> is purely a summary; it is
+      missing a lot of detail.</para>
+
+    <para id="x_23"><xref linkend="fig:tour-basic:history"/> provides
+      a graphical representation of the history of the <filename
+	class="directory">hello</filename> repository, to make it a
+      little easier to see which direction history is
+      <quote>flowing</quote> in.  We'll be returning to this figure
+      several times in this chapter and the chapter that
+      follows.</para>
+
+    <figure id="fig:tour-basic:history">
+      <title>Graphical history of the <filename
+	  class="directory">hello</filename> repository</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <sect2>
+      <title>Changesets, revisions, and talking to other
+	people</title>
+
+      <para id="x_25">As English is a notoriously sloppy language, and computer
+	science has a hallowed history of terminological confusion
+	(why use one term when four will do?), revision control has a
+	variety of words and phrases that mean the same thing.  If you
+	are talking about Mercurial history with other people, you
+	will find that the word <quote>changeset</quote> is often
+	compressed to <quote>change</quote> or (when written)
+	<quote>cset</quote>, and sometimes a changeset is referred to
+	as a <quote>revision</quote> or a <quote>rev</quote>.</para>
+
+      <para id="x_26">While it doesn't matter what <emphasis>word</emphasis> you
+	use to refer to the concept of <quote>a changeset</quote>, the
+	<emphasis>identifier</emphasis> that you use to refer to
+	<quote>a <emphasis>specific</emphasis> changeset</quote> is of
+	great importance. Recall that the <literal>changeset</literal>
+	field in the output from <command role="hg-cmd">hg
+	  log</command> identifies a changeset using both a number and
+	a hexadecimal string.</para>
+      <itemizedlist>
+	<listitem><para id="x_27">The revision number is a handy
+	    notation that is <emphasis>only valid in that
+	      repository</emphasis>.</para></listitem>
+	<listitem><para id="x_28">The hexadecimal string is the
+	    <emphasis>permanent, unchanging identifier</emphasis> that
+	    will always identify that exact changeset in
+	    <emphasis>every</emphasis> copy of the
+	    repository.</para></listitem></itemizedlist>
+
+      <para id="x_29">This distinction is important.  If you send
+	someone an email talking about <quote>revision 33</quote>,
+	there's a high likelihood that their revision 33 will
+	<emphasis>not be the same</emphasis> as yours.  The reason for
+	this is that a revision number depends on the order in which
+	changes arrived in a repository, and there is no guarantee
+	that the same changes will happen in the same order in
+	different repositories. Three changes <literal>a,b,c</literal>
+	can easily appear in one repository as
+	<literal>0,1,2</literal>, while in another as
+	<literal>0,2,1</literal>.</para>
+
+      <para id="x_2a">Mercurial uses revision numbers purely as a convenient
+	shorthand.  If you need to discuss a changeset with someone,
+	or make a record of a changeset for some other reason (for
+	example, in a bug report), use the hexadecimal
+	identifier.</para>
+
+    </sect2>
+    <sect2>
+      <title>Viewing specific revisions</title>
+
+      <para id="x_2b">To narrow the output of <command role="hg-cmd">hg
+	  log</command> down to a single revision, use the <option
+	  role="hg-opt-log">-r</option> (or <option
+	  role="hg-opt-log">--rev</option>) option.  You can use
+	either a revision number or a hexadecimal identifier,
+	and you can provide as many revisions as you want.</para>
+
+      &interaction.tour.log-r;
+
+      <para id="x_2c">If you want to see the history of several revisions
+	without having to list each one, you can use <emphasis>range
+	  notation</emphasis>; this lets you express the idea <quote>I
+	  want all revisions between <literal>abc</literal> and
+	  <literal>def</literal>, inclusive</quote>.</para>
+      
+	&interaction.tour.log.range;
+
+      <para id="x_2d">Mercurial also honours the order in which you specify
+	revisions, so <command role="hg-cmd">hg log -r 2:4</command>
+	prints 2, 3, and 4. while <command role="hg-cmd">hg log -r
+	  4:2</command> prints 4, 3, and 2.</para>
+
+    </sect2>
+    <sect2>
+      <title>More detailed information</title>
+
+      <para id="x_2e">While the summary information printed by <command
+	  role="hg-cmd">hg log</command> is useful if you already know
+	what you're looking for, you may need to see a complete
+	description of the change, or a list of the files changed, if
+	you're trying to decide whether a changeset is the one you're
+	looking for. The <command role="hg-cmd">hg log</command>
+	command's <option role="hg-opt-global">-v</option> (or <option
+	  role="hg-opt-global">--verbose</option>) option gives you
+	this extra detail.</para>
+
+      &interaction.tour.log-v;
+
+      <para id="x_2f">If you want to see both the description and
+	content of a change, add the <option
+	  role="hg-opt-log">-p</option> (or <option
+	  role="hg-opt-log">--patch</option>) option.  This displays
+	the content of a change as a <emphasis>unified diff</emphasis>
+	(if you've never seen a unified diff before, see <xref
+	  linkend="sec:mq:patch"/> for an overview).</para>
+
+      &interaction.tour.log-vp;
+
+      <para id="x_67e">The <option role="hg-opt-log">-p</option> option is
+	tremendously useful, so it's well worth remembering.</para>
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>All about command options</title>
+
+    <para id="x_30">Let's take a brief break from exploring Mercurial commands
+      to discuss a pattern in the way that they work; you may find
+      this useful to keep in mind as we continue our tour.</para>
+
+    <para id="x_31">Mercurial has a consistent and straightforward approach to
+      dealing with the options that you can pass to commands.  It
+      follows the conventions for options that are common to modern
+      Linux and Unix systems.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para id="x_32">Every option has a long name.  For example, as
+	  we've already seen, the <command role="hg-cmd">hg
+	    log</command> command accepts a <option
+	    role="hg-opt-log">--rev</option> option.</para>
+      </listitem>
+      <listitem>
+	<para id="x_33">Most options have short names, too.  Instead
+	  of <option role="hg-opt-log">--rev</option>, we can use
+	  <option role="hg-opt-log">-r</option>.  (The reason that
+	  some options don't have short names is that the options in
+	  question are rarely used.)</para>
+      </listitem>
+      <listitem>
+	<para id="x_34">Long options start with two dashes (e.g.
+	  <option role="hg-opt-log">--rev</option>), while short
+	  options start with one (e.g. <option
+	    role="hg-opt-log">-r</option>).</para>
+      </listitem>
+      <listitem>
+	<para id="x_35">Option naming and usage is consistent across
+	  commands.  For example, every command that lets you specify
+	  a changeset ID or revision number accepts both <option
+	    role="hg-opt-log">-r</option> and <option
+	    role="hg-opt-log">--rev</option> arguments.</para>
+      </listitem>
+      <listitem>
+	<para id="x_67f">If you are using short options, you can save typing by
+	  running them together. For example, the command <command
+	    role="hg-cmd">hg log -v -p -r 2</command> can be written
+	  as <command role="hg-cmd">hg log -vpr2</command>.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_36">In the examples throughout this book, I use short options
+      instead of long.  This just reflects my own preference, so don't
+      read anything significant into it.</para>
+
+    <para id="x_37">Most commands that print output of some kind will print more
+      output when passed a <option role="hg-opt-global">-v</option>
+      (or <option role="hg-opt-global">--verbose</option>) option, and
+      less when passed <option role="hg-opt-global">-q</option> (or
+      <option role="hg-opt-global">--quiet</option>).</para>
+
+    <note>
+      <title>Option naming consistency</title>
+
+      <para id="x_680">Almost always, Mercurial commands use consistent option
+	names to refer to the same concepts.  For instance, if a
+	command deals with changesets, you'll always identify them
+	with <option role="hg-opt-log">--rev</option> or <option
+	  role="hg-opt-log">-r</option>.  This consistent use of
+	option names makes it easier to remember what options a
+	particular command takes.</para>
+    </note>
+
+  </sect1>
+  <sect1>
+    <title>Making and reviewing changes</title>
+
+    <para id="x_38">Now that we have a grasp of viewing history in Mercurial,
+      let's take a look at making some changes and examining
+      them.</para>
+
+    <para id="x_39">The first thing we'll do is isolate our experiment in a
+      repository of its own.  We use the <command role="hg-cmd">hg
+	clone</command> command, but we don't need to clone a copy of
+      the remote repository.  Since we already have a copy of it
+      locally, we can just clone that instead.  This is much faster
+      than cloning over the network, and cloning a local repository
+      uses less disk space in most cases, too<footnote>
+	<para id="x_681">The saving of space arises when source and destination
+	  repositories are on the same filesystem, in which case
+	  Mercurial will use hardlinks to do copy-on-write sharing of
+	  its internal metadata.  If that explanation meant nothing to
+	  you, don't worry: everything happens transparently and
+	  automatically, and you don't need to understand it.</para>
+	</footnote>.</para>
+
+    &interaction.tour.reclone;
+
+    <para id="x_3a">As an aside, it's often good practice to keep a
+      <quote>pristine</quote> copy of a remote repository around,
+      which you can then make temporary clones of to create sandboxes
+      for each task you want to work on.  This lets you work on
+      multiple tasks in parallel, each isolated from the others until
+      it's complete and you're ready to integrate it back.  Because
+      local clones are so cheap, there's almost no overhead to cloning
+      and destroying repositories whenever you want.</para>
+
+    <para id="x_3b">In our <filename class="directory">my-hello</filename>
+      repository, we have a file <filename>hello.c</filename> that
+      contains the classic <quote>hello, world</quote> program.</para>
+
+    &interaction.tour.cat1;
+
+    <para id="x_682">Let's edit this file so that it prints a second line of
+      output.</para>
+
+    &interaction.tour.cat2;
+
+    <para id="x_3c">Mercurial's <command role="hg-cmd">hg status</command>
+      command will tell us what Mercurial knows about the files in the
+      repository.</para>
+
+    &interaction.tour.status;
+
+    <para id="x_3d">The <command role="hg-cmd">hg status</command> command
+      prints no output for some files, but a line starting with
+      <quote><literal>M</literal></quote> for
+      <filename>hello.c</filename>.  Unless you tell it to, <command
+	role="hg-cmd">hg status</command> will not print any output
+      for files that have not been modified.</para>
+
+    <para id="x_3e">The <quote><literal>M</literal></quote> indicates that
+      Mercurial has noticed that we modified
+      <filename>hello.c</filename>.  We didn't need to
+      <emphasis>inform</emphasis> Mercurial that we were going to
+      modify the file before we started, or that we had modified the
+      file after we were done; it was able to figure this out
+      itself.</para>
+
+    <para id="x_3f">It's somewhat helpful to know that we've modified
+      <filename>hello.c</filename>, but we might prefer to know
+      exactly <emphasis>what</emphasis> changes we've made to it.  To
+      do this, we use the <command role="hg-cmd">hg diff</command>
+      command.</para>
+
+    &interaction.tour.diff;
+
+    <tip>
+      <title>Understanding patches</title>
+
+      <para id="x_683">Remember to take a look at <xref
+	  linkend="sec:mq:patch"/> if you don't know how to read
+	output above.</para>
+    </tip>
+  </sect1>
+  <sect1>
+    <title>Recording changes in a new changeset</title>
+
+    <para id="x_40">We can modify files, build and test our changes, and use
+      <command role="hg-cmd">hg status</command> and <command
+	role="hg-cmd">hg diff</command> to review our changes, until
+      we're satisfied with what we've done and arrive at a natural
+      stopping point where we want to record our work in a new
+      changeset.</para>
+
+    <para id="x_41">The <command role="hg-cmd">hg commit</command> command lets
+      us create a new changeset; we'll usually refer to this as
+      <quote>making a commit</quote> or
+      <quote>committing</quote>.</para>
+
+    <sect2>
+      <title>Setting up a username</title>
+
+      <para id="x_42">When you try to run <command role="hg-cmd">hg
+	  commit</command> for the first time, it is not guaranteed to
+	succeed.  Mercurial records your name and address with each
+	change that you commit, so that you and others will later be
+	able to tell who made each change.  Mercurial tries to
+	automatically figure out a sensible username to commit the
+	change with.  It will attempt each of the following methods,
+	in order:</para>
+      <orderedlist>
+	<listitem><para id="x_43">If you specify a <option
+	      role="hg-opt-commit">-u</option> option to the <command
+	      role="hg-cmd">hg commit</command> command on the command
+	    line, followed by a username, this is always given the
+	    highest precedence.</para></listitem>
+	<listitem><para id="x_44">If you have set the <envar>HGUSER</envar>
+	    environment variable, this is checked
+	    next.</para></listitem>
+	<listitem><para id="x_45">If you create a file in your home
+	    directory called <filename
+	      role="special">.hgrc</filename>, with a <envar
+	      role="rc-item-ui">username</envar> entry, that will be
+	    used next.  To see what the contents of this file should
+	    look like, refer to <xref
+	      linkend="sec:tour-basic:username"/>
+	    below.</para></listitem>
+	<listitem><para id="x_46">If you have set the <envar>EMAIL</envar>
+	    environment variable, this will be used
+	    next.</para></listitem>
+	<listitem><para id="x_47">Mercurial will query your system to find out
+	    your local user name and host name, and construct a
+	    username from these components. Since this often results
+	    in a username that is not very useful, it will print a
+	    warning if it has to do
+	    this.</para></listitem>
+      </orderedlist>
+      <para id="x_48">If all of these mechanisms fail, Mercurial will
+	  fail, printing an error message.  In this case, it will not
+	  let you commit until you set up a
+	  username.</para>
+      <para id="x_49">You should think of the <envar>HGUSER</envar> environment
+	variable and the <option role="hg-opt-commit">-u</option>
+	option to the <command role="hg-cmd">hg commit</command>
+	command as ways to <emphasis>override</emphasis> Mercurial's
+	default selection of username.  For normal use, the simplest
+	and most robust way to set a username for yourself is by
+	creating a <filename role="special">.hgrc</filename> file; see
+	below for details.</para>
+      <sect3 id="sec:tour-basic:username">
+	<title>Creating a Mercurial configuration file</title>
+
+	<para id="x_4a">To set a user name, use your favorite editor
+	    to create a file called <filename
+	      role="special">.hgrc</filename> in your home directory.
+	    Mercurial will use this file to look up your personalised
+	    configuration settings.  The initial contents of your
+	    <filename role="special">.hgrc</filename> should look like
+	    this.</para>
+
+	<remark>Figure out what the appropriate directory is on
+	  Windows.</remark>
+
+	<programlisting># This is a Mercurial configuration file.
+[ui]
+username = Firstname Lastname &lt;email.address@domain.net&gt;</programlisting>
+
+	<para id="x_4b">The <quote><literal>[ui]</literal></quote> line begins a
+	  <emphasis>section</emphasis> of the config file, so you can
+	  read the <quote><literal>username = ...</literal></quote>
+	  line as meaning <quote>set the value of the
+	    <literal>username</literal> item in the
+	    <literal>ui</literal> section</quote>. A section continues
+	  until a new section begins, or the end of the file.
+	  Mercurial ignores empty lines and treats any text from
+	  <quote><literal>#</literal></quote> to the end of a line as
+	  a comment.</para>
+      </sect3>
+
+      <sect3>
+	<title>Choosing a user name</title>
+
+	<para id="x_4c">You can use any text you like as the value of
+	    the <literal>username</literal> config item, since this
+	    information is for reading by other people, but will not be
+	    interpreted by Mercurial.  The convention that most
+	    people follow is to use their name and email address, as
+	    in the example above.</para>
+	<note>
+	  <para id="x_4d">Mercurial's built-in web server obfuscates
+	      email addresses, to make it more difficult for the email
+	      harvesting tools that spammers use. This reduces the
+	      likelihood that you'll start receiving more junk email
+	      if you publish a Mercurial repository on the
+	      web.</para></note>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Writing a commit message</title>
+
+      <para id="x_4e">When we commit a change, Mercurial drops us into
+	  a text editor, to enter a message that will describe the
+	  modifications we've made in this changeset.  This is called
+	  the <emphasis>commit message</emphasis>.  It will be a
+	  record for readers of what we did and why, and it will be
+	  printed by <command role="hg-cmd">hg log</command> after
+	  we've finished committing.</para>
+
+       &interaction.tour.commit;
+
+      <para id="x_4f">The editor that the <command role="hg-cmd">hg
+	    commit</command> command drops us into will contain an
+	  empty line or two, followed by a number of lines starting with
+	  <quote><literal>HG:</literal></quote>.</para>
+
+    <programlisting>
+This is where I type my commit comment.
+
+HG: Enter commit message.  Lines beginning with 'HG:' are removed.
+HG: --
+HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
+HG: branch 'default'
+HG: changed hello.c</programlisting>
+
+      <para id="x_50">Mercurial ignores the lines that start with
+	  <quote><literal>HG:</literal></quote>; it uses them only to
+	  tell us which files it's recording changes to.  Modifying or
+	  deleting these lines has no effect.</para>
+    </sect2>
+    <sect2>
+      <title>Writing a good commit message</title>
+
+      <para id="x_51">Since <command role="hg-cmd">hg log</command>
+	  only prints the first line of a commit message by default,
+	  it's best to write a commit message whose first line stands
+	  alone.  Here's a real example of a commit message that
+	  <emphasis>doesn't</emphasis> follow this guideline, and
+	  hence has a summary that is not
+	  readable.</para>
+
+      <programlisting>
+changeset:   73:584af0e231be
+user:        Censored Person &lt;censored.person@example.org&gt;
+date:        Tue Sep 26 21:37:07 2006 -0700
+summary:     include buildmeister/commondefs. Add exports.</programlisting>
+
+      <para id="x_52">As far as the remainder of the contents of the
+	  commit message are concerned, there are no hard-and-fast
+	  rules.  Mercurial itself doesn't interpret or care about the
+	  contents of the commit message, though your project may have
+	  policies that dictate a certain kind of
+	  formatting.</para>
+      <para id="x_53">My personal preference is for short, but
+	  informative, commit messages that tell me something that I
+	  can't figure out with a quick glance at the output of
+	  <command role="hg-cmd">hg log
+	    --patch</command>.</para>
+    </sect2>
+    <sect2>
+      <title>Aborting a commit</title>
+
+      <para id="x_54">If you decide that you don't want to commit
+	  while in the middle of editing a commit message, simply exit
+	  from your editor without saving the file that it's editing.
+	  This will cause nothing to happen to either the repository
+	  or the working directory.</para>
+      <para id="x_55">If we run the <command role="hg-cmd">hg
+	    commit</command> command without any arguments, it records
+	  all of the changes we've made, as reported by <command
+	    role="hg-cmd">hg status</command> and <command
+	    role="hg-cmd">hg diff</command>.</para>
+    </sect2>
+    <sect2>
+      <title>Admiring our new handiwork</title>
+
+      <para id="x_56">Once we've finished the commit, we can use the
+	  <command role="hg-cmd">hg tip</command> command to display
+	  the changeset we just created.  This command produces output
+	  that is identical to <command role="hg-cmd">hg
+	    log</command>, but it only displays the newest revision in
+	  the repository.</para>
+
+      &interaction.tour.tip;
+
+      <para id="x_57">We refer to the newest revision in the
+	repository as the <emphasis>tip revision</emphasis>, or simply
+	the <emphasis>tip</emphasis>.</para>
+
+      <para id="x_684">By the way, the <command role="hg-cmd">hg tip</command>
+	command accepts many of the same options as <command
+	  role="hg-cmd">hg log</command>, so <option
+	  role="hg-opt-global">-v</option> above indicates <quote>be
+	  verbose</quote>, <option role="hg-opt-tip">-p</option>
+	specifies <quote>print a patch</quote>.  The use of <option
+	  role="hg-opt-tip">-p</option> to print patches is another
+	example of the consistent naming we mentioned earlier.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Sharing changes</title>
+
+    <para id="x_58">We mentioned earlier that repositories in
+	Mercurial are self-contained.  This means that the changeset
+	we just created exists only in our <filename
+	  class="directory">my-hello</filename> repository.  Let's
+	look at a few ways that we can propagate this change into
+	other repositories.</para>
+
+    <sect2 id="sec:tour:pull">
+      <title>Pulling changes from another repository</title>
+      <para id="x_59">To get started, let's clone our original
+	  <filename class="directory">hello</filename> repository,
+	  which does not contain the change we just committed.  We'll
+	  call our temporary repository <filename
+	    class="directory">hello-pull</filename>.</para>
+
+      &interaction.tour.clone-pull;
+
+      <para id="x_5a">We'll use the <command role="hg-cmd">hg
+	    pull</command> command to bring changes from <filename
+	    class="directory">my-hello</filename> into <filename
+	    class="directory">hello-pull</filename>.  However, blindly
+	  pulling unknown changes into a repository is a somewhat
+	  scary prospect.  Mercurial provides the <command
+	    role="hg-cmd">hg incoming</command> command to tell us
+	  what changes the <command role="hg-cmd">hg pull</command>
+	  command <emphasis>would</emphasis> pull into the repository,
+	  without actually pulling the changes in.</para>
+
+      &interaction.tour.incoming;
+
+      <para id="x_5b">Suppose you're pulling changes from a repository
+      on the network somewhere. While you are looking at the <command
+	  role="hg-cmd">hg incoming</command> output, and before you
+	pull those changes, someone might have committed something in
+	the remote repository. This means that it's possible to pull
+	more changes than you saw when using <command
+	  role="hg-cmd">hg incoming</command>.</para>
+
+      <para id="x_5c">Bringing changes into a repository is a simple
+	  matter of running the <command role="hg-cmd">hg
+	    pull</command> command, and telling it which repository to
+	  pull from.</para>
+
+      &interaction.tour.pull;
+
+      <para id="x_5d">As you can see
+	  from the before-and-after output of <command
+	    role="hg-cmd">hg tip</command>, we have successfully
+	  pulled changes into our repository.  There remains one step
+	  before we can see these changes in the working
+	  directory.</para>
+    </sect2>
+    <sect2>
+      <title>Updating the working directory</title>
+
+      <para id="x_5e">We have so far glossed over the relationship
+	between a repository and its working directory.  The <command
+	  role="hg-cmd">hg pull</command> command that we ran in
+	<xref linkend="sec:tour:pull"/> brought changes into the
+	repository, but if we check, there's no sign of those changes
+	in the working directory.  This is because <command
+	  role="hg-cmd">hg pull</command> does not (by default) touch
+	the working directory.  Instead, we use the <command
+	  role="hg-cmd">hg update</command> command to do this.</para>
+
+      &interaction.tour.update;
+
+      <para id="x_5f">It might seem a bit strange that <command role="hg-cmd">hg
+	  pull</command> doesn't update the working directory
+	automatically.  There's actually a good reason for this: you
+	can use <command role="hg-cmd">hg update</command> to update
+	the working directory to the state it was in at <emphasis>any
+	  revision</emphasis> in the history of the repository.  If
+	you had the working directory updated to an old revision&emdash;to
+	hunt down the origin of a bug, say&emdash;and ran a <command
+	  role="hg-cmd">hg pull</command> which automatically updated
+	the working directory to a new revision, you might not be
+	terribly happy.</para>
+      <para id="x_60">However, since pull-then-update is such a common thing to
+	do, Mercurial lets you combine the two by passing the <option
+	  role="hg-opt-pull">-u</option> option to <command
+	  role="hg-cmd">hg pull</command>.</para>
+
+      <para id="x_61">If you look back at the output of <command
+	  role="hg-cmd">hg pull</command> in <xref
+	    linkend="sec:tour:pull"/> when we ran it without <option
+	  role="hg-opt-pull">-u</option>, you can see that it printed
+	a helpful reminder that we'd have to take an explicit step to
+	update the working directory:</para>
+
+      <!-- &interaction.xxx.fixme; -->
+
+      <para id="x_62">To find out what revision the working directory is at, use
+	the <command role="hg-cmd">hg parents</command>
+	command.</para>
+
+      &interaction.tour.parents;
+
+      <para id="x_63">If you look back at <xref
+	  linkend="fig:tour-basic:history"/>,
+	you'll see arrows connecting each changeset.  The node that
+	the arrow leads <emphasis>from</emphasis> in each case is a
+	parent, and the node that the arrow leads
+	<emphasis>to</emphasis> is its child.  The working directory
+	has a parent in just the same way; this is the changeset that
+	the working directory currently contains.</para>
+
+      <para id="x_64">To update the working directory to a particular revision,
+
+	give a revision number or changeset ID to the <command
+	  role="hg-cmd">hg update</command> command.</para>
+
+      &interaction.tour.older;
+
+      <para id="x_65">If you omit an explicit revision, <command
+	  role="hg-cmd">hg update</command> will update to the tip
+	revision, as shown by the second call to <command
+	  role="hg-cmd">hg update</command> in the example
+	above.</para>
+    </sect2>
+
+    <sect2>
+      <title>Pushing changes to another repository</title>
+
+      <para id="x_66">Mercurial lets us push changes to another
+	  repository, from the repository we're currently visiting.
+	  As with the example of <command role="hg-cmd">hg
+	    pull</command> above, we'll create a temporary repository
+	  to push our changes into.</para>
+
+      &interaction.tour.clone-push;
+
+      <para id="x_67">The <command role="hg-cmd">hg outgoing</command> command
+	  tells us what changes would be pushed into another
+	  repository.</para>
+
+      &interaction.tour.outgoing;
+
+      <para id="x_68">And the
+	  <command role="hg-cmd">hg push</command> command does the
+	  actual push.</para>
+
+      &interaction.tour.push;
+
+      <para id="x_69">As with <command role="hg-cmd">hg
+	  pull</command>, the <command role="hg-cmd">hg push</command>
+	command does not update the working directory in the
+	repository that it's pushing changes into. Unlike <command
+	  role="hg-cmd">hg pull</command>, <command role="hg-cmd">hg
+	  push</command> does not provide a <literal>-u</literal>
+	option that updates the other repository's working directory.
+	This asymmetry is deliberate: the repository we're pushing to
+	might be on a remote server and shared between several people.
+	If we were to update its working directory while someone was
+	working in it, their work would be disrupted.</para>
+
+      <para id="x_6a">What happens if we try to pull or push changes
+	  and the receiving repository already has those changes?
+	  Nothing too exciting.</para>
+
+      &interaction.tour.push.nothing;
+    </sect2>
+    <sect2>
+      <title>Sharing changes over a network</title>
+
+      <para id="x_6b">The commands we have covered in the previous few
+	  sections are not limited to working with local repositories.
+	  Each works in exactly the same fashion over a network
+	  connection; simply pass in a URL instead of a local
+	  path.</para>
+	
+      &interaction.tour.outgoing.net;
+
+      <para id="x_6c">In this example, we
+	  can see what changes we could push to the remote repository,
+	  but the repository is understandably not set up to let
+	  anonymous users push to it.</para>
+
+      &interaction.tour.push.net;
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch02-tour-merge.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,401 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:tour-merge">
+  <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?>
+  <title>A tour of Mercurial: merging work</title>
+
+  <para id="x_338">We've now covered cloning a repository, making changes in a
+    repository, and pulling or pushing changes from one repository
+    into another.  Our next step is <emphasis>merging</emphasis>
+    changes from separate repositories.</para>
+
+  <sect1>
+    <title>Merging streams of work</title>
+
+    <para id="x_339">Merging is a fundamental part of working with a distributed
+      revision control tool.</para>
+    <itemizedlist>
+      <listitem><para id="x_33a">Alice and Bob each have a personal copy of a
+	  repository for a project they're collaborating on.  Alice
+	  fixes a bug in her repository; Bob adds a new feature in
+	  his.  They want the shared repository to contain both the
+	  bug fix and the new feature.</para>
+      </listitem>
+      <listitem><para id="x_33b">I frequently work on several different tasks for
+	  a single project at once, each safely isolated in its own
+	  repository. Working this way means that I often need to
+	  merge one piece of my own work with another.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_33c">Because merging is such a common thing to need to do,
+      Mercurial makes it easy.  Let's walk through the process.  We'll
+      begin by cloning yet another repository (see how often they
+      spring up?) and making a change in it.</para>
+
+    &interaction.tour.merge.clone;
+
+    <para id="x_33d">We should now have two copies of
+      <filename>hello.c</filename> with different contents.  The
+      histories of the two repositories have also diverged, as
+      illustrated in <xref
+	linkend="fig:tour-merge:sep-repos"/>.</para>
+
+    &interaction.tour.merge.cat;
+
+    <figure id="fig:tour-merge:sep-repos">
+      <title>Divergent recent histories of the <filename
+	  class="directory">my-hello</filename> and <filename
+	  class="directory">my-new-hello</filename>
+	repositories</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-merge-sep-repos.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <para id="x_33f">We already know that pulling changes from our <filename
+	class="directory">my-hello</filename> repository will have no
+      effect on the working directory.</para>
+
+    &interaction.tour.merge.pull;
+
+    <para id="x_340">However, the <command role="hg-cmd">hg pull</command>
+      command says something about <quote>heads</quote>.</para>
+
+    <sect2>
+      <title>Head changesets</title>
+
+      <para id="x_341">A head is a change that has no descendants, or children,
+	as they're also known.  The tip revision is thus a head,
+	because the newest revision in a repository doesn't have any
+	children, but a repository can contain more than one
+	head.</para>
+
+      <figure id="fig:tour-merge:pull">
+	<title>Repository contents after pulling from <filename
+	    class="directory">my-hello</filename> into <filename
+	    class="directory">my-new-hello</filename></title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/tour-merge-pull.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_343">In <xref linkend="fig:tour-merge:pull"/>, you can
+	see the effect of the pull from <filename
+	  class="directory">my-hello</filename> into <filename
+	  class="directory">my-new-hello</filename>.  The history that
+	was already present in <filename
+	  class="directory">my-new-hello</filename> is untouched, but
+	a new revision has been added.  By referring to <xref
+	  linkend="fig:tour-merge:sep-repos"/>, we can see that the
+	<emphasis>changeset ID</emphasis> remains the same in the new
+	repository, but the <emphasis>revision number</emphasis> has
+	changed.  (This, incidentally, is a fine example of why it's
+	not safe to use revision numbers when discussing changesets.)
+	We can view the heads in a repository using the <command
+	  role="hg-cmd">hg heads</command> command.</para>
+
+      &interaction.tour.merge.heads;
+
+    </sect2>
+    <sect2>
+      <title>Performing the merge</title>
+
+      <para id="x_344">What happens if we try to use the normal <command
+	  role="hg-cmd">hg update</command> command to update to the
+	new tip?</para>
+
+      &interaction.tour.merge.update;
+
+      <para id="x_345">Mercurial is telling us that the <command role="hg-cmd">hg
+	  update</command> command won't do a merge; it won't update
+	the working directory when it thinks we might want to do
+	a merge, unless we force it to do so.  Instead, we use the
+	<command role="hg-cmd">hg merge</command> command to merge the
+	two heads.</para>
+
+      &interaction.tour.merge.merge;
+
+      <para id="x_347">This updates the working directory so that it contains
+	changes from <emphasis>both</emphasis> heads, which is
+	reflected in both the output of <command role="hg-cmd">hg
+	  parents</command> and the contents of
+	<filename>hello.c</filename>.</para>
+
+      &interaction.tour.merge.parents;
+
+    </sect2>
+    <sect2>
+      <title>Committing the results of the merge</title>
+
+      <para id="x_348">Whenever we've done a merge, <command role="hg-cmd">hg
+	  parents</command> will display two parents until we <command
+	  role="hg-cmd">hg commit</command> the results of the
+	  merge.</para>
+
+	&interaction.tour.merge.commit;
+
+      <para id="x_349">We now have a new tip revision; notice that it has
+	<emphasis>both</emphasis> of our former heads as its parents.
+	These are the same revisions that were previously displayed by
+	<command role="hg-cmd">hg parents</command>.</para>
+
+      &interaction.tour.merge.tip;
+
+      <para id="x_34a">In <xref
+	  linkend="fig:tour-merge:merge"/>, you can see a
+	representation of what happens to the working directory during
+	the merge, and how this affects the repository when the commit
+	happens.  During the merge, the working directory has two
+	parent changesets, and these become the parents of the new
+	changeset.</para>
+
+      <figure id="fig:tour-merge:merge">
+	<title>Working directory and repository during merge, and
+	  following commit</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/tour-merge-merge.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_69c">We sometimes talk about a merge having
+	<emphasis>sides</emphasis>: the left side is the first parent
+	in the output of <command role="hg-cmd">hg parents</command>,
+	and the right side is the second.  If the working directory
+	was at e.g. revision 5 before we began a merge, that revision
+	will become the left side of the merge.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Merging conflicting changes</title>
+
+    <para id="x_34b">Most merges are simple affairs, but sometimes you'll find
+      yourself merging changes where each side modifies the same portions
+      of the same files.  Unless both modifications are identical,
+      this results in a <emphasis>conflict</emphasis>, where you have
+      to decide how to reconcile the different changes into something
+      coherent.</para>
+
+    <figure id="fig:tour-merge:conflict">
+      <title>Conflicting changes to a document</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/tour-merge-conflict.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+    <para id="x_34d"><xref linkend="fig:tour-merge:conflict"/> illustrates
+      an instance of two conflicting changes to a document.  We
+      started with a single version of the file; then we made some
+      changes; while someone else made different changes to the same
+      text.  Our task in resolving the conflicting changes is to
+      decide what the file should look like.</para>
+
+    <para id="x_34e">Mercurial doesn't have a built-in facility for handling
+      conflicts. Instead, it runs an external program, usually one
+      that displays some kind of graphical conflict resolution
+      interface.  By default, Mercurial tries to find one of several
+      different merging tools that are likely to be installed on your
+      system.  It first tries a few fully automatic merging tools; if
+      these don't succeed (because the resolution process requires
+      human guidance) or aren't present, it tries a few
+      different graphical merging tools.</para>
+
+    <para id="x_34f">It's also possible to get Mercurial to run another program
+      or script instead of <command>hgmerge</command>, by setting the
+      <envar>HGMERGE</envar> environment variable to the name of your
+      preferred program.</para>
+
+    <sect2>
+      <title>Using a graphical merge tool</title>
+
+      <para id="x_350">My preferred graphical merge tool is
+	<command>kdiff3</command>, which I'll use to describe the
+	features that are common to graphical file merging tools.  You
+	can see a screenshot of <command>kdiff3</command> in action in
+	<xref linkend="fig:tour-merge:kdiff3"/>.  The kind of
+	merge it is performing is called a <emphasis>three-way
+	  merge</emphasis>, because there are three different versions
+	of the file of interest to us.  The tool thus splits the upper
+	portion of the window into three panes:</para>
+      <itemizedlist>
+	<listitem><para id="x_351">At the left is the <emphasis>base</emphasis>
+	    version of the file, i.e. the most recent version from
+	    which the two versions we're trying to merge are
+	    descended.</para>
+	</listitem>
+	<listitem><para id="x_352">In the middle is <quote>our</quote> version of
+	    the file, with the contents that we modified.</para>
+	</listitem>
+	<listitem><para id="x_353">On the right is <quote>their</quote> version
+	    of the file, the one that from the changeset that we're
+	    trying to merge with.</para>
+	</listitem></itemizedlist>
+      <para id="x_354">In the pane below these is the current
+	<emphasis>result</emphasis> of the merge. Our task is to
+	replace all of the red text, which indicates unresolved
+	conflicts, with some sensible merger of the
+	<quote>ours</quote> and <quote>theirs</quote> versions of the
+	file.</para>
+
+      <para id="x_355">All four of these panes are <emphasis>locked
+	  together</emphasis>; if we scroll vertically or horizontally
+	in any of them, the others are updated to display the
+	corresponding sections of their respective files.</para>
+
+      <figure id="fig:tour-merge:kdiff3">
+	<title>Using <command>kdiff3</command> to merge versions of a
+	  file</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
+	  <textobject>
+	    <phrase>XXX add text</phrase>
+	  </textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_357">For each conflicting portion of the file, we can choose to
+	resolve the conflict using some combination of text from the
+	base version, ours, or theirs.  We can also manually edit the
+	merged file at any time, in case we need to make further
+	modifications.</para>
+
+      <para id="x_358">There are <emphasis>many</emphasis> file merging tools
+	available, too many to cover here.  They vary in which
+	platforms they are available for, and in their particular
+	strengths and weaknesses.  Most are tuned for merging files
+	containing plain text, while a few are aimed at specialised
+	file formats (generally XML).</para>
+
+    </sect2>
+    <sect2>
+      <title>A worked example</title>
+
+      <para id="x_359">In this example, we will reproduce the file modification
+	history of <xref linkend="fig:tour-merge:conflict"/>
+	above.  Let's begin by creating a repository with a base
+	version of our document.</para>
+
+      &interaction.tour-merge-conflict.wife;
+
+      <para id="x_35a">We'll clone the repository and make a change to the
+	file.</para>
+
+      &interaction.tour-merge-conflict.cousin;
+
+      <para id="x_35b">And another clone, to simulate someone else making a
+	change to the file. (This hints at the idea that it's not all
+	that unusual to merge with yourself when you isolate tasks in
+	separate repositories, and indeed to find and resolve
+	conflicts while doing so.)</para>
+
+      &interaction.tour-merge-conflict.son;
+
+      <para id="x_35c">Having created two
+	different versions of the file, we'll set up an environment
+	suitable for running our merge.</para>
+
+      &interaction.tour-merge-conflict.pull;
+
+      <para id="x_35d">In this example, I'll set
+	<envar>HGMERGE</envar> to tell Mercurial to use the
+	non-interactive <command>merge</command> command.  This is
+	bundled with many Unix-like systems. (If you're following this
+	example on your computer, don't bother setting
+	<envar>HGMERGE</envar>.)</para>
+
+      &interaction.tour-merge-conflict.merge;
+
+      <para id="x_35f">Because <command>merge</command> can't resolve the
+	conflicting changes, it leaves <emphasis>merge
+	  markers</emphasis> inside the file that has conflicts,
+	indicating which lines have conflicts, and whether they came
+	from our version of the file or theirs.</para>
+
+      <para id="x_360">Mercurial can tell from the way <command>merge</command>
+	exits that it wasn't able to merge successfully, so it tells
+	us what commands we'll need to run if we want to redo the
+	merging operation.  This could be useful if, for example, we
+	were running a graphical merge tool and quit because we were
+	confused or realised we had made a mistake.</para>
+
+      <para id="x_361">If automatic or manual merges fail, there's nothing to
+	prevent us from <quote>fixing up</quote> the affected files
+	ourselves, and committing the results of our merge:</para>
+
+      &interaction.tour-merge-conflict.commit;
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:tour-merge:fetch">
+    <title>Simplifying the pull-merge-commit sequence</title>
+
+    <para id="x_362">The process of merging changes as outlined above is
+      straightforward, but requires running three commands in
+      sequence.</para>
+    <programlisting>hg pull -u
+hg merge
+hg commit -m 'Merged remote changes'</programlisting>
+    <para id="x_363">In the case of the final commit, you also need to enter a
+      commit message, which is almost always going to be a piece of
+      uninteresting <quote>boilerplate</quote> text.</para>
+
+    <para id="x_364">It would be nice to reduce the number of steps needed, if
+      this were possible.  Indeed, Mercurial is distributed with an
+      extension called <literal role="hg-ext">fetch</literal> that
+      does just this.</para>
+
+    <para id="x_365">Mercurial provides a flexible extension mechanism that lets
+      people extend its functionality, while keeping the core of
+      Mercurial small and easy to deal with.  Some extensions add new
+      commands that you can use from the command line, while others
+      work <quote>behind the scenes,</quote> for example adding
+      capabilities to the server.</para>
+
+    <para id="x_366">The <literal role="hg-ext">fetch</literal>
+      extension adds a new command called, not surprisingly, <command
+	role="hg-cmd">hg fetch</command>.  This extension acts as a
+      combination of <command role="hg-cmd">hg pull -u</command>,
+      <command role="hg-cmd">hg merge</command> and <command
+	role="hg-cmd">hg commit</command>.  It begins by pulling
+      changes from another repository into the current repository.  If
+      it finds that the changes added a new head to the repository, it
+      begins a merge, then (if the merge succeeded) commits the result
+      of the merge with an automatically-generated commit message.  If
+      no new heads were added, it updates the working directory to the
+      new tip changeset.</para>
+
+    <para id="x_367">Enabling the <literal
+	role="hg-ext">fetch</literal> extension is easy.  Edit the
+      <filename role="special">.hgrc</filename> file in your home
+      directory, and either go to the <literal
+	role="rc-extensions">extensions</literal> section or create an
+      <literal role="rc-extensions">extensions</literal> section. Then
+      add a line that simply reads
+      <quote><literal>fetch=</literal></quote>.</para>
+
+    <programlisting>[extensions]
+fetch =</programlisting>
+
+    <para id="x_368">(Normally, the right-hand side of the
+      <quote><literal>=</literal></quote> would indicate where to find
+      the extension, but since the <literal
+	role="hg-ext">fetch</literal> extension is in the standard
+      distribution, Mercurial knows where to search for it.)</para>
+
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch03-concepts.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,754 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:concepts">
+  <?dbhtml filename="behind-the-scenes.html"?>
+  <title>Behind the scenes</title>
+
+  <para id="x_2e8">Unlike many revision control systems, the concepts
+    upon which Mercurial is built are simple enough that it's easy to
+    understand how the software really works.  Knowing these details
+    certainly isn't necessary, so it is certainly safe to skip this
+    chapter.  However, I think you will get more out of the software
+    with a <quote>mental model</quote> of what's going on.</para>
+
+  <para id="x_2e9">Being able to understand what's going on behind the
+    scenes gives me confidence that Mercurial has been carefully
+    designed to be both <emphasis>safe</emphasis> and
+    <emphasis>efficient</emphasis>.  And just as importantly, if it's
+    easy for me to retain a good idea of what the software is doing
+    when I perform a revision control task, I'm less likely to be
+    surprised by its behavior.</para>
+
+  <para id="x_2ea">In this chapter, we'll initially cover the core concepts
+    behind Mercurial's design, then continue to discuss some of the
+    interesting details of its implementation.</para>
+
+  <sect1>
+    <title>Mercurial's historical record</title>
+
+    <sect2>
+      <title>Tracking the history of a single file</title>
+
+      <para id="x_2eb">When Mercurial tracks modifications to a file, it stores
+	the history of that file in a metadata object called a
+	<emphasis>filelog</emphasis>.  Each entry in the filelog
+	contains enough information to reconstruct one revision of the
+	file that is being tracked.  Filelogs are stored as files in
+	the <filename role="special"
+	  class="directory">.hg/store/data</filename> directory.  A
+	filelog contains two kinds of information: revision data, and
+	an index to help Mercurial to find a revision
+	efficiently.</para>
+
+      <para id="x_2ec">A file that is large, or has a lot of history, has its
+	filelog stored in separate data
+	(<quote><literal>.d</literal></quote> suffix) and index
+	(<quote><literal>.i</literal></quote> suffix) files.  For
+	small files without much history, the revision data and index
+	are combined in a single <quote><literal>.i</literal></quote>
+	file.  The correspondence between a file in the working
+	directory and the filelog that tracks its history in the
+	repository is illustrated in <xref
+	  linkend="fig:concepts:filelog"/>.</para>
+
+      <figure id="fig:concepts:filelog">
+	<title>Relationships between files in working directory and
+	  filelogs in repository</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/filelog.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Managing tracked files</title>
+
+      <para id="x_2ee">Mercurial uses a structure called a
+	<emphasis>manifest</emphasis> to collect together information
+	about the files that it tracks.  Each entry in the manifest
+	contains information about the files present in a single
+	changeset.  An entry records which files are present in the
+	changeset, the revision of each file, and a few other pieces
+	of file metadata.</para>
+
+    </sect2>
+    <sect2>
+      <title>Recording changeset information</title>
+
+      <para id="x_2ef">The <emphasis>changelog</emphasis> contains information
+	about each changeset.  Each revision records who committed a
+	change, the changeset comment, other pieces of
+	changeset-related information, and the revision of the
+	manifest to use.</para>
+
+    </sect2>
+    <sect2>
+      <title>Relationships between revisions</title>
+
+      <para id="x_2f0">Within a changelog, a manifest, or a filelog, each
+	revision stores a pointer to its immediate parent (or to its
+	two parents, if it's a merge revision).  As I mentioned above,
+	there are also relationships between revisions
+	<emphasis>across</emphasis> these structures, and they are
+	hierarchical in nature.</para>
+
+      <para id="x_2f1">For every changeset in a repository, there is exactly one
+	revision stored in the changelog.  Each revision of the
+	changelog contains a pointer to a single revision of the
+	manifest.  A revision of the manifest stores a pointer to a
+	single revision of each filelog tracked when that changeset
+	was created.  These relationships are illustrated in
+	<xref linkend="fig:concepts:metadata"/>.</para>
+
+      <figure id="fig:concepts:metadata">
+	<title>Metadata relationships</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/metadata.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_2f3">As the illustration shows, there is
+	<emphasis>not</emphasis> a <quote>one to one</quote>
+	relationship between revisions in the changelog, manifest, or
+	filelog. If the manifest hasn't changed between two
+	changesets, the changelog entries for those changesets will
+	point to the same revision of the manifest.  If a file that
+	Mercurial tracks hasn't changed between two changesets, the
+	entry for that file in the two revisions of the manifest will
+	point to the same revision of its filelog.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Safe, efficient storage</title>
+
+    <para id="x_2f4">The underpinnings of changelogs, manifests, and filelogs are
+      provided by a single structure called the
+      <emphasis>revlog</emphasis>.</para>
+
+    <sect2>
+      <title>Efficient storage</title>
+
+      <para id="x_2f5">The revlog provides efficient storage of revisions using a
+	<emphasis>delta</emphasis> mechanism.  Instead of storing a
+	complete copy of a file for each revision, it stores the
+	changes needed to transform an older revision into the new
+	revision.  For many kinds of file data, these deltas are
+	typically a fraction of a percent of the size of a full copy
+	of a file.</para>
+
+      <para id="x_2f6">Some obsolete revision control systems can only work with
+	deltas of text files.  They must either store binary files as
+	complete snapshots or encoded into a text representation, both
+	of which are wasteful approaches.  Mercurial can efficiently
+	handle deltas of files with arbitrary binary contents; it
+	doesn't need to treat text as special.</para>
+
+    </sect2>
+    <sect2 id="sec:concepts:txn">
+      <title>Safe operation</title>
+
+      <para id="x_2f7">Mercurial only ever <emphasis>appends</emphasis> data to
+	the end of a revlog file. It never modifies a section of a
+	file after it has written it.  This is both more robust and
+	efficient than schemes that need to modify or rewrite
+	data.</para>
+
+      <para id="x_2f8">In addition, Mercurial treats every write as part of a
+	<emphasis>transaction</emphasis> that can span a number of
+	files.  A transaction is <emphasis>atomic</emphasis>: either
+	the entire transaction succeeds and its effects are all
+	visible to readers in one go, or the whole thing is undone.
+	This guarantee of atomicity means that if you're running two
+	copies of Mercurial, where one is reading data and one is
+	writing it, the reader will never see a partially written
+	result that might confuse it.</para>
+
+      <para id="x_2f9">The fact that Mercurial only appends to files makes it
+	easier to provide this transactional guarantee.  The easier it
+	is to do stuff like this, the more confident you should be
+	that it's done correctly.</para>
+
+    </sect2>
+    <sect2>
+      <title>Fast retrieval</title>
+
+      <para id="x_2fa">Mercurial cleverly avoids a pitfall common to all earlier
+	revision control systems: the problem of <emphasis>inefficient
+	  retrieval</emphasis>. Most revision control systems store
+	the contents of a revision as an incremental series of
+	modifications against a <quote>snapshot</quote>.  To
+	reconstruct a specific revision, you must first read the
+	snapshot, and then every one of the revisions between the
+	snapshot and your target revision.  The more history that a
+	file accumulates, the more revisions you must read, hence the
+	longer it takes to reconstruct a particular revision.</para>
+
+      <figure id="fig:concepts:snapshot">
+	<title>Snapshot of a revlog, with incremental deltas</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/snapshot.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_2fc">The innovation that Mercurial applies to this problem is
+	simple but effective.  Once the cumulative amount of delta
+	information stored since the last snapshot exceeds a fixed
+	threshold, it stores a new snapshot (compressed, of course),
+	instead of another delta.  This makes it possible to
+	reconstruct <emphasis>any</emphasis> revision of a file
+	quickly.  This approach works so well that it has since been
+	copied by several other revision control systems.</para>
+
+      <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustrates
+	the idea.  In an entry in a revlog's index file, Mercurial
+	stores the range of entries from the data file that it must
+	read to reconstruct a particular revision.</para>
+
+      <sect3>
+	<title>Aside: the influence of video compression</title>
+
+	<para id="x_2fe">If you're familiar with video compression or have ever
+	  watched a TV feed through a digital cable or satellite
+	  service, you may know that most video compression schemes
+	  store each frame of video as a delta against its predecessor
+	  frame.  In addition, these schemes use <quote>lossy</quote>
+	  compression techniques to increase the compression ratio, so
+	  visual errors accumulate over the course of a number of
+	  inter-frame deltas.</para>
+
+	<para id="x_2ff">Because it's possible for a video stream to <quote>drop
+	    out</quote> occasionally due to signal glitches, and to
+	  limit the accumulation of artefacts introduced by the lossy
+	  compression process, video encoders periodically insert a
+	  complete frame (called a <quote>key frame</quote>) into the
+	  video stream; the next delta is generated against that
+	  frame.  This means that if the video signal gets
+	  interrupted, it will resume once the next key frame is
+	  received.  Also, the accumulation of encoding errors
+	  restarts anew with each key frame.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Identification and strong integrity</title>
+
+      <para id="x_300">Along with delta or snapshot information, a revlog entry
+	contains a cryptographic hash of the data that it represents.
+	This makes it difficult to forge the contents of a revision,
+	and easy to detect accidental corruption.</para>
+
+      <para id="x_301">Hashes provide more than a mere check against corruption;
+	they are used as the identifiers for revisions.  The changeset
+	identification hashes that you see as an end user are from
+	revisions of the changelog.  Although filelogs and the
+	manifest also use hashes, Mercurial only uses these behind the
+	scenes.</para>
+
+      <para id="x_302">Mercurial verifies that hashes are correct when it
+	retrieves file revisions and when it pulls changes from
+	another repository.  If it encounters an integrity problem, it
+	will complain and stop whatever it's doing.</para>
+
+      <para id="x_303">In addition to the effect it has on retrieval efficiency,
+	Mercurial's use of periodic snapshots makes it more robust
+	against partial data corruption.  If a revlog becomes partly
+	corrupted due to a hardware error or system bug, it's often
+	possible to reconstruct some or most revisions from the
+	uncorrupted sections of the revlog, both before and after the
+	corrupted section.  This would not be possible with a
+	delta-only storage model.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Revision history, branching, and merging</title>
+
+    <para id="x_304">Every entry in a Mercurial revlog knows the identity of its
+      immediate ancestor revision, usually referred to as its
+      <emphasis>parent</emphasis>.  In fact, a revision contains room
+      for not one parent, but two.  Mercurial uses a special hash,
+      called the <quote>null ID</quote>, to represent the idea
+      <quote>there is no parent here</quote>.  This hash is simply a
+      string of zeroes.</para>
+
+    <para id="x_305">In <xref linkend="fig:concepts:revlog"/>, you can see
+      an example of the conceptual structure of a revlog.  Filelogs,
+      manifests, and changelogs all have this same structure; they
+      differ only in the kind of data stored in each delta or
+      snapshot.</para>
+
+    <para id="x_306">The first revision in a revlog (at the bottom of the image)
+      has the null ID in both of its parent slots.  For a
+      <quote>normal</quote> revision, its first parent slot contains
+      the ID of its parent revision, and its second contains the null
+      ID, indicating that the revision has only one real parent.  Any
+      two revisions that have the same parent ID are branches.  A
+      revision that represents a merge between branches has two normal
+      revision IDs in its parent slots.</para>
+
+    <figure id="fig:concepts:revlog">
+      <title>The conceptual structure of a revlog</title>
+      <mediaobject>
+	<imageobject><imagedata fileref="figs/revlog.png"/></imageobject>
+	<textobject><phrase>XXX add text</phrase></textobject>
+      </mediaobject>
+    </figure>
+
+  </sect1>
+  <sect1>
+    <title>The working directory</title>
+
+    <para id="x_307">In the working directory, Mercurial stores a snapshot of the
+      files from the repository as of a particular changeset.</para>
+
+    <para id="x_308">The working directory <quote>knows</quote> which changeset
+      it contains.  When you update the working directory to contain a
+      particular changeset, Mercurial looks up the appropriate
+      revision of the manifest to find out which files it was tracking
+      at the time that changeset was committed, and which revision of
+      each file was then current.  It then recreates a copy of each of
+      those files, with the same contents it had when the changeset
+      was committed.</para>
+
+    <para id="x_309">The <emphasis>dirstate</emphasis> contains Mercurial's
+      knowledge of the working directory.  This details which
+      changeset the working directory is updated to, and all of the
+      files that Mercurial is tracking in the working
+      directory.</para>
+
+    <para id="x_30a">Just as a revision of a revlog has room for two parents, so
+      that it can represent either a normal revision (with one parent)
+      or a merge of two earlier revisions, the dirstate has slots for
+      two parents.  When you use the <command role="hg-cmd">hg
+	update</command> command, the changeset that you update to is
+      stored in the <quote>first parent</quote> slot, and the null ID
+      in the second. When you <command role="hg-cmd">hg
+	merge</command> with another changeset, the first parent
+      remains unchanged, and the second parent is filled in with the
+      changeset you're merging with.  The <command role="hg-cmd">hg
+	parents</command> command tells you what the parents of the
+      dirstate are.</para>
+
+    <sect2>
+      <title>What happens when you commit</title>
+
+      <para id="x_30b">The dirstate stores parent information for more than just
+	book-keeping purposes.  Mercurial uses the parents of the
+	dirstate as <emphasis>the parents of a new
+	  changeset</emphasis> when you perform a commit.</para>
+
+      <figure id="fig:concepts:wdir">
+	<title>The working directory can have two parents</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_30d"><xref linkend="fig:concepts:wdir"/> shows the
+	normal state of the working directory, where it has a single
+	changeset as parent.  That changeset is the
+	<emphasis>tip</emphasis>, the newest changeset in the
+	repository that has no children.</para>
+
+      <figure id="fig:concepts:wdir-after-commit">
+	<title>The working directory gains new parents after a
+	  commit</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-after-commit.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_30f">It's useful to think of the working directory as
+	<quote>the changeset I'm about to commit</quote>.  Any files
+	that you tell Mercurial that you've added, removed, renamed,
+	or copied will be reflected in that changeset, as will
+	modifications to any files that Mercurial is already tracking;
+	the new changeset will have the parents of the working
+	directory as its parents.</para>
+
+      <para id="x_310">After a commit, Mercurial will update the
+	parents of the working directory, so that the first parent is
+	the ID of the new changeset, and the second is the null ID.
+	This is shown in <xref
+	  linkend="fig:concepts:wdir-after-commit"/>. Mercurial
+	doesn't touch any of the files in the working directory when
+	you commit; it just modifies the dirstate to note its new
+	parents.</para>
+
+    </sect2>
+    <sect2>
+      <title>Creating a new head</title>
+
+      <para id="x_311">It's perfectly normal to update the working directory to a
+	changeset other than the current tip.  For example, you might
+	want to know what your project looked like last Tuesday, or
+	you could be looking through changesets to see which one
+	introduced a bug.  In cases like this, the natural thing to do
+	is update the working directory to the changeset you're
+	interested in, and then examine the files in the working
+	directory directly to see their contents as they were when you
+	committed that changeset.  The effect of this is shown in
+	<xref linkend="fig:concepts:wdir-pre-branch"/>.</para>
+
+      <figure id="fig:concepts:wdir-pre-branch">
+	<title>The working directory, updated to an older
+	  changeset</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-pre-branch.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_313">Having updated the working directory to an
+	older changeset, what happens if you make some changes, and
+	then commit?  Mercurial behaves in the same way as I outlined
+	above.  The parents of the working directory become the
+	parents of the new changeset.  This new changeset has no
+	children, so it becomes the new tip.  And the repository now
+	contains two changesets that have no children; we call these
+	<emphasis>heads</emphasis>.  You can see the structure that
+	this creates in <xref
+	  linkend="fig:concepts:wdir-branch"/>.</para>
+
+      <figure id="fig:concepts:wdir-branch">
+	<title>After a commit made while synced to an older
+	  changeset</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/wdir-branch.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <note>
+	<para id="x_315">  If you're new to Mercurial, you should keep in mind a
+	  common <quote>error</quote>, which is to use the <command
+	    role="hg-cmd">hg pull</command> command without any
+	  options.  By default, the <command role="hg-cmd">hg
+	    pull</command> command <emphasis>does not</emphasis>
+	  update the working directory, so you'll bring new changesets
+	  into your repository, but the working directory will stay
+	  synced at the same changeset as before the pull.  If you
+	  make some changes and commit afterwards, you'll thus create
+	  a new head, because your working directory isn't synced to
+	  whatever the current tip is.</para>
+
+	<para id="x_316">  I put the word <quote>error</quote> in
+	  quotes because all that you need to do to rectify this
+	  situation is <command role="hg-cmd">hg merge</command>, then
+	  <command role="hg-cmd">hg commit</command>.  In other words,
+	  this almost never has negative consequences; it's just
+	  something of a surprise for newcomers.  I'll discuss other
+	  ways to avoid this behavior, and why Mercurial behaves in
+	  this initially surprising way, later on.</para>
+      </note>
+
+    </sect2>
+    <sect2>
+      <title>Merging changes</title>
+
+      <para id="x_317">When you run the <command role="hg-cmd">hg
+	  merge</command> command, Mercurial leaves the first parent
+	of the working directory unchanged, and sets the second parent
+	to the changeset you're merging with, as shown in <xref
+	  linkend="fig:concepts:wdir-merge"/>.</para>
+
+      <figure id="fig:concepts:wdir-merge">
+	<title>Merging two heads</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figs/wdir-merge.png"/>
+	  </imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_319">Mercurial also has to modify the working directory, to
+	merge the files managed in the two changesets.  Simplified a
+	little, the merging process goes like this, for every file in
+	the manifests of both changesets.</para>
+      <itemizedlist>
+	<listitem><para id="x_31a">If neither changeset has modified a file, do
+	    nothing with that file.</para>
+	</listitem>
+	<listitem><para id="x_31b">If one changeset has modified a file, and the
+	    other hasn't, create the modified copy of the file in the
+	    working directory.</para>
+	</listitem>
+	<listitem><para id="x_31c">If one changeset has removed a file, and the
+	    other hasn't (or has also deleted it), delete the file
+	    from the working directory.</para>
+	</listitem>
+	<listitem><para id="x_31d">If one changeset has removed a file, but the
+	    other has modified the file, ask the user what to do: keep
+	    the modified file, or remove it?</para>
+	</listitem>
+	<listitem><para id="x_31e">If both changesets have modified a file,
+	    invoke an external merge program to choose the new
+	    contents for the merged file.  This may require input from
+	    the user.</para>
+	</listitem>
+	<listitem><para id="x_31f">If one changeset has modified a file, and the
+	    other has renamed or copied the file, make sure that the
+	    changes follow the new name of the file.</para>
+	</listitem></itemizedlist>
+      <para id="x_320">There are more details&emdash;merging has plenty of corner
+	cases&emdash;but these are the most common choices that are
+	involved in a merge.  As you can see, most cases are
+	completely automatic, and indeed most merges finish
+	automatically, without requiring your input to resolve any
+	conflicts.</para>
+
+      <para id="x_321">When you're thinking about what happens when you commit
+	after a merge, once again the working directory is <quote>the
+	  changeset I'm about to commit</quote>.  After the <command
+	  role="hg-cmd">hg merge</command> command completes, the
+	working directory has two parents; these will become the
+	parents of the new changeset.</para>
+
+      <para id="x_322">Mercurial lets you perform multiple merges, but you must
+	commit the results of each individual merge as you go.  This
+	is necessary because Mercurial only tracks two parents for
+	both revisions and the working directory.  While it would be
+	technically possible to merge multiple changesets at once, the
+	prospect of user confusion and making a terrible mess of a
+	merge immediately becomes overwhelming.</para>
+
+    </sect2>
+
+    <sect2>
+      <title>Merging and renames</title>
+
+      <para id="x_69a">A surprising number of revision control systems pay little
+	or no attention to a file's <emphasis>name</emphasis> over
+	time.  For instance, it used to be common that if a file got
+	renamed on one side of a merge, the changes from the other
+	side would be silently dropped.</para>
+
+      <para id="x_69b">Mercurial records metadata when you tell it to perform a
+	rename or copy. It uses this metadata during a merge to do the
+	right thing in the case of a merge.  For instance, if I rename
+	a file, and you edit it without renaming it, when we merge our
+	work the file will be renamed and have your edits
+	applied.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Other interesting design features</title>
+
+    <para id="x_323">In the sections above, I've tried to highlight some of the
+      most important aspects of Mercurial's design, to illustrate that
+      it pays careful attention to reliability and performance.
+      However, the attention to detail doesn't stop there.  There are
+      a number of other aspects of Mercurial's construction that I
+      personally find interesting.  I'll detail a few of them here,
+      separate from the <quote>big ticket</quote> items above, so that
+      if you're interested, you can gain a better idea of the amount
+      of thinking that goes into a well-designed system.</para>
+
+    <sect2>
+      <title>Clever compression</title>
+
+      <para id="x_324">When appropriate, Mercurial will store both snapshots and
+	deltas in compressed form.  It does this by always
+	<emphasis>trying to</emphasis> compress a snapshot or delta,
+	but only storing the compressed version if it's smaller than
+	the uncompressed version.</para>
+
+      <para id="x_325">This means that Mercurial does <quote>the right
+	  thing</quote> when storing a file whose native form is
+	compressed, such as a <literal>zip</literal> archive or a JPEG
+	image.  When these types of files are compressed a second
+	time, the resulting file is usually bigger than the
+	once-compressed form, and so Mercurial will store the plain
+	<literal>zip</literal> or JPEG.</para>
+
+      <para id="x_326">Deltas between revisions of a compressed file are usually
+	larger than snapshots of the file, and Mercurial again does
+	<quote>the right thing</quote> in these cases.  It finds that
+	such a delta exceeds the threshold at which it should store a
+	complete snapshot of the file, so it stores the snapshot,
+	again saving space compared to a naive delta-only
+	approach.</para>
+
+      <sect3>
+	<title>Network recompression</title>
+
+	<para id="x_327">When storing revisions on disk, Mercurial uses the
+	  <quote>deflate</quote> compression algorithm (the same one
+	  used by the popular <literal>zip</literal> archive format),
+	  which balances good speed with a respectable compression
+	  ratio.  However, when transmitting revision data over a
+	  network connection, Mercurial uncompresses the compressed
+	  revision data.</para>
+
+	<para id="x_328">If the connection is over HTTP, Mercurial recompresses
+	  the entire stream of data using a compression algorithm that
+	  gives a better compression ratio (the Burrows-Wheeler
+	  algorithm from the widely used <literal>bzip2</literal>
+	  compression package).  This combination of algorithm and
+	  compression of the entire stream (instead of a revision at a
+	  time) substantially reduces the number of bytes to be
+	  transferred, yielding better network performance over most
+	  kinds of network.</para>
+
+	<para id="x_329">(If the connection is over <command>ssh</command>,
+	  Mercurial <emphasis>doesn't</emphasis> recompress the
+	  stream, because <command>ssh</command> can already do this
+	  itself.)</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Read/write ordering and atomicity</title>
+
+      <para id="x_32a">Appending to files isn't the whole story when
+	it comes to guaranteeing that a reader won't see a partial
+	write.  If you recall <xref linkend="fig:concepts:metadata"/>,
+	revisions in
+	the changelog point to revisions in the manifest, and
+	revisions in the manifest point to revisions in filelogs.
+	This hierarchy is deliberate.</para>
+
+      <para id="x_32b">A writer starts a transaction by writing filelog and
+	manifest data, and doesn't write any changelog data until
+	those are finished.  A reader starts by reading changelog
+	data, then manifest data, followed by filelog data.</para>
+
+      <para id="x_32c">Since the writer has always finished writing filelog and
+	manifest data before it writes to the changelog, a reader will
+	never read a pointer to a partially written manifest revision
+	from the changelog, and it will never read a pointer to a
+	partially written filelog revision from the manifest.</para>
+
+    </sect2>
+    <sect2>
+      <title>Concurrent access</title>
+
+      <para id="x_32d">The read/write ordering and atomicity guarantees mean that
+	Mercurial never needs to <emphasis>lock</emphasis> a
+	repository when it's reading data, even if the repository is
+	being written to while the read is occurring. This has a big
+	effect on scalability; you can have an arbitrary number of
+	Mercurial processes safely reading data from a repository
+	safely all at once, no matter whether it's being written to or
+	not.</para>
+
+      <para id="x_32e">The lockless nature of reading means that if you're
+	sharing a repository on a multi-user system, you don't need to
+	grant other local users permission to
+	<emphasis>write</emphasis> to your repository in order for
+	them to be able to clone it or pull changes from it; they only
+	need <emphasis>read</emphasis> permission.  (This is
+	<emphasis>not</emphasis> a common feature among revision
+	control systems, so don't take it for granted!  Most require
+	readers to be able to lock a repository to access it safely,
+	and this requires write permission on at least one directory,
+	which of course makes for all kinds of nasty and annoying
+	security and administrative problems.)</para>
+
+      <para id="x_32f">Mercurial uses locks to ensure that only one process can
+	write to a repository at a time (the locking mechanism is safe
+	even over filesystems that are notoriously hostile to locking,
+	such as NFS).  If a repository is locked, a writer will wait
+	for a while to retry if the repository becomes unlocked, but
+	if the repository remains locked for too long, the process
+	attempting to write will time out after a while. This means
+	that your daily automated scripts won't get stuck forever and
+	pile up if a system crashes unnoticed, for example.  (Yes, the
+	timeout is configurable, from zero to infinity.)</para>
+
+      <sect3>
+	<title>Safe dirstate access</title>
+
+	<para id="x_330">As with revision data, Mercurial doesn't take a lock to
+	  read the dirstate file; it does acquire a lock to write it.
+	  To avoid the possibility of reading a partially written copy
+	  of the dirstate file, Mercurial writes to a file with a
+	  unique name in the same directory as the dirstate file, then
+	  renames the temporary file atomically to
+	  <filename>dirstate</filename>.  The file named
+	  <filename>dirstate</filename> is thus guaranteed to be
+	  complete, not partially written.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Avoiding seeks</title>
+
+      <para id="x_331">Critical to Mercurial's performance is the avoidance of
+	seeks of the disk head, since any seek is far more expensive
+	than even a comparatively large read operation.</para>
+
+      <para id="x_332">This is why, for example, the dirstate is stored in a
+	single file.  If there were a dirstate file per directory that
+	Mercurial tracked, the disk would seek once per directory.
+	Instead, Mercurial reads the entire single dirstate file in
+	one step.</para>
+
+      <para id="x_333">Mercurial also uses a <quote>copy on write</quote> scheme
+	when cloning a repository on local storage.  Instead of
+	copying every revlog file from the old repository into the new
+	repository, it makes a <quote>hard link</quote>, which is a
+	shorthand way to say <quote>these two names point to the same
+	  file</quote>.  When Mercurial is about to write to one of a
+	revlog's files, it checks to see if the number of names
+	pointing at the file is greater than one.  If it is, more than
+	one repository is using the file, so Mercurial makes a new
+	copy of the file that is private to this repository.</para>
+
+      <para id="x_334">A few revision control developers have pointed out that
+	this idea of making a complete private copy of a file is not
+	very efficient in its use of storage.  While this is true,
+	storage is cheap, and this method gives the highest
+	performance while deferring most book-keeping to the operating
+	system.  An alternative scheme would most likely reduce
+	performance and increase the complexity of the software, each
+	of which is much more important to the <quote>feel</quote> of
+	day-to-day use.</para>
+
+    </sect2>
+    <sect2>
+      <title>Other contents of the dirstate</title>
+
+      <para id="x_335">Because Mercurial doesn't force you to tell it when you're
+	modifying a file, it uses the dirstate to store some extra
+	information so it can determine efficiently whether you have
+	modified a file.  For each file in the working directory, it
+	stores the time that it last modified the file itself, and the
+	size of the file at that time.</para>
+
+      <para id="x_336">When you explicitly <command role="hg-cmd">hg
+	  add</command>, <command role="hg-cmd">hg remove</command>,
+	<command role="hg-cmd">hg rename</command> or <command
+	  role="hg-cmd">hg copy</command> files, Mercurial updates the
+	dirstate so that it knows what to do with those files when you
+	commit.</para>
+
+      <para id="x_337">When Mercurial is checking the states of files in the
+	working directory, it first checks a file's modification time.
+	If that has not changed, the file must not have been modified.
+	If the file's size has changed, the file must have been
+	modified.  If the modification time has changed, but the size
+	has not, only then does Mercurial need to read the actual
+	contents of the file to see if they've changed. Storing these
+	few extra pieces of information dramatically reduces the
+	amount of data that Mercurial needs to read, which yields
+	large performance improvements compared to other revision
+	control systems.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch04-daily.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,682 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:daily">
+  <?dbhtml filename="mercurial-in-daily-use.html"?>
+  <title>Mercurial in daily use</title>
+
+  <sect1>
+    <title>Telling Mercurial which files to track</title>
+
+    <para id="x_1a3">Mercurial does not work with files in your repository unless
+      you tell it to manage them.  The <command role="hg-cmd">hg
+	status</command> command will tell you which files Mercurial
+      doesn't know about; it uses a
+      <quote><literal>?</literal></quote> to display such
+      files.</para>
+
+    <para id="x_1a4">To tell Mercurial to track a file, use the <command
+	role="hg-cmd">hg add</command> command.  Once you have added a
+      file, the entry in the output of <command role="hg-cmd">hg
+	status</command> for that file changes from
+      <quote><literal>?</literal></quote> to
+      <quote><literal>A</literal></quote>.</para>
+
+      &interaction.daily.files.add;
+
+    <para id="x_1a5">After you run a <command role="hg-cmd">hg commit</command>,
+      the files that you added before the commit will no longer be
+      listed in the output of <command role="hg-cmd">hg
+	status</command>.  The reason for this is that by default, <command
+	role="hg-cmd">hg status</command> only tells you about
+      <quote>interesting</quote> files&emdash;those that you have (for
+      example) modified, removed, or renamed.  If you have a repository
+      that contains thousands of files, you will rarely want to know
+      about files that Mercurial is tracking, but that have not
+      changed.  (You can still get this information; we'll return to
+      this later.)</para>
+
+    <para id="x_1a6">Once you add a file, Mercurial doesn't do anything with it
+      immediately.  Instead, it will take a snapshot of the file's
+      state the next time you perform a commit.  It will then continue
+      to track the changes you make to the file every time you commit,
+      until you remove the file.</para>
+
+    <sect2>
+      <title>Explicit versus implicit file naming</title>
+
+      <para id="x_1a7">A useful behavior that Mercurial has is that if you pass
+	the name of a directory to a command, every Mercurial command
+	will treat this as <quote>I want to operate on every file in
+	  this directory and its subdirectories</quote>.</para>
+
+      &interaction.daily.files.add-dir;
+
+      <para id="x_1a8">Notice in this example that Mercurial printed
+	the names of the files it added, whereas it didn't do so when
+	we added the file named <filename>myfile.txt</filename> in the
+	earlier example.</para>
+
+      <para id="x_1a9">What's going on is that in the former case, we explicitly
+	named the file to add on the command line.  The assumption
+	that Mercurial makes in such cases is that we know what we
+	are doing, and it doesn't print any output.</para>
+
+      <para id="x_1aa">However, when we <emphasis>imply</emphasis> the names of
+	files by giving the name of a directory, Mercurial takes the
+	extra step of printing the name of each file that it does
+	something with.  This makes it more clear what is happening,
+	and reduces the likelihood of a silent and nasty surprise.
+	This behavior is common to most Mercurial commands.</para>
+    </sect2>
+
+    <sect2>
+      <title>Mercurial tracks files, not directories</title>
+
+      <para id="x_1ab">Mercurial does not track directory information.  Instead,
+	it tracks the path to a file.  Before creating a file, it
+	first creates any missing directory components of the path.
+	After it deletes a file, it then deletes any empty directories
+	that were in the deleted file's path.  This sounds like a
+	trivial distinction, but it has one minor practical
+	consequence: it is not possible to represent a completely
+	empty directory in Mercurial.</para>
+
+      <para id="x_1ac">Empty directories are rarely useful, and there are
+	unintrusive workarounds that you can use to achieve an
+	appropriate effect.  The developers of Mercurial thus felt
+	that the complexity that would be required to manage empty
+	directories was not worth the limited benefit this feature
+	would bring.</para>
+
+      <para id="x_1ad">If you need an empty directory in your repository, there
+	are a few ways to achieve this. One is to create a directory,
+	then <command role="hg-cmd">hg add</command> a
+	<quote>hidden</quote> file to that directory.  On Unix-like
+	systems, any file name that begins with a period
+	(<quote><literal>.</literal></quote>) is treated as hidden by
+	most commands and GUI tools.  This approach is illustrated
+	below.</para>
+
+&interaction.daily.files.hidden;
+
+      <para id="x_1ae">Another way to tackle a need for an empty directory is to
+	simply create one in your automated build scripts before they
+	will need it.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>How to stop tracking a file</title>
+
+    <para id="x_1af">Once you decide that a file no longer belongs in your
+      repository, use the <command role="hg-cmd">hg remove</command>
+      command. This deletes the file, and tells Mercurial to stop
+      tracking it.  A removed file is represented in the output of
+      <command role="hg-cmd">hg status</command> with a
+      <quote><literal>R</literal></quote>.</para>
+
+    &interaction.daily.files.remove;
+
+    <para id="x_1b0">After you <command role="hg-cmd">hg remove</command> a file,
+      Mercurial will no longer track changes to that file, even if you
+      recreate a file with the same name in your working directory.
+      If you do recreate a file with the same name and want Mercurial
+      to track the new file, simply <command role="hg-cmd">hg
+	add</command> it. Mercurial will know that the newly added
+      file is not related to the old file of the same name.</para>
+
+    <sect2>
+      <title>Removing a file does not affect its history</title>
+
+      <para id="x_1b1">It is important to understand that removing a file has
+	only two effects.</para>
+      <itemizedlist>
+	<listitem><para id="x_1b2">It removes the current version of the file
+	    from the working directory.</para>
+	</listitem>
+	<listitem><para id="x_1b3">It stops Mercurial from tracking changes to
+	    the file, from the time of the next commit.</para>
+	</listitem></itemizedlist>
+      <para id="x_1b4">Removing a file <emphasis>does not</emphasis> in any way
+	alter the <emphasis>history</emphasis> of the file.</para>
+
+      <para id="x_1b5">If you update the working directory to a
+	changeset that was committed when it was still tracking a file
+	that you later removed, the file will reappear in the working
+	directory, with the contents it had when you committed that
+	changeset.  If you then update the working directory to a
+	later changeset, in which the file had been removed, Mercurial
+	will once again remove the file from the working
+	directory.</para>
+    </sect2>
+
+    <sect2>
+      <title>Missing files</title>
+
+      <para id="x_1b6">Mercurial considers a file that you have deleted, but not
+	used <command role="hg-cmd">hg remove</command> to delete, to
+	be <emphasis>missing</emphasis>.  A missing file is
+	represented with <quote><literal>!</literal></quote> in the
+	output of <command role="hg-cmd">hg status</command>.
+	Mercurial commands will not generally do anything with missing
+	files.</para>
+
+      &interaction.daily.files.missing;
+
+      <para id="x_1b7">If your repository contains a file that <command
+	  role="hg-cmd">hg status</command> reports as missing, and
+	you want the file to stay gone, you can run <command
+	  role="hg-cmd">hg remove <option
+	    role="hg-opt-remove">--after</option></command> at any
+	time later on, to tell Mercurial that you really did mean to
+	remove the file.</para>
+
+      &interaction.daily.files.remove-after;
+
+      <para id="x_1b8">On the other hand, if you deleted the missing file by
+	accident, give <command role="hg-cmd">hg revert</command> the
+	name of the file to recover.  It will reappear, in unmodified
+	form.</para>
+
+      &interaction.daily.files.recover-missing;
+    </sect2>
+
+    <sect2>
+      <title>Aside: why tell Mercurial explicitly to remove a
+	file?</title>
+
+      <para id="x_1b9">You might wonder why Mercurial requires you to explicitly
+	tell it that you are deleting a file.  Early during the
+	development of Mercurial, it let you delete a file however you
+	pleased; Mercurial would notice the absence of the file
+	automatically when you next ran a <command role="hg-cmd">hg
+	  commit</command>, and stop tracking the file.  In practice,
+	this made it too easy to accidentally remove a file without
+	noticing.</para>
+    </sect2>
+
+    <sect2>
+      <title>Useful shorthand&emdash;adding and removing files in one
+	step</title>
+
+      <para id="x_1ba">Mercurial offers a combination command, <command
+	  role="hg-cmd">hg addremove</command>, that adds untracked
+	files and marks missing files as removed.</para>
+
+      &interaction.daily.files.addremove;
+
+      <para id="x_1bb">The <command role="hg-cmd">hg commit</command> command
+	also provides a <option role="hg-opt-commit">-A</option>
+	option that performs this same add-and-remove, immediately
+	followed by a commit.</para>
+
+      &interaction.daily.files.commit-addremove;
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Copying files</title>
+
+    <para id="x_1bc">Mercurial provides a <command role="hg-cmd">hg
+	copy</command> command that lets you make a new copy of a
+      file.  When you copy a file using this command, Mercurial makes
+      a record of the fact that the new file is a copy of the original
+      file.  It treats these copied files specially when you merge
+      your work with someone else's.</para>
+
+    <sect2>
+      <title>The results of copying during a merge</title>
+
+      <para id="x_1bd">What happens during a merge is that changes
+	<quote>follow</quote> a copy.  To best illustrate what this
+	means, let's create an example.  We'll start with the usual
+	tiny repository that contains a single file.</para>
+
+      &interaction.daily.copy.init;
+
+      <para id="x_1be">We need to do some work in
+	parallel, so that we'll have something to merge.  So let's
+	clone our repository.</para>
+
+      &interaction.daily.copy.clone;
+
+      <para id="x_1bf">Back in our initial repository, let's use the <command
+	  role="hg-cmd">hg copy</command> command to make a copy of
+	the first file we created.</para>
+
+      &interaction.daily.copy.copy;
+
+      <para id="x_1c0">If we look at the output of the <command role="hg-cmd">hg
+	  status</command> command afterwards, the copied file looks
+	just like a normal added file.</para>
+
+      &interaction.daily.copy.status;
+
+      <para id="x_1c1">But if we pass the <option
+	  role="hg-opt-status">-C</option> option to <command
+	  role="hg-cmd">hg status</command>, it prints another line of
+	output: this is the file that our newly-added file was copied
+	<emphasis>from</emphasis>.</para>
+
+      &interaction.daily.copy.status-copy;
+
+      <para id="x_1c2">Now, back in the repository we cloned, let's make a change
+	in parallel.  We'll add a line of content to the original file
+	that we created.</para>
+
+      &interaction.daily.copy.other;
+
+      <para id="x_1c3">Now we have a modified <filename>file</filename> in this
+	repository.  When we pull the changes from the first
+	repository, and merge the two heads, Mercurial will propagate
+	the changes that we made locally to <filename>file</filename>
+	into its copy, <filename>new-file</filename>.</para>
+
+      &interaction.daily.copy.merge;
+    </sect2>
+
+    <sect2 id="sec:daily:why-copy">
+      <title>Why should changes follow copies?</title>
+
+      <para id="x_1c4">This behavior&emdash;of changes to a file
+	propagating out to copies of the file&emdash;might seem
+	esoteric, but in most cases it's highly desirable.</para>
+
+      <para id="x_1c5">First of all, remember that this propagation
+	<emphasis>only</emphasis> happens when you merge.  So if you
+	<command role="hg-cmd">hg copy</command> a file, and
+	subsequently modify the original file during the normal course
+	of your work, nothing will happen.</para>
+
+      <para id="x_1c6">The second thing to know is that modifications will only
+	propagate across a copy as long as the changeset that you're
+	merging changes from <emphasis>hasn't yet seen</emphasis> 
+	the copy.</para>
+
+      <para id="x_1c7">The reason that Mercurial does this is as follows.  Let's
+	say I make an important bug fix in a source file, and commit
+	my changes. Meanwhile, you've decided to <command
+	  role="hg-cmd">hg copy</command> the file in your repository,
+	without knowing about the bug or having seen the fix, and you
+	have started hacking on your copy of the file.</para>
+
+      <para id="x_1c8">If you pulled and merged my changes, and Mercurial
+	<emphasis>didn't</emphasis> propagate changes across copies,
+	your new source file would now contain the bug, and unless you
+	knew to propagate the bug fix by hand, the bug would
+	<emphasis>remain</emphasis> in your copy of the file.</para>
+
+      <para id="x_1c9">By automatically propagating the change that fixed the bug
+	from the original file to the copy, Mercurial prevents this
+	class of problem. To my knowledge, Mercurial is the
+	<emphasis>only</emphasis> revision control system that
+	propagates changes across copies like this.</para>
+
+      <para id="x_1ca">Once your change history has a record that the copy and
+	subsequent merge occurred, there's usually no further need to
+	propagate changes from the original file to the copied file,
+	and that's why Mercurial only propagates changes across copies
+	at the first merge, and not afterwards.</para>
+    </sect2>
+
+    <sect2>
+      <title>How to make changes <emphasis>not</emphasis> follow a
+	copy</title>
+
+      <para id="x_1cb">If, for some reason, you decide that this business of
+	automatically propagating changes across copies is not for
+	you, simply use your system's normal file copy command (on
+	Unix-like systems, that's <command>cp</command>) to make a
+	copy of a file, then <command role="hg-cmd">hg add</command>
+	the new copy by hand.  Before you do so, though, please do
+	reread <xref linkend="sec:daily:why-copy"/>, and make
+	an informed
+	decision that this behavior is not appropriate to your
+	specific case.</para>
+
+    </sect2>
+    <sect2>
+      <title>Behavior of the <command role="hg-cmd">hg copy</command>
+	command</title>
+
+      <para id="x_1cc">When you use the <command role="hg-cmd">hg copy</command>
+	command, Mercurial makes a copy of each source file as it
+	currently stands in the working directory.  This means that if
+	you make some modifications to a file, then <command
+	  role="hg-cmd">hg copy</command> it without first having
+	committed those changes, the new copy will also contain the
+	modifications you have made up until that point.  (I find this
+	behavior a little counterintuitive, which is why I mention it
+	here.)</para>
+
+      <para id="x_1cd">The <command role="hg-cmd">hg copy</command>
+	command acts similarly to the Unix <command>cp</command>
+	command (you can use the <command role="hg-cmd">hg
+	  cp</command> alias if you prefer).  We must supply two or
+	more arguments, of which the last is treated as the
+	<emphasis>destination</emphasis>, and all others are
+	<emphasis>sources</emphasis>.</para>
+
+      <para id="x_685">If you pass <command role="hg-cmd">hg copy</command> a
+	single file as the source, and the destination does not exist,
+	it creates a new file with that name.</para>
+
+      &interaction.daily.copy.simple;
+      
+      <para id="x_1ce">If the destination is a directory, Mercurial copies its
+	sources into that directory.</para>
+
+      &interaction.daily.copy.dir-dest;
+
+      <para id="x_1cf">Copying a directory is
+	recursive, and preserves the directory structure of the
+	source.</para>
+
+      &interaction.daily.copy.dir-src;
+
+      <para id="x_1d0">If the source and destination are both directories, the
+	source tree is recreated in the destination directory.</para>
+
+	&interaction.daily.copy.dir-src-dest;
+
+      <para id="x_1d1">As with the <command role="hg-cmd">hg remove</command>
+	command, if you copy a file manually and then want Mercurial
+	to know that you've copied the file, simply use the <option
+	  role="hg-opt-copy">--after</option> option to <command
+	  role="hg-cmd">hg copy</command>.</para>
+
+      &interaction.daily.copy.after;
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Renaming files</title>
+
+    <para id="x_1d2">It's rather more common to need to rename a file than to
+      make a copy of it.  The reason I discussed the <command
+	role="hg-cmd">hg copy</command> command before talking about
+      renaming files is that Mercurial treats a rename in essentially
+      the same way as a copy.  Therefore, knowing what Mercurial does
+      when you copy a file tells you what to expect when you rename a
+      file.</para>
+
+    <para id="x_1d3">When you use the <command role="hg-cmd">hg rename</command>
+      command, Mercurial makes a copy of each source file, then
+      deletes it and marks the file as removed.</para>
+
+      &interaction.daily.rename.rename;
+
+    <para id="x_1d4">The <command role="hg-cmd">hg status</command> command shows
+      the newly copied file as added, and the copied-from file as
+      removed.</para>
+
+    &interaction.daily.rename.status;
+
+    <para id="x_1d5">As with the results of a <command role="hg-cmd">hg
+	copy</command>, we must use the <option
+	role="hg-opt-status">-C</option> option to <command
+	role="hg-cmd">hg status</command> to see that the added file
+      is really being tracked by Mercurial as a copy of the original,
+      now removed, file.</para>
+
+    &interaction.daily.rename.status-copy;
+
+    <para id="x_1d6">As with <command role="hg-cmd">hg remove</command> and
+      <command role="hg-cmd">hg copy</command>, you can tell Mercurial
+      about a rename after the fact using the <option
+	role="hg-opt-rename">--after</option> option.  In most other
+      respects, the behavior of the <command role="hg-cmd">hg
+	rename</command> command, and the options it accepts, are
+      similar to the <command role="hg-cmd">hg copy</command>
+      command.</para>
+
+    <para id="x_686">If you're familiar with the Unix command line, you'll be
+      glad to know that <command role="hg-cmd">hg rename</command>
+      command can be invoked as <command role="hg-cmd">hg
+	mv</command>.</para>
+
+    <sect2>
+      <title>Renaming files and merging changes</title>
+
+      <para id="x_1d7">Since Mercurial's rename is implemented as
+	copy-and-remove, the same propagation of changes happens when
+	you merge after a rename as after a copy.</para>
+
+      <para id="x_1d8">If I modify a file, and you rename it to a new name, and
+	then we merge our respective changes, my modifications to the
+	file under its original name will be propagated into the file
+	under its new name. (This is something you might expect to
+	<quote>simply work,</quote> but not all revision control
+	systems actually do this.)</para>
+
+      <para id="x_1d9">Whereas having changes follow a copy is a feature where
+	you can perhaps nod and say <quote>yes, that might be
+	  useful,</quote> it should be clear that having them follow a
+	rename is definitely important.  Without this facility, it
+	would simply be too easy for changes to become orphaned when
+	files are renamed.</para>
+    </sect2>
+
+    <sect2>
+      <title>Divergent renames and merging</title>
+
+      <para id="x_1da">The case of diverging names occurs when two developers
+	start with a file&emdash;let's call it
+	<filename>foo</filename>&emdash;in their respective
+	repositories.</para>
+
+      &interaction.rename.divergent.clone;
+
+      <para id="x_1db">Anne renames the file to <filename>bar</filename>.</para>
+
+      &interaction.rename.divergent.rename.anne;
+
+      <para id="x_1dc">Meanwhile, Bob renames it to
+	<filename>quux</filename>. (Remember that <command
+	  role="hg-cmd">hg mv</command> is an alias for <command
+	  role="hg-cmd">hg rename</command>.)</para>
+
+	&interaction.rename.divergent.rename.bob;
+
+      <para id="x_1dd">I like to think of this as a conflict because each
+	developer has expressed different intentions about what the
+	file ought to be named.</para>
+
+      <para id="x_1de">What do you think should happen when they merge their
+	work? Mercurial's actual behavior is that it always preserves
+	<emphasis>both</emphasis> names when it merges changesets that
+	contain divergent renames.</para>
+
+      &interaction.rename.divergent.merge;
+
+      <para id="x_1df">Notice that while Mercurial warns about the divergent
+	renames, it leaves it up to you to do something about the
+	divergence after the merge.</para>
+    </sect2>
+
+    <sect2>
+      <title>Convergent renames and merging</title>
+
+      <para id="x_1e0">Another kind of rename conflict occurs when two people
+	choose to rename different <emphasis>source</emphasis> files
+	to the same <emphasis>destination</emphasis>. In this case,
+	Mercurial runs its normal merge machinery, and lets you guide
+	it to a suitable resolution.</para>
+    </sect2>
+
+    <sect2>
+      <title>Other name-related corner cases</title>
+
+      <para id="x_1e1">Mercurial has a longstanding bug in which it fails to
+	handle a merge where one side has a file with a given name,
+	while another has a directory with the same name.  This is
+	documented as <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue29">issue
+	  29</ulink>.</para>
+
+      &interaction.issue29.go;
+
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Recovering from mistakes</title>
+
+    <para id="x_1e2">Mercurial has some useful commands that will help you to
+      recover from some common mistakes.</para>
+
+    <para id="x_1e3">The <command role="hg-cmd">hg revert</command> command lets
+      you undo changes that you have made to your working directory.
+      For example, if you <command role="hg-cmd">hg add</command> a
+      file by accident, just run <command role="hg-cmd">hg
+	revert</command> with the name of the file you added, and
+      while the file won't be touched in any way, it won't be tracked
+      for adding by Mercurial any longer, either.  You can also use
+      <command role="hg-cmd">hg revert</command> to get rid of
+      erroneous changes to a file.</para>
+
+    <para id="x_1e4">It's good to remember that the <command role="hg-cmd">hg
+	revert</command> command is useful for changes that you have
+      not yet committed.  Once you've committed a change, if you
+      decide it was a mistake, you can still do something about it,
+      though your options may be more limited.</para>
+
+    <para id="x_1e5">For more information about the <command
+	role="hg-cmd">hg revert</command> command, and details about
+      how to deal with changes you have already committed, see <xref
+	linkend="chap:undo"/>.</para>
+  </sect1>
+
+  <sect1>
+    <title>Dealing with tricky merges</title>
+
+    <para id="x_687">In a complicated or large project, it's not unusual for a
+      merge of two changesets to result in some headaches.  Suppose
+      there's a big source file that's been extensively edited by each
+      side of a merge: this is almost inevitably going to result in
+      conflicts, some of which can take a few tries to sort
+      out.</para>
+
+    <para id="x_688">Let's develop a simple case of this and see how to deal with
+      it.  We'll start off with a repository containing one file, and
+      clone it twice.</para>
+
+    &interaction.ch04-resolve.init;
+
+    <para id="x_689">In one clone, we'll modify the file in one way.</para>
+
+    &interaction.ch04-resolve.left;
+
+    <para id="x_68a">In another, we'll modify the file differently.</para>
+
+    &interaction.ch04-resolve.right;
+
+    <para id="x_68b">Next, we'll pull each set of changes into our original
+      repo.</para>
+
+    &interaction.ch04-resolve.pull;
+
+    <para id="x_68c">We expect our repository to now contain two heads.</para>
+
+    &interaction.ch04-resolve.heads;
+
+    <para id="x_68d">Normally, if we run <command role="hg-cmd">hg
+	merge</command> at this point, it will drop us into a GUI that
+      will let us manually resolve the conflicting edits to
+      <filename>myfile.txt</filename>.  However, to simplify things
+      for presentation here, we'd like the merge to fail immediately
+      instead.  Here's one way we can do so.</para>
+
+    &interaction.ch04-resolve.export;
+
+    <para id="x_68e">We've told Mercurial's merge machinery to run the command
+      <command>false</command> (which, as we desire, fails
+      immediately) if it detects a merge that it can't sort out
+      automatically.</para>
+
+    <para id="x_68f">If we now fire up <command role="hg-cmd">hg
+	merge</command>, it should grind to a halt and report a
+	failure.</para>
+
+    &interaction.ch04-resolve.merge;
+
+    <para id="x_690">Even if we don't notice that the merge failed, Mercurial
+      will prevent us from accidentally committing the result of a
+      failed merge.</para>
+
+    &interaction.ch04-resolve.cifail;
+
+    <para id="x_691">When <command role="hg-cmd">hg commit</command> fails in
+      this case, it suggests that we use the unfamiliar <command
+	role="hg-cmd">hg resolve</command> command.  As usual,
+	<command role="hg-cmd">hg help resolve</command> will print a
+      helpful synopsis.</para>
+
+    <sect2>
+      <title>File resolution states</title>
+
+      <para id="x_692">When a merge occurs, most files will usually remain
+	unmodified.  For each file where Mercurial has to do
+	something, it tracks the state of the file.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_693">A <emphasis>resolved</emphasis> file has been
+	    successfully merged, either automatically by Mercurial or
+	    manually with human intervention.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_694">An <emphasis>unresolved</emphasis> file was not merged
+	    successfully, and needs more attention.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_695">If Mercurial sees <emphasis>any</emphasis> file in the
+	unresolved state after a merge, it considers the merge to have
+	failed.  Fortunately, we do not need to restart the entire
+	merge from scratch.</para>
+
+      <para id="x_696">The <option role="hg-opt-resolve">--list</option> or
+	<option role="hg-opt-resolve">-l</option> option to <command
+	  role="hg-cmd">hg resolve</command> prints out the state of
+	each merged file.</para>
+
+      &interaction.ch04-resolve.list;
+
+      <para id="x_697">In the output from <command role="hg-cmd">hg
+	  resolve</command>, a resolved file is marked with
+	<literal>R</literal>, while an unresolved file is marked with
+	<literal>U</literal>.  If any files are listed with
+	<literal>U</literal>, we know that an attempt to commit the
+	results of the merge will fail.</para>
+    </sect2>
+
+    <sect2>
+      <title>Resolving a file merge</title>
+
+      <para id="x_698">We have several options to move a file from the unresolved
+	into the resolved state.  By far the most common is to rerun
+	<command role="hg-cmd">hg resolve</command>.  If we pass the
+	names of individual files or directories, it will retry the
+	merges of any unresolved files present in those locations. We
+	can also pass the <option role="hg-opt-resolve">--all</option>
+	or <option role="hg-opt-resolve">-a</option> option, which
+	will retry the merges of <emphasis>all</emphasis> unresolved
+	files.</para>
+
+      <para id="x_699">Mercurial also lets us modify the resolution state of a
+	file directly.  We can manually mark a file as resolved using
+	the <option role="hg-opt-resolve">--mark</option> option, or
+	as unresolved using the <option
+	  role="hg-opt-resolve">--unmark</option> option.  This allows
+	us to clean up a particularly messy merge by hand, and to keep
+	track of our progress with each file as we go.</para>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch05-collab.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1575 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="cha:collab">
+  <?dbhtml filename="collaborating-with-other-people.html"?>
+  <title>Collaborating with other people</title>
+
+  <para id="x_44a">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.</para>
+
+  <sect1>
+    <title>Mercurial's web interface</title>
+
+    <para id="x_44b">Mercurial has a powerful web interface that provides several
+      useful capabilities.</para>
+
+    <para id="x_44c">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.  You
+      can even get a view of history that gives a graphical view of
+      the relationships between individual changes and merges.</para>
+
+    <para id="x_44d">Also for human consumption, the web interface provides
+      Atom and RSS feeds of the changes in a repository.  This lets you
+      <quote>subscribe</quote> to a repository using your favorite
+      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.</para>
+
+    <para id="x_44e">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.</para>
+
+    <para id="x_44f">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 <ulink
+	url="http://www.selenic.com/repo/hg">http://www.selenic.com/repo/hg</ulink>.</para>
+
+    <para id="x_450">If you're interested in providing a web interface
+      to your own repositories, there are several good ways to do
+      this.</para>
+
+    <para id="x_69d">The easiest and fastest way to get started in an informal
+      environment is to use the <command role="hg-cmd">hg
+	serve</command> command, which is best suited to short-term
+      <quote>lightweight</quote> serving.  See <xref
+	linkend="sec:collab:serve"/> below for details of how to use
+      this command.</para>
+
+    <para id="x_69e">For longer-lived repositories that you'd like to have
+      permanently available, there are several public hosting services
+      available.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para id="x_69f">Bitbucket, at <ulink
+	    url="http://bitbucket.org/">http://bitbucket.org/</ulink>,
+	  provides free hosting for open source projects, and paid
+	  hosting for commercial projects.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_6a0">If you would prefer to host your own repositories, Mercurial
+      has built-in support for several popular hosting technologies,
+      most notably CGI (Common Gateway Interface), and WSGI (Web
+      Services Gateway Interface).  See <xref
+	linkend="sec:collab:cgi"/> for details of CGI and WSGI
+      configuration.</para>
+  </sect1>
+
+  <sect1>
+    <title>Collaboration models</title>
+
+    <para id="x_451">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.</para>
+
+    <sect2>
+      <title>Factors to keep in mind</title>
+
+      <para id="x_452">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.</para>
+
+      <para id="x_453">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.</para>
+
+      <para id="x_454">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.</para>
+    </sect2>
+
+    <sect2>
+      <title>Informal anarchy</title>
+
+      <para id="x_455">I wouldn't suggest an <quote>anything goes</quote>
+	approach as something sustainable, but it's a model that's
+	easy to grasp, and it works perfectly well in a few unusual
+	situations.</para>
+
+      <para id="x_456">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 organizing occasional <quote>sprints</quote>.  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.</para>
+
+      <para id="x_457">A sprint or a hacking session in a coffee shop are the perfect places to use the
+	<command role="hg-cmd">hg serve</command> command, since
+	<command role="hg-cmd">hg serve</command> does not require any
+	fancy server infrastructure.  You can get started with
+	<command role="hg-cmd">hg serve</command> in moments, by
+	reading <xref linkend="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.</para>
+
+      <para id="x_458">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
+	<emphasis>n</emphasis> different repositories to pull
+	from.</para>
+    </sect2>
+
+    <sect2>
+      <title>A single central repository</title>
+
+      <para id="x_459">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 <quote>building block</quote> for
+	more ambitious workflow schemes.</para>
+
+      <para id="x_45a">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.</para>
+
+      <para id="x_45b">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.</para>
+
+      <para id="x_45c">If a team is hosting its own repository in this
+	kind of scenario, people will usually use the
+	<command>ssh</command> protocol to securely push changes to
+	the central repository, as documented in <xref
+	  linkend="sec:collab:ssh"/>.  It's also usual to publish a
+	read-only copy of the repository over HTTP, as in
+	<xref linkend="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.</para>
+    </sect2>
+
+    <sect2>
+      <title>A hosted central repository</title>
+
+      <para id="x_6a1">A wonderful thing about public hosting services like
+	<ulink url="http://bitbucket.org/">Bitbucket</ulink> is that
+	not only do they handle the fiddly server configuration
+	details, such as user accounts, authentication, and secure
+	wire protocols, they provide additional infrastructure to make
+	this model work well.</para>
+
+      <para id="x_6a2">For instance, a well-engineered hosting service will let
+	people clone their own copies of a repository with a single
+	click.  This lets people work in separate spaces and share
+	their changes when they're ready.</para>
+
+      <para id="x_6a3">In addition, a good hosting service will let people
+	communicate with each other, for instance to say <quote>there
+	  are changes ready for you to review in this
+	  tree</quote>.</para>
+    </sect2>
+
+    <sect2>
+      <title>Working with multiple branches</title>
+
+      <para id="x_45d">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
+	<quote>maintenance mode</quote> 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
+	<quote>branch</quote> to refer to one of these many slightly
+	different directions in which development is
+	proceeding.</para>
+
+      <para id="x_45e">Mercurial is particularly well suited to managing a number
+	of simultaneous, but not identical, branches.  Each
+	<quote>development direction</quote> 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 into the stable branch.</para>
+
+      <para id="x_45f">Here's an example of how this can work in practice.  Let's
+	say you have one <quote>main branch</quote> on a central
+	server.</para>
+
+      &interaction.branching.init;
+
+      <para id="x_460">People clone it, make changes locally, test them, and push
+	them back.</para>
+
+      <para id="x_461">Once the main branch reaches a release milestone, you can
+	use the <command role="hg-cmd">hg tag</command> command to
+	give a permanent name to the milestone revision.</para>
+
+	&interaction.branching.tag;
+
+      <para id="x_462">Let's say some ongoing
+	development occurs on the main branch.</para>
+
+      &interaction.branching.main;
+
+      <para id="x_463">Using the tag that was recorded at the milestone, people
+	who clone that repository at any time in the future can use
+	<command role="hg-cmd">hg update</command> to get a copy of
+	the working directory exactly as it was when that tagged
+	revision was committed.</para>
+
+      &interaction.branching.update;
+
+      <para id="x_464">In addition, immediately after the main branch is tagged,
+	we can then clone the main branch on the server to a new
+	<quote>stable</quote> branch, also on the server.</para>
+
+      &interaction.branching.clone;
+
+      <para id="x_465">If we need to make a change to the stable
+	branch, we can then clone <emphasis>that</emphasis>
+	repository, make our changes, commit, and push our changes
+	back there.</para>
+
+      &interaction.branching.stable;
+
+      <para id="x_466">Because Mercurial repositories are independent, and
+	Mercurial doesn't move changes around automatically, the
+	stable and main branches are <emphasis>isolated</emphasis>
+	from each other.  The changes that we made on the main branch
+	don't <quote>leak</quote> to the stable branch, and vice
+	versa.</para>
+
+      <para id="x_467">We'll often want all of our bugfixes on the stable
+	branch to show up on the main branch, too.  Rather than
+	rewrite a bugfix on the main branch, we can simply pull and
+	merge changes from the stable to the main branch, and
+	Mercurial will bring those bugfixes in for us.</para>
+
+      &interaction.branching.merge;
+
+      <para id="x_468">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, since changes are only
+	flowing from the stable to the main branch, and not the other
+	way.</para>
+    </sect2>
+
+    <sect2>
+      <title>Feature branches</title>
+
+      <para id="x_469">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
+	<quote>master</quote> branch used by the entire project.
+	People working on an individual branch are typically quite
+	isolated from developments on other branches.</para>
+
+      <figure id="fig:collab:feature-branches">
+	<title>Feature branches</title>
+	<mediaobject>
+	  <imageobject><imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_46b">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.</para>
+    </sect2>
+
+    <sect2>
+      <title>The release train</title>
+
+      <para id="x_46c">Some projects are organized on a <quote>train</quote>
+	basis: a release is scheduled to happen every few months, and
+	whatever features are ready when the <quote>train</quote> is
+	ready to leave are allowed in.</para>
+
+      <para id="x_46d">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.</para>
+    </sect2>
+
+    <sect2>
+      <title>The Linux kernel model</title>
+
+      <para id="x_46e">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</command>, 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.</para>
+
+      <para id="x_46f">At the center of the community sits Linus Torvalds, the
+	creator of Linux.  He publishes a single source repository
+	that is considered the <quote>authoritative</quote> current
+	tree by the entire developer community. Anyone can clone
+	Linus's tree, but he is very choosy about whose trees he pulls
+	from.</para>
+
+      <para id="x_470">Linus has a number of <quote>trusted lieutenants</quote>.
+	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
+	<quote>maintainers</quote>, 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.</para>
+
+      <para id="x_471">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 <quote>stable</quote>
+	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.</para>
+
+      <para id="x_472">This model has two notable features.  The first is that
+	it's <quote>pull only</quote>.  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.</para>
+
+      <para id="x_473">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 <quote>good</quote>
+	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.</para>
+
+      <para id="x_474">Reputation and acclaim don't necessarily cross subsystem
+	or <quote>people</quote> 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.</para>
+
+      <para id="x_475">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.</para>
+    </sect2>
+
+    <sect2>
+      <title>Pull-only versus shared-push collaboration</title>
+
+      <para id="x_476">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 <quote>better than</quote> one in which
+	multiple people can push changes to a shared
+	repository.</para>
+
+      <para id="x_477">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).</para>
+
+      <para id="x_478">A good distributed revision control tool 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.</para>
+    </sect2>
+    <sect2>
+      <title>Where collaboration meets branch management</title>
+
+      <para id="x_479">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 <xref linkend="chap:branch"/>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>The technical side of sharing</title>
+
+    <para id="x_47a">The remainder of this chapter is devoted to the question of
+      sharing changes with your collaborators.</para>
+  </sect1>
+
+  <sect1 id="sec:collab:serve">
+    <title>Informal sharing with <command role="hg-cmd">hg
+	serve</command></title>
+
+    <para id="x_47b">Mercurial's <command role="hg-cmd">hg serve</command>
+      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.</para>
+
+    <para id="x_47c">Run <command role="hg-cmd">hg serve</command> 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 <command role="hg-cmd">hg serve</command> instance running
+      on a laptop is likely to look something like
+      <literal>http://my-laptop.local:8000/</literal>.</para>
+
+    <para id="x_47d">The <command role="hg-cmd">hg serve</command> command is
+      <emphasis>not</emphasis> a general-purpose web server. It can do
+      only two things:</para>
+    <itemizedlist>
+      <listitem><para id="x_47e">Allow people to browse the history of the
+	  repository it's serving, from their normal web
+	  browsers.</para>
+      </listitem>
+      <listitem><para id="x_47f">Speak Mercurial's wire protocol, so that people
+	  can <command role="hg-cmd">hg clone</command> or <command
+	    role="hg-cmd">hg pull</command> changes from that
+	  repository.</para>
+      </listitem></itemizedlist>
+    <para id="x_480">In particular, <command role="hg-cmd">hg serve</command>
+      won't allow remote users to <emphasis>modify</emphasis> your
+      repository.  It's intended for read-only use.</para>
+
+    <para id="x_481">If you're getting started with Mercurial, there's nothing to
+      prevent you from using <command role="hg-cmd">hg serve</command>
+      to serve up a repository on your own computer, then use commands
+      like <command role="hg-cmd">hg clone</command>, <command
+	role="hg-cmd">hg incoming</command>, 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.</para>
+
+    <sect2>
+      <title>A few things to keep in mind</title>
+
+      <para id="x_482">Because it provides unauthenticated read access to all
+	clients, you should only use <command role="hg-cmd">hg
+	  serve</command> 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.</para>
+
+      <para id="x_483">The <command role="hg-cmd">hg serve</command> 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 <command role="hg-cmd">hg serve</command>
+	instance, the second thing you should do
+	(<emphasis>after</emphasis> you make sure that they're using
+	the correct URL) is check your firewall configuration.</para>
+
+      <para id="x_484">By default, <command role="hg-cmd">hg serve</command>
+	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 <option
+	  role="hg-opt-serve">-p</option> option.</para>
+
+      <para id="x_485">Normally, when <command role="hg-cmd">hg serve</command>
+	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 <option role="hg-opt-global">-v</option>
+	option.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:collab:ssh">
+    <title>Using the Secure Shell (ssh) protocol</title>
+
+    <para id="x_486">You can pull and push changes securely over a network
+      connection using the Secure Shell (<literal>ssh</literal>)
+      protocol.  To use this successfully, you may have to do a little
+      bit of configuration on the client or server sides.</para>
+
+    <para id="x_487">If you're not familiar with ssh, it's the name of
+      both a command and a network protocol that let 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.</para>
+
+    <para id="x_488">(If you <emphasis>are</emphasis> familiar with ssh, you'll
+      probably find some of the material that follows to be elementary
+      in nature.)</para>
+
+    <sect2>
+      <title>How to read and write ssh URLs</title>
+
+      <para id="x_489">An ssh URL tends to look like this:</para>
+      <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting>
+      <orderedlist>
+	<listitem><para id="x_48a">The <quote><literal>ssh://</literal></quote>
+	    part tells Mercurial to use the ssh protocol.</para>
+	</listitem>
+	<listitem><para id="x_48b">The <quote><literal>bos@</literal></quote>
+	    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.</para>
+	</listitem>
+	<listitem><para id="x_48c">The
+	    <quote><literal>hg.serpentine.com</literal></quote> gives
+	    the hostname of the server to log into.</para>
+	</listitem>
+	<listitem><para id="x_48d">The <quote>:22</quote> identifies the port
+	    number to connect to the server on.  The default port is
+	    22, so you only need to specify a colon and port number if
+	    you're <emphasis>not</emphasis> using port 22.</para>
+	</listitem>
+	<listitem><para id="x_48e">The remainder of the URL is the local path to
+	    the repository on the server.</para>
+	</listitem></orderedlist>
+
+      <para id="x_48f">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.</para>
+
+      <para id="x_490">Mercurial treats the path to a repository on the server as
+	relative to the remote user's home directory.  For example, if
+	user <literal>foo</literal> on the server has a home directory
+	of <filename class="directory">/home/foo</filename>, then an
+	ssh URL that contains a path component of <filename
+	  class="directory">bar</filename> <emphasis>really</emphasis>
+	refers to the directory <filename
+	  class="directory">/home/foo/bar</filename>.</para>
+
+      <para id="x_491">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
+	<literal>otheruser</literal>), like this.</para>
+      <programlisting>ssh://server/~otheruser/hg/repo</programlisting>
+
+      <para id="x_492">And if you really want to specify an
+	<emphasis>absolute</emphasis> path on the server, begin the
+	path component with two slashes, as in this example.</para>
+      <programlisting>ssh://server//absolute/path</programlisting>
+    </sect2>
+
+    <sect2>
+      <title>Finding an ssh client for your system</title>
+
+      <para id="x_493">Almost every Unix-like system comes with OpenSSH
+	preinstalled.  If you're using such a system, run
+	<literal>which ssh</literal> to find out if the
+	<command>ssh</command> command is installed (it's usually in
+	<filename class="directory">/usr/bin</filename>).  In the
+	unlikely event that it isn't present, take a look at your
+	system documentation to figure out how to install it.</para>
+
+      <para id="x_494">On Windows, the TortoiseHg package is bundled
+	with a version of Simon Tatham's excellent
+	<command>plink</command> command, and you should not need to
+	do any further configuration.</para>
+    </sect2>
+
+    <sect2>
+      <title>Generating a key pair</title>
+
+      <para id="x_499">To avoid the need to repetitively type a
+	password every time you need to use your ssh client, I
+	recommend generating a key pair.</para>
+
+      <tip>
+	<title>Key pairs are not mandatory</title>
+
+	<para id="x_6a4">Mercurial knows nothing about ssh authentication or key
+	  pairs.  You can, if you like, safely ignore this section and
+	  the one that follows until you grow tired of repeatedly
+	  typing ssh passwords.</para>
+      </tip>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_6a5">On a Unix-like system, the
+	    <command>ssh-keygen</command> command will do the
+	    trick.</para>
+	  <para id="x_6a6">On Windows, if you're using TortoiseHg, you may need
+	    to download a command named <command>puttygen</command>
+	    from <ulink
+	      url="http://www.chiark.greenend.org.uk/~sgtatham/putty">the 
+	      PuTTY web site</ulink> to generate a key pair.  See
+	    <ulink
+	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">the 
+	      <command>puttygen</command> documentation</ulink> for
+	    details of how use the command.</para>
+	</listitem>
+      </itemizedlist>
+
+      <para id="x_49a">When you generate a key pair, it's usually
+	<emphasis>highly</emphasis> 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.)</para>
+
+      <para id="x_49b">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 <filename
+	  role="special">authorized_keys</filename> in their <filename
+	  role="special" class="directory">.ssh</filename>
+	directory.</para>
+
+      <para id="x_49c">On a Unix-like system, your public key will have a
+	<filename>.pub</filename> extension.  If you're using
+	<command>puttygen</command> 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 <filename
+	  role="special">authorized_keys</filename> file.</para>
+    </sect2>
+    <sect2>
+      <title>Using an authentication agent</title>
+
+      <para id="x_49d">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).</para>
+
+      <para id="x_49e">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.</para>
+
+      <itemizedlist>
+	<listitem>
+	  <para id="x_49f">On Unix-like systems, the agent is called
+	    <command>ssh-agent</command>, and it's often run
+	    automatically for you when you log in.  You'll need to use
+	    the <command>ssh-add</command> command to add passphrases
+	    to the agent's store.</para>
+	</listitem>
+	<listitem>
+	  <para id="x_6a7">On Windows, if you're using TortoiseHg, the
+	    <command>pageant</command> command acts as the agent.  As
+	    with <command>puttygen</command>, you'll need to <ulink
+	      url="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/download.html">download 
+	      <command>pageant</command></ulink> from the PuTTY web
+	    site and read <ulink
+	      url="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant">its 
+	      documentation</ulink>.  The <command>pageant</command>
+	    command adds an icon to your system tray that will let you
+	    manage stored passphrases.</para>
+	</listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2>
+      <title>Configuring the server side properly</title>
+
+      <para id="x_4a0">Because ssh can be fiddly to set up if you're new to it,
+	a variety of things 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.</para>
+
+      <para id="x_4a1">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</command> or <command>putty</command> 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,
+	<emphasis>before</emphasis> you worry about whether there's a
+	problem with Mercurial.</para>
+
+      <para id="x_4a2">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</command> or <command>putty</command>
+	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.</para>
+      <itemizedlist>
+	<listitem><para id="x_4a3">If you get a <quote>connection refused</quote>
+	    error, either there isn't an SSH daemon running on the
+	    server at all, or it's inaccessible due to firewall
+	    configuration.</para>
+	</listitem>
+	<listitem><para id="x_4a4">If you get a <quote>no route to host</quote>
+	    error, you either have an incorrect address for the server
+	    or a seriously locked down firewall that won't admit its
+	    existence at all.</para>
+	</listitem>
+	<listitem><para id="x_4a5">If you get a <quote>permission denied</quote>
+	    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.</para>
+	</listitem></itemizedlist>
+      <para id="x_4a6">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.</para>
+
+      <para id="x_4a7">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.</para>
+      <itemizedlist>
+	<listitem><para id="x_4a8">You might have forgotten to use
+	    <command>ssh-add</command> or <command>pageant</command>
+	    to store the passphrase.</para>
+	</listitem>
+	<listitem><para id="x_4a9">You might have stored the passphrase for the
+	    wrong key.</para>
+	</listitem></itemizedlist>
+      <para id="x_4aa">If you're being prompted for the remote user's password,
+	there are another few possible problems to check.</para>
+      <itemizedlist>
+	<listitem><para id="x_4ab">Either the user's home directory or their
+	    <filename role="special" class="directory">.ssh</filename>
+	    directory might have excessively liberal permissions.  As
+	    a result, the ssh daemon will not trust or read their
+	    <filename role="special">authorized_keys</filename> file.
+	    For example, a group-writable home or <filename
+	      role="special" class="directory">.ssh</filename>
+	    directory will often cause this symptom.</para>
+	</listitem>
+	<listitem><para id="x_4ac">The user's <filename
+	      role="special">authorized_keys</filename> 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.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_4ad">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.</para>
+      <programlisting>ssh myserver date</programlisting>
+
+      <para id="x_4ae">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</command> 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
+	<literal>tty -s</literal>.)</para>
+
+      <para id="x_4af">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:</para>
+
+      <programlisting>ssh myserver hg version</programlisting>
+
+      <para id="x_4b0">If you see an error message instead of normal <command
+	  role="hg-cmd">hg version</command> output, this is usually
+	because you haven't installed Mercurial to <filename
+	  class="directory">/usr/bin</filename>.  Don't worry if this
+	is the case; you don't need to do that.  But you should check
+	for a few possible problems.</para>
+      <itemizedlist>
+	<listitem><para id="x_4b1">Is Mercurial really installed on the server at
+	    all?  I know this sounds trivial, but it's worth
+	    checking!</para>
+	</listitem>
+	<listitem><para id="x_4b2">Maybe your shell's search path (usually set
+	    via the <envar>PATH</envar> environment variable) is
+	    simply misconfigured.</para>
+	</listitem>
+	<listitem><para id="x_4b3">Perhaps your <envar>PATH</envar> environment
+	    variable is only being set to point to the location of the
+	    <command>hg</command> 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.</para>
+	</listitem>
+	<listitem><para id="x_4b4">The <envar>PYTHONPATH</envar> 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.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_4b5">If you can run <command role="hg-cmd">hg version</command>
+	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 <option role="hg-opt-global">--debug</option>
+	option to get a clearer picture of what's going on.</para>
+    </sect2>
+    <sect2>
+      <title>Using compression with ssh</title>
+
+      <para id="x_4b6">Mercurial does not compress data when it uses the ssh
+	protocol, because the ssh protocol can transparently compress
+	data.  However, the default behavior of ssh clients is
+	<emphasis>not</emphasis> to request compression.</para>
+
+      <para id="x_4b7">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.</para>
+
+      <para id="x_4b8">Both <command>ssh</command> and <command>plink</command>
+	accept a <option role="cmd-opt-ssh">-C</option> option which
+	turns on compression.  You can easily edit your <filename
+	  role="special">~/.hgrc</filename> to enable compression for
+	all of Mercurial's uses of the ssh protocol.  Here is how to
+	do so for regular <command>ssh</command> on Unix-like systems,
+	for example.</para>
+      <programlisting>[ui]
+ssh = ssh -C</programlisting>
+
+      <para id="x_4b9">If you use <command>ssh</command> on a
+	Unix-like system, you can configure it to always use
+	compression when talking to your server.  To do this, edit
+	your <filename role="special">.ssh/config</filename> file
+	(which may not yet exist), as follows.</para>
+
+      <programlisting>Host hg
+  Compression yes
+  HostName hg.example.com</programlisting>
+
+      <para id="x_4ba">This defines a hostname alias,
+	<literal>hg</literal>.  When you use that hostname on the
+	<command>ssh</command> command line or in a Mercurial
+	<literal>ssh</literal>-protocol URL, it will cause
+	<command>ssh</command> to connect to
+	<literal>hg.example.com</literal> 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.</para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="sec:collab:cgi">
+    <title>Serving over HTTP using CGI</title>
+
+    <para id="x_6a8">The simplest way to host one or more repositories in a
+      permanent way is to use a web server and Mercurial's CGI
+      support.</para>
+
+    <para id="x_4bb">Depending on how ambitious you are, configuring Mercurial's
+      CGI interface can take anything from a few moments to several
+      hours.</para>
+
+    <para id="x_4bc">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.</para>
+
+    <note>
+      <title>High pain tolerance required</title>
+
+      <para id="x_4bd">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.</para>
+
+      <para id="x_6a9">If you don't have a strong stomach for tweaking
+	configurations over and over, or a compelling need to host
+	your own services, you might want to try one of the public
+	hosting services that I mentioned earlier.</para>
+    </note>
+
+    <sect2>
+      <title>Web server configuration checklist</title>
+
+      <para id="x_4be">Before you continue, do take a few moments to check a few
+	aspects of your system's setup.</para>
+
+      <orderedlist>
+	<listitem><para id="x_4bf">Do you have a web server installed
+	    at all? Mac OS X and some Linux distributions ship with
+	    Apache, but many other systems may not have a web server
+	    installed.</para>
+	</listitem>
+	<listitem><para id="x_4c0">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.</para>
+	</listitem>
+	<listitem><para id="x_4c1">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.</para>
+	</listitem></orderedlist>
+
+      <para id="x_4c2">If you don't have a web server installed, and don't have
+	substantial experience configuring Apache, you should consider
+	using the <literal>lighttpd</literal> web server instead of
+	Apache.  Apache has a well-deserved reputation for baroque and
+	confusing configuration. While <literal>lighttpd</literal> is
+	less capable in some ways than Apache, most of these
+	capabilities are not relevant to serving Mercurial
+	repositories.  And <literal>lighttpd</literal> is undeniably
+	<emphasis>much</emphasis> easier to get started with than
+	Apache.</para>
+    </sect2>
+
+    <sect2>
+      <title>Basic CGI configuration</title>
+
+      <para id="x_4c3">On Unix-like systems, it's common for users to have a
+	subdirectory named something like <filename
+	  class="directory">public_html</filename> in their home
+	directory, from which they can serve up web pages.  A file
+	named <filename>foo</filename> in this directory will be
+	accessible at a URL of the form
+	<literal>http://www.example.com/username/foo</literal>.</para>
+
+      <para id="x_4c4">To get started, find the <filename
+	  role="special">hgweb.cgi</filename> 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 <ulink
+	  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>
+
+      <para id="x_4c5">You'll need to copy this script into your <filename
+	  class="directory">public_html</filename> directory, and
+	ensure that it's executable.</para>
+      <programlisting>cp .../hgweb.cgi ~/public_html
+chmod 755 ~/public_html/hgweb.cgi</programlisting>
+      <para id="x_4c6">The <literal>755</literal> argument to
+	<command>chmod</command> is a little more general than just
+	making the script executable: it ensures that the script is
+	executable by anyone, and that <quote>group</quote> and
+	<quote>other</quote> write permissions are
+	<emphasis>not</emphasis> set.  If you were to leave those
+	write permissions enabled, Apache's <literal>suexec</literal>
+	subsystem would likely refuse to execute the script.  In fact,
+	<literal>suexec</literal> also insists that the
+	<emphasis>directory</emphasis> in which the script resides
+	must not be writable by others.</para>
+      <programlisting>chmod 755 ~/public_html</programlisting>
+
+      <sect3 id="sec:collab:wtf">
+	<title>What could <emphasis>possibly</emphasis> go
+	  wrong?</title>
+
+	<para id="x_4c7">Once you've copied the CGI script into place, go into a
+	  web browser, and try to open the URL <ulink
+	    url="http://myhostname/
+	    myuser/hgweb.cgi">http://myhostname/
+	    myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> 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.</para>
+
+	<para id="x_4c8">Your web server may have per-user directories disabled.
+	  If you're using Apache, search your config file for a
+	  <literal>UserDir</literal> directive.  If there's none
+	  present, per-user directories will be disabled.  If one
+	  exists, but its value is <literal>disabled</literal>, then
+	  per-user directories will be disabled.  Otherwise, the
+	  string after <literal>UserDir</literal> gives the name of
+	  the subdirectory that Apache will look in under your home
+	  directory, for example <filename
+	    class="directory">public_html</filename>.</para>
+
+	<para id="x_4c9">Your file access permissions may be too restrictive.
+	  The web server must be able to traverse your home directory
+	  and directories under your <filename
+	    class="directory">public_html</filename> directory, and
+	  read files under the latter too.  Here's a quick recipe to
+	  help you to make your permissions more appropriate.</para>
+	<programlisting>chmod 755 ~
+find ~/public_html -type d -print0 | xargs -0r chmod 755
+find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting>
+
+	<para id="x_4ca">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 <emphasis>too permissive</emphasis>.  Apache's
+	  <literal>suexec</literal> subsystem won't execute a script
+	  that's group- or world-writable, for example.</para>
+
+	<para id="x_4cb">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.</para>
+
+	&ch06-apache-config.lst;
+
+	<para id="x_4cc">If you find a similar-looking
+	  <literal>Directory</literal> group in your Apache
+	  configuration, the directive to look at inside it is
+	  <literal>Options</literal>. Add <literal>ExecCGI</literal>
+	  to the end of this list if it's missing, and restart the web
+	  server.</para>
+
+	<para id="x_4cd">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.</para>
+	<programlisting>AddHandler cgi-script .cgi</programlisting>
+
+	<para id="x_4ce">The next possibility is that you might be served with a
+	  colourful Python backtrace claiming that it can't import a
+	  <literal>mercurial</literal>-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 <filename
+	    role="special">hgweb.cgi</filename> and follow the
+	  directions inside it to correctly set your
+	  <envar>PYTHONPATH</envar> environment variable.</para>
+
+	<para id="x_4cf">Finally, you are <emphasis>certain</emphasis> to by
+	  served with another colourful Python backtrace: this one
+	  will complain that it can't find <filename
+	    class="directory">/path/to/repository</filename>.  Edit
+	  your <filename role="special">hgweb.cgi</filename> script
+	  and replace the <filename
+	    class="directory">/path/to/repository</filename> string
+	  with the complete path to the repository you want to serve
+	  up.</para>
+
+	<para id="x_4d0">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!</para>
+      </sect3>
+
+      <sect3>
+	<title>Configuring lighttpd</title>
+
+	<para id="x_4d1">To be exhaustive in my experiments, I tried configuring
+	  the increasingly popular <literal>lighttpd</literal> 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 <filename
+	    role="special">hgweb.cgi</filename> script was properly
+	  edited.</para>
+
+	<para id="x_4d2">Once I had Apache running, getting
+	  <literal>lighttpd</literal> to serve the repository was a
+	  snap (in other words, even if you're trying to use
+	  <literal>lighttpd</literal>, you should read the Apache
+	  section).  I first had to edit the
+	  <literal>mod_access</literal> section of its config file to
+	  enable <literal>mod_cgi</literal> and
+	  <literal>mod_userdir</literal>, 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.</para>
+	<programlisting>userdir.path = "public_html"
+cgi.assign = (".cgi" =&gt; "" )</programlisting>
+	<para id="x_4d3">With this done, <literal>lighttpd</literal> ran
+	  immediately for me.  If I had configured
+	  <literal>lighttpd</literal> 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 <literal>lighttpd</literal> 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
+	  <literal>lighttpd</literal>.</para>
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Sharing multiple repositories with one CGI script</title>
+
+      <para id="x_4d4">The <filename role="special">hgweb.cgi</filename> 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 <filename role="special">hgwebdir.cgi</filename>
+	script.</para>
+
+      <para id="x_4d5">The procedure to configure <filename
+	  role="special">hgwebdir.cgi</filename> is only a little more
+	involved than for <filename
+	  role="special">hgweb.cgi</filename>.  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 <ulink
+	  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>
+
+      <para id="x_4d6">You'll need to copy this script into your <filename
+	  class="directory">public_html</filename> directory, and
+	ensure that it's executable.</para>
+
+      <programlisting>cp .../hgwebdir.cgi ~/public_html
+chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting>
+
+      <para id="x_4d7">With basic configuration out of the way, try to
+	visit <ulink url="http://myhostname/
+	  myuser/hgwebdir.cgi">http://myhostname/
+	  myuser/hgwebdir.cgi</ulink> 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 <xref
+	  linkend="sec:collab:wtf"/>.</para>
+
+      <para id="x_4d8">The <filename role="special">hgwebdir.cgi</filename>
+	script relies on an external configuration file.  By default,
+	it searches for a file named <filename
+	  role="special">hgweb.config</filename> 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 <quote>ini</quote> file, as understood by Python's
+	<literal>ConfigParser</literal>
+	<citation>web:configparser</citation> module.</para>
+
+      <para id="x_4d9">The easiest way to configure <filename
+	  role="special">hgwebdir.cgi</filename> is with a section
+	named <literal>collections</literal>.  This will automatically
+	publish <emphasis>every</emphasis> repository under the
+	directories you name.  The section should look like
+	this:</para>
+      <programlisting>[collections]
+/my/root = /my/root</programlisting>
+      <para id="x_4da">Mercurial interprets this by looking at the directory name
+	on the <emphasis>right</emphasis> hand side of the
+	<quote><literal>=</literal></quote> sign; finding repositories
+	in that directory hierarchy; and using the text on the
+	<emphasis>left</emphasis> 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 <quote>virtual path</quote>.</para>
+
+      <para id="x_4db">Given the example above, if we have a repository whose
+	local path is <filename
+	  class="directory">/my/root/this/repo</filename>, the CGI
+	script will strip the leading <filename
+	  class="directory">/my/root</filename> from the name, and
+	publish the repository with a virtual path of <filename
+	  class="directory">this/repo</filename>.  If the base URL for
+	our CGI script is <ulink url="http://myhostname/
+	  myuser/hgwebdir.cgi">http://myhostname/
+	  myuser/hgwebdir.cgi</ulink>, the complete URL for that
+	repository will be <ulink url="http://myhostname/
+	  myuser/hgwebdir.cgi/this/repo">http://myhostname/
+	  myuser/hgwebdir.cgi/this/repo</ulink>.</para>
+
+      <para id="x_4dc">If we replace <filename
+	  class="directory">/my/root</filename> on the left hand side
+	of this example with <filename
+	  class="directory">/my</filename>, then <filename
+	  role="special">hgwebdir.cgi</filename> will only strip off
+	<filename class="directory">/my</filename> from the repository
+	name, and will give us a virtual path of <filename
+	  class="directory">root/this/repo</filename> instead of
+	<filename class="directory">this/repo</filename>.</para>
+
+      <para id="x_4dd">The <filename role="special">hgwebdir.cgi</filename>
+	script will recursively search each directory listed in the
+	<literal>collections</literal> section of its configuration
+	file, but it will <literal>not</literal> recurse into the
+	repositories it finds.</para>
+
+      <para id="x_4de">The <literal>collections</literal> mechanism makes it easy
+	to publish many repositories in a <quote>fire and
+	  forget</quote> manner.  You only need to set up the CGI
+	script and configuration file one time.  Afterwards, you can
+	publish or unpublish a repository at any time by simply moving
+	it into, or out of, the directory hierarchy in which you've
+	configured <filename role="special">hgwebdir.cgi</filename> to
+	look.</para>
+
+      <sect3>
+	<title>Explicitly specifying which repositories to
+	  publish</title>
+
+	<para id="x_4df">In addition to the <literal>collections</literal>
+	  mechanism, the <filename
+	    role="special">hgwebdir.cgi</filename> script allows you
+	  to publish a specific list of repositories.  To do so,
+	  create a <literal>paths</literal> section, with contents of
+	  the following form.</para>
+	<programlisting>[paths]
+repo1 = /my/path/to/some/repo
+repo2 = /some/path/to/another</programlisting>
+	<para id="x_4e0">In this case, the virtual path (the component that will
+	  appear in a URL) is on the left hand side of each
+	  definition, while the path to the repository is on the
+	  right.  Notice that there does not need to be any
+	  relationship between the virtual path you choose and the
+	  location of a repository in your filesystem.</para>
+
+	<para id="x_4e1">If you wish, you can use both the
+	  <literal>collections</literal> and <literal>paths</literal>
+	  mechanisms simultaneously in a single configuration
+	  file.</para>
+
+	<note>
+	  <title>Beware duplicate virtual paths</title>
+
+	  <para id="x_4e2">  If several repositories have the same
+	    virtual path, <filename
+	      role="special">hgwebdir.cgi</filename> will not report
+	    an error.  Instead, it will behave unpredictably.</para>
+	</note>
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Downloading source archives</title>
+
+      <para id="x_4e3">Mercurial's web interface lets users download an archive
+	of any revision.  This archive will contain a snapshot of the
+	working directory as of that revision, but it will not contain
+	a copy of the repository data.</para>
+
+      <para id="x_4e4">By default, this feature is not enabled.  To enable it,
+	you'll need to add an <envar
+	  role="rc-item-web">allow_archive</envar> item to the
+	<literal role="rc-web">web</literal> section of your <filename
+	  role="special">~/.hgrc</filename>; see below for details.</para>
+    </sect2>
+    <sect2>
+      <title>Web configuration options</title>
+
+      <para id="x_4e5">Mercurial's web interfaces (the <command role="hg-cmd">hg
+	  serve</command> command, and the <filename
+	  role="special">hgweb.cgi</filename> and <filename
+	  role="special">hgwebdir.cgi</filename> scripts) have a
+	number of configuration options that you can set.  These
+	belong in a section named <literal
+	  role="rc-web">web</literal>.</para>
+      <itemizedlist>
+	<listitem><para id="x_4e6"><envar
+	      role="rc-item-web">allow_archive</envar>: Determines
+	    which (if any) archive download mechanisms Mercurial
+	    supports.  If you enable this feature, users of the web
+	    interface will be able to download an archive of whatever
+	    revision of a repository they are viewing. To enable the
+	    archive feature, this item must take the form of a
+	    sequence of words drawn from the list below.</para>
+	  <itemizedlist>
+	    <listitem><para id="x_4e7"><literal>bz2</literal>: A
+		<command>tar</command> archive, compressed using
+		<literal>bzip2</literal> compression.  This has the
+		best compression ratio, but uses the most CPU time on
+		the server.</para>
+	    </listitem>
+	    <listitem><para id="x_4e8"><literal>gz</literal>: A
+		<command>tar</command> archive, compressed using
+		<literal>gzip</literal> compression.</para>
+	    </listitem>
+	    <listitem><para id="x_4e9"><literal>zip</literal>: A
+		<command>zip</command> archive, compressed using LZW
+		compression.  This format has the worst compression
+		ratio, but is widely used in the Windows world.</para>
+	    </listitem>
+	  </itemizedlist>
+	  <para id="x_4ea">  If you provide an empty list, or don't have an
+	    <envar role="rc-item-web">allow_archive</envar> entry at
+	    all, this feature will be disabled.  Here is an example of
+	    how to enable all three supported formats.</para>
+	  <programlisting>[web]
+allow_archive = bz2 gz zip</programlisting>
+	</listitem>
+	<listitem><para id="x_4eb"><envar role="rc-item-web">allowpull</envar>:
+	    Boolean.  Determines whether the web interface allows
+	    remote users to <command role="hg-cmd">hg pull</command>
+	    and <command role="hg-cmd">hg clone</command> this
+	    repository over HTTP.  If set to <literal>no</literal> or
+	    <literal>false</literal>, only the
+	    <quote>human-oriented</quote> portion of the web interface
+	    is available.</para>
+	</listitem>
+	<listitem><para id="x_4ec"><envar role="rc-item-web">contact</envar>:
+	    String.  A free-form (but preferably brief) string
+	    identifying the person or group in charge of the
+	    repository.  This often contains the name and email
+	    address of a person or mailing list.  It often makes sense
+	    to place this entry in a repository's own <filename
+	      role="special">.hg/hgrc</filename> file, but it can make
+	    sense to use in a global <filename
+	      role="special">~/.hgrc</filename> if every repository
+	    has a single maintainer.</para>
+	</listitem>
+	<listitem><para id="x_4ed"><envar role="rc-item-web">maxchanges</envar>:
+	    Integer.  The default maximum number of changesets to
+	    display in a single page of output.</para>
+	</listitem>
+	<listitem><para id="x_4ee"><envar role="rc-item-web">maxfiles</envar>:
+	    Integer.  The default maximum number of modified files to
+	    display in a single page of output.</para>
+	</listitem>
+	<listitem><para id="x_4ef"><envar role="rc-item-web">stripes</envar>:
+	    Integer.  If the web interface displays alternating
+	    <quote>stripes</quote> to make it easier to visually align
+	    rows when you are looking at a table, this number controls
+	    the number of rows in each stripe.</para>
+	</listitem>
+	<listitem><para id="x_4f0"><envar
+	      role="rc-item-web">style</envar>: Controls the template
+	    Mercurial uses to display the web interface.  Mercurial
+	    ships with several web templates.</para>
+	  <itemizedlist>
+	    <listitem>
+	      <para id="x_6aa"><literal>coal</literal> is monochromatic.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ab"><literal>gitweb</literal> emulates the visual
+		style of git's web interface.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ac"><literal>monoblue</literal> uses solid blues and
+		greys.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ad"><literal>paper</literal> is the default.</para>
+	    </listitem>
+	    <listitem>
+	      <para id="x_6ae"><literal>spartan</literal> was the default for a
+		long time.</para>
+	    </listitem>
+	  </itemizedlist>
+	  <para id="x_6af">You can
+	    also specify a custom template of your own; see 
+	    <xref linkend="chap:template"/> for details. Here, you can
+	    see how to enable the <literal>gitweb</literal>
+	    style.</para>
+	  <programlisting>[web]
+style = gitweb</programlisting>
+	</listitem>
+	<listitem><para id="x_4f1"><envar role="rc-item-web">templates</envar>:
+	    Path.  The directory in which to search for template
+	    files.  By default, Mercurial searches in the directory in
+	    which it was installed.</para>
+	</listitem></itemizedlist>
+      <para id="x_4f2">If you are using <filename
+	  role="special">hgwebdir.cgi</filename>, you can place a few
+	configuration items in a <literal role="rc-web">web</literal>
+	section of the <filename
+	  role="special">hgweb.config</filename> file instead of a
+	<filename role="special">~/.hgrc</filename> file, for
+	convenience.  These items are <envar
+	  role="rc-item-web">motd</envar> and <envar
+	  role="rc-item-web">style</envar>.</para>
+
+      <sect3>
+	<title>Options specific to an individual repository</title>
+
+	<para id="x_4f3">A few <literal role="rc-web">web</literal> configuration
+	  items ought to be placed in a repository's local <filename
+	    role="special">.hg/hgrc</filename>, rather than a user's
+	  or global <filename role="special">~/.hgrc</filename>.</para>
+	<itemizedlist>
+	  <listitem><para id="x_4f4"><envar
+		role="rc-item-web">description</envar>: String.  A
+	      free-form (but preferably brief) string that describes
+	      the contents or purpose of the repository.</para>
+	  </listitem>
+	  <listitem><para id="x_4f5"><envar role="rc-item-web">name</envar>:
+	      String.  The name to use for the repository in the web
+	      interface.  This overrides the default name, which is
+	      the last component of the repository's path.</para>
+	  </listitem></itemizedlist>
+      </sect3>
+
+      <sect3>
+	<title>Options specific to the <command role="hg-cmd">hg
+	    serve</command> command</title>
+
+	<para id="x_4f6">Some of the items in the <literal
+	    role="rc-web">web</literal> section of a <filename
+	    role="special">~/.hgrc</filename> file are only for use
+	  with the <command role="hg-cmd">hg serve</command>
+	  command.</para>
+	<itemizedlist>
+	  <listitem><para id="x_4f7"><envar role="rc-item-web">accesslog</envar>:
+	      Path.  The name of a file into which to write an access
+	      log.  By default, the <command role="hg-cmd">hg
+		serve</command> command writes this information to
+	      standard output, not to a file.  Log entries are written
+	      in the standard <quote>combined</quote> file format used
+	      by almost all web servers.</para>
+	  </listitem>
+	  <listitem><para id="x_4f8"><envar role="rc-item-web">address</envar>:
+	      String.  The local address on which the server should
+	      listen for incoming connections.  By default, the server
+	      listens on all addresses.</para>
+	  </listitem>
+	  <listitem><para id="x_4f9"><envar role="rc-item-web">errorlog</envar>:
+	      Path.  The name of a file into which to write an error
+	      log.  By default, the <command role="hg-cmd">hg
+		serve</command> command writes this information to
+	      standard error, not to a file.</para>
+	  </listitem>
+	  <listitem><para id="x_4fa"><envar role="rc-item-web">ipv6</envar>:
+	      Boolean.  Whether to use the IPv6 protocol. By default,
+	      IPv6 is not used.</para>
+	  </listitem>
+	  <listitem><para id="x_4fb"><envar role="rc-item-web">port</envar>:
+	      Integer.  The TCP port number on which the server should
+	      listen.  The default port number used is 8000.</para>
+	  </listitem></itemizedlist>
+      </sect3>
+
+      <sect3>
+	<title>Choosing the right <filename
+	    role="special">~/.hgrc</filename> file to add <literal
+	    role="rc-web">web</literal> items to</title>
+
+	<para id="x_4fc">It is important to remember that a web server like
+	  Apache or <literal>lighttpd</literal> will run under a user
+	  ID that is different to yours. CGI scripts run by your
+	  server, such as <filename
+	    role="special">hgweb.cgi</filename>, will usually also run
+	  under that user ID.</para>
+
+	<para id="x_4fd">If you add <literal role="rc-web">web</literal> items to
+	  your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that
+	  <filename role="special">~/.hgrc</filename> file.  Those
+	  settings will thus only affect the behavior of the <command
+	    role="hg-cmd">hg serve</command> command when you run it.
+	  To cause CGI scripts to see your settings, either create a
+	  <filename role="special">~/.hgrc</filename> file in the
+	  home directory of the user ID that runs your web server, or
+	  add those settings to a system-wide <filename
+	    role="special">hgrc</filename> file.</para>
+      </sect3>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>System-wide configuration</title>
+
+    <para id="x_6b0">On Unix-like systems shared by multiple users (such as a
+      server to which people publish changes), it often makes sense to
+      set up some global default behaviors, such as what theme to use
+      in web interfaces.</para>
+
+    <para id="x_6b1">If a file named <filename>/etc/mercurial/hgrc</filename>
+      exists, Mercurial will read it at startup time and apply any
+      configuration settings it finds in that file.  It will also look
+      for files ending in a <literal>.rc</literal> extension in a
+      directory named <filename>/etc/mercurial/hgrc.d</filename>, and
+      apply any configuration settings it finds in each of those
+      files.</para>
+
+    <sect2>
+      <title>Making Mercurial more trusting</title>
+
+      <para id="x_6b2">One situation in which a global <filename>hgrc</filename>
+	can be useful is if users are pulling changes owned by other
+	users.  By default, Mercurial will not trust most of the
+	configuration items in a <filename>.hg/hgrc</filename> file
+	inside a repository that is owned by a different user. If we
+	clone or pull changes from such a repository, Mercurial will
+	print a warning stating that it does not trust their
+	<filename>.hg/hgrc</filename>.</para>
+
+      <para id="x_6b3">If everyone in a particular Unix group is on the same team
+	and <emphasis>should</emphasis> trust each other's
+	configuration settings, or we want to trust particular users,
+	we can override Mercurial's skeptical defaults by creating a
+	system-wide <filename>hgrc</filename> file such as the
+	following:</para>
+
+    <programlisting># Save this as e.g. /etc/mercurial/hgrc.d/trust.rc
+[trusted]
+# Trust all entries in any hgrc file owned by the "editors" or
+# "www-data" groups.
+groups = editors, www-data
+
+# Trust entries in hgrc files owned by the following users.
+users = apache, bobo
+</programlisting>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch06-filenames.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,450 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:names">
+  <?dbhtml filename="file-names-and-pattern-matching.html"?>
+  <title>File names and pattern matching</title>
+
+  <para id="x_543">Mercurial provides mechanisms that let you work with file
+    names in a consistent and expressive way.</para>
+
+  <sect1>
+    <title>Simple file naming</title>
+
+    <para id="x_544">Mercurial uses a unified piece of machinery <quote>under the
+	hood</quote> to handle file names.  Every command behaves
+      uniformly with respect to file names.  The way in which commands
+      work with file names is as follows.</para>
+
+    <para id="x_545">If you explicitly name real files on the command line,
+      Mercurial works with exactly those files, as you would expect.
+      &interaction.filenames.files;</para>
+
+    <para id="x_546">When you provide a directory name, Mercurial will interpret
+      this as <quote>operate on every file in this directory and its
+	subdirectories</quote>. Mercurial traverses the files and
+      subdirectories in a directory in alphabetical order.  When it
+      encounters a subdirectory, it will traverse that subdirectory
+      before continuing with the current directory.</para>
+
+      &interaction.filenames.dirs;
+  </sect1>
+
+  <sect1>
+    <title>Running commands without any file names</title>
+
+    <para id="x_547">Mercurial's commands that work with file names have useful
+      default behaviors when you invoke them without providing any
+      file names or patterns.  What kind of behavior you should
+      expect depends on what the command does.  Here are a few rules
+      of thumb you can use to predict what a command is likely to do
+      if you don't give it any names to work with.</para>
+    <itemizedlist>
+      <listitem><para id="x_548">Most commands will operate on the entire working
+	  directory. This is what the <command role="hg-cmd">hg
+	    add</command> command does, for example.</para>
+      </listitem>
+      <listitem><para id="x_549">If the command has effects that are difficult or
+	  impossible to reverse, it will force you to explicitly
+	  provide at least one name or pattern (see below).  This
+	  protects you from accidentally deleting files by running
+	  <command role="hg-cmd">hg remove</command> with no
+	  arguments, for example.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_54a">It's easy to work around these default behaviors if they
+      don't suit you.  If a command normally operates on the whole
+      working directory, you can invoke it on just the current
+      directory and its subdirectories by giving it the name
+      <quote><filename class="directory">.</filename></quote>.</para>
+
+    &interaction.filenames.wdir-subdir;
+
+    <para id="x_54b">Along the same lines, some commands normally print file
+      names relative to the root of the repository, even if you're
+      invoking them from a subdirectory.  Such a command will print
+      file names relative to your subdirectory if you give it explicit
+      names.  Here, we're going to run <command role="hg-cmd">hg
+	status</command> from a subdirectory, and get it to operate on
+      the entire working directory while printing file names relative
+      to our subdirectory, by passing it the output of the <command
+	role="hg-cmd">hg root</command> command.</para>
+
+      &interaction.filenames.wdir-relname;
+  </sect1>
+
+  <sect1>
+    <title>Telling you what's going on</title>
+
+    <para id="x_54c">The <command role="hg-cmd">hg add</command> example in the
+      preceding section illustrates something else that's helpful
+      about Mercurial commands.  If a command operates on a file that
+      you didn't name explicitly on the command line, it will usually
+      print the name of the file, so that you will not be surprised
+      what's going on.</para>
+
+    <para id="x_54d">The principle here is of <emphasis>least
+	surprise</emphasis>.  If you've exactly named a file on the
+      command line, there's no point in repeating it back at you.  If
+      Mercurial is acting on a file <emphasis>implicitly</emphasis>, e.g.
+      because you provided no names, or a directory, or a pattern (see
+      below), it is safest to tell you what files it's operating on.</para>
+
+    <para id="x_54e">For commands that behave this way, you can silence them
+      using the <option role="hg-opt-global">-q</option> option.  You
+      can also get them to print the name of every file, even those
+      you've named explicitly, using the <option
+	role="hg-opt-global">-v</option> option.</para>
+  </sect1>
+
+  <sect1>
+    <title>Using patterns to identify files</title>
+
+    <para id="x_54f">In addition to working with file and directory names,
+      Mercurial lets you use <emphasis>patterns</emphasis> to identify
+      files.  Mercurial's pattern handling is expressive.</para>
+
+    <para id="x_550">On Unix-like systems (Linux, MacOS, etc.), the job of
+      matching file names to patterns normally falls to the shell.  On
+      these systems, you must explicitly tell Mercurial that a name is
+      a pattern.  On Windows, the shell does not expand patterns, so
+      Mercurial will automatically identify names that are patterns,
+      and expand them for you.</para>
+
+    <para id="x_551">To provide a pattern in place of a regular name on the
+      command line, the mechanism is simple:</para>
+    <programlisting>syntax:patternbody</programlisting>
+    <para id="x_552">That is, a pattern is identified by a short text string that
+      says what kind of pattern this is, followed by a colon, followed
+      by the actual pattern.</para>
+
+    <para id="x_553">Mercurial supports two kinds of pattern syntax.  The most
+      frequently used is called <literal>glob</literal>; this is the
+      same kind of pattern matching used by the Unix shell, and should
+      be familiar to Windows command prompt users, too.</para>
+
+    <para id="x_554">When Mercurial does automatic pattern matching on Windows,
+      it uses <literal>glob</literal> syntax.  You can thus omit the
+      <quote><literal>glob:</literal></quote> prefix on Windows, but
+      it's safe to use it, too.</para>
+
+    <para id="x_555">The <literal>re</literal> syntax is more powerful; it lets
+      you specify patterns using regular expressions, also known as
+      regexps.</para>
+
+    <para id="x_556">By the way, in the examples that follow, notice that I'm
+      careful to wrap all of my patterns in quote characters, so that
+      they won't get expanded by the shell before Mercurial sees
+      them.</para>
+
+    <sect2>
+      <title>Shell-style <literal>glob</literal> patterns</title>
+
+      <para id="x_557">This is an overview of the kinds of patterns you can use
+	when you're matching on glob patterns.</para>
+
+      <para id="x_558">The <quote><literal>*</literal></quote> character matches
+	any string, within a single directory.</para>
+
+      &interaction.filenames.glob.star;
+
+      <para id="x_559">The <quote><literal>**</literal></quote> pattern matches
+	any string, and crosses directory boundaries.  It's not a
+	standard Unix glob token, but it's accepted by several popular
+	Unix shells, and is very useful.</para>
+
+      &interaction.filenames.glob.starstar;
+
+      <para id="x_55a">The <quote><literal>?</literal></quote> pattern matches
+	any single character.</para>
+
+      &interaction.filenames.glob.question;
+
+      <para id="x_55b">The <quote><literal>[</literal></quote> character begins a
+	<emphasis>character class</emphasis>.  This matches any single
+	character within the class.  The class ends with a
+	<quote><literal>]</literal></quote> character.  A class may
+	contain multiple <emphasis>range</emphasis>s of the form
+	<quote><literal>a-f</literal></quote>, which is shorthand for
+	<quote><literal>abcdef</literal></quote>.</para>
+
+	&interaction.filenames.glob.range;
+
+      <para id="x_55c">If the first character after the
+	<quote><literal>[</literal></quote> in a character class is a
+	<quote><literal>!</literal></quote>, it
+	<emphasis>negates</emphasis> the class, making it match any
+	single character not in the class.</para>
+
+      <para id="x_55d">A <quote><literal>{</literal></quote> begins a group of
+	subpatterns, where the whole group matches if any subpattern
+	in the group matches.  The <quote><literal>,</literal></quote>
+	character separates subpatterns, and
+	<quote><literal>}</literal></quote> ends the group.</para>
+
+      &interaction.filenames.glob.group;
+
+      <sect3>
+	<title>Watch out!</title>
+
+	<para id="x_55e">Don't forget that if you want to match a pattern in any
+	  directory, you should not be using the
+	  <quote><literal>*</literal></quote> match-any token, as this
+	  will only match within one directory.  Instead, use the
+	  <quote><literal>**</literal></quote> token.  This small
+	  example illustrates the difference between the two.</para>
+
+	  &interaction.filenames.glob.star-starstar;
+      </sect3>
+    </sect2>
+
+    <sect2>
+      <title>Regular expression matching with <literal>re</literal>
+	patterns</title>
+
+      <para id="x_55f">Mercurial accepts the same regular expression syntax as
+	the Python programming language (it uses Python's regexp
+	engine internally). This is based on the Perl language's
+	regexp syntax, which is the most popular dialect in use (it's
+	also used in Java, for example).</para>
+
+      <para id="x_560">I won't discuss Mercurial's regexp dialect in any detail
+	here, as regexps are not often used.  Perl-style regexps are
+	in any case already exhaustively documented on a multitude of
+	web sites, and in many books.  Instead, I will focus here on a
+	few things you should know if you find yourself needing to use
+	regexps with Mercurial.</para>
+
+      <para id="x_561">A regexp is matched against an entire file name, relative
+	to the root of the repository.  In other words, even if you're
+	already in subbdirectory <filename
+	  class="directory">foo</filename>, if you want to match files
+	under this directory, your pattern must start with
+	<quote><literal>foo/</literal></quote>.</para>
+
+      <para id="x_562">One thing to note, if you're familiar with Perl-style
+	regexps, is that Mercurial's are <emphasis>rooted</emphasis>.
+	That is, a regexp starts matching against the beginning of a
+	string; it doesn't look for a match anywhere within the
+	string.  To match anywhere in a string, start your pattern
+	with <quote><literal>.*</literal></quote>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Filtering files</title>
+
+    <para id="x_563">Not only does Mercurial give you a variety of ways to
+      specify files; it lets you further winnow those files using
+      <emphasis>filters</emphasis>.  Commands that work with file
+      names accept two filtering options.</para>
+    <itemizedlist>
+      <listitem><para id="x_564"><option role="hg-opt-global">-I</option>, or
+	  <option role="hg-opt-global">--include</option>, lets you
+	  specify a pattern that file names must match in order to be
+	  processed.</para>
+      </listitem>
+      <listitem><para id="x_565"><option role="hg-opt-global">-X</option>, or
+	  <option role="hg-opt-global">--exclude</option>, gives you a
+	  way to <emphasis>avoid</emphasis> processing files, if they
+	  match this pattern.</para>
+      </listitem></itemizedlist>
+    <para id="x_566">You can provide multiple <option
+	role="hg-opt-global">-I</option> and <option
+	role="hg-opt-global">-X</option> options on the command line,
+      and intermix them as you please.  Mercurial interprets the
+      patterns you provide using glob syntax by default (but you can
+      use regexps if you need to).</para>
+
+    <para id="x_567">You can read a <option role="hg-opt-global">-I</option>
+      filter as <quote>process only the files that match this
+	filter</quote>.</para>
+
+    &interaction.filenames.filter.include;
+
+    <para id="x_568">The <option role="hg-opt-global">-X</option> filter is best
+      read as <quote>process only the files that don't match this
+	pattern</quote>.</para>
+
+    &interaction.filenames.filter.exclude;
+  </sect1>
+
+  <sect1>
+    <title>Permanently ignoring unwanted files and directories</title>
+
+    <para id="x_569">When you create a new repository, the chances are
+      that over time it will grow to contain files that ought to
+      <emphasis>not</emphasis> be managed by Mercurial, but which you
+      don't want to see listed every time you run <command>hg
+	status</command>.  For instance, <quote>build products</quote>
+      are files that are created as part of a build but which should
+      not be managed by a revision control system.  The most common
+      build products are output files produced by software tools such
+      as compilers.  As another example, many text editors litter a
+      directory with lock files, temporary working files, and backup
+      files, which it also makes no sense to manage.</para>
+
+    <para id="x_6b4">To have Mercurial permanently ignore such files, create a
+      file named <filename>.hgignore</filename> in the root of your
+      repository.  You <emphasis>should</emphasis> <command>hg
+      add</command> this file so that it gets tracked with the rest of
+      your repository contents, since your collaborators will probably
+      find it useful too.</para>
+
+    <para id="x_6b5">By default, the <filename>.hgignore</filename> file should
+      contain a list of regular expressions, one per line.  Empty
+      lines are skipped. Most people prefer to describe the files they
+      want to ignore using the <quote>glob</quote> syntax that we
+      described above, so a typical <filename>.hgignore</filename>
+      file will start with this directive:</para>
+
+    <programlisting>syntax: glob</programlisting>
+
+    <para id="x_6b6">This tells Mercurial to interpret the lines that follow as
+      glob patterns, not regular expressions.</para>
+
+    <para id="x_6b7">Here is a typical-looking <filename>.hgignore</filename>
+      file.</para>
+
+    <programlisting>syntax: glob
+# This line is a comment, and will be skipped.
+# Empty lines are skipped too.
+
+# Backup files left behind by the Emacs editor.
+*~
+
+# Lock files used by the Emacs editor.
+# Notice that the "#" character is quoted with a backslash.
+# This prevents it from being interpreted as starting a comment.
+.\#*
+
+# Temporary files used by the vim editor.
+.*.swp
+
+# A hidden file created by the Mac OS X Finder.
+.DS_Store
+</programlisting>
+  </sect1>
+
+  <sect1 id="sec:names:case">
+    <title>Case sensitivity</title>
+
+    <para id="x_56a">If you're working in a mixed development environment that
+      contains both Linux (or other Unix) systems and Macs or Windows
+      systems, you should keep in the back of your mind the knowledge
+      that they treat the case (<quote>N</quote> versus
+      <quote>n</quote>) of file names in incompatible ways.  This is
+      not very likely to affect you, and it's easy to deal with if it
+      does, but it could surprise you if you don't know about
+      it.</para>
+
+    <para id="x_56b">Operating systems and filesystems differ in the way they
+      handle the <emphasis>case</emphasis> of characters in file and
+      directory names.  There are three common ways to handle case in
+      names.</para>
+    <itemizedlist>
+      <listitem><para id="x_56c">Completely case insensitive.  Uppercase and
+	  lowercase versions of a letter are treated as identical,
+	  both when creating a file and during subsequent accesses.
+	  This is common on older DOS-based systems.</para>
+      </listitem>
+      <listitem><para id="x_56d">Case preserving, but insensitive.  When a file
+	  or directory is created, the case of its name is stored, and
+	  can be retrieved and displayed by the operating system.
+	  When an existing file is being looked up, its case is
+	  ignored.  This is the standard arrangement on Windows and
+	  MacOS.  The names <filename>foo</filename> and
+	  <filename>FoO</filename> identify the same file.  This
+	  treatment of uppercase and lowercase letters as
+	  interchangeable is also referred to as <emphasis>case
+	    folding</emphasis>.</para>
+      </listitem>
+      <listitem><para id="x_56e">Case sensitive.  The case of a name is
+	  significant at all times. The names <filename>foo</filename>
+	  and {FoO} identify different files.  This is the way Linux
+	  and Unix systems normally work.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_56f">On Unix-like systems, it is possible to have any or all of
+      the above ways of handling case in action at once.  For example,
+      if you use a USB thumb drive formatted with a FAT32 filesystem
+      on a Linux system, Linux will handle names on that filesystem in
+      a case preserving, but insensitive, way.</para>
+
+    <sect2>
+      <title>Safe, portable repository storage</title>
+
+      <para id="x_570">Mercurial's repository storage mechanism is <emphasis>case
+	  safe</emphasis>.  It translates file names so that they can
+	be safely stored on both case sensitive and case insensitive
+	filesystems.  This means that you can use normal file copying
+	tools to transfer a Mercurial repository onto, for example, a
+	USB thumb drive, and safely move that drive and repository
+	back and forth between a Mac, a PC running Windows, and a
+	Linux box.</para>
+
+    </sect2>
+    <sect2>
+      <title>Detecting case conflicts</title>
+
+      <para id="x_571">When operating in the working directory, Mercurial honours
+	the naming policy of the filesystem where the working
+	directory is located.  If the filesystem is case preserving,
+	but insensitive, Mercurial will treat names that differ only
+	in case as the same.</para>
+
+      <para id="x_572">An important aspect of this approach is that it is
+	possible to commit a changeset on a case sensitive (typically
+	Linux or Unix) filesystem that will cause trouble for users on
+	case insensitive (usually Windows and MacOS) users.  If a
+	Linux user commits changes to two files, one named
+	<filename>myfile.c</filename> and the other named
+	<filename>MyFile.C</filename>, they will be stored correctly
+	in the repository.  And in the working directories of other
+	Linux users, they will be correctly represented as separate
+	files.</para>
+
+      <para id="x_573">If a Windows or Mac user pulls this change, they will not
+	initially have a problem, because Mercurial's repository
+	storage mechanism is case safe.  However, once they try to
+	<command role="hg-cmd">hg update</command> the working
+	directory to that changeset, or <command role="hg-cmd">hg
+	  merge</command> with that changeset, Mercurial will spot the
+	conflict between the two file names that the filesystem would
+	treat as the same, and forbid the update or merge from
+	occurring.</para>
+    </sect2>
+
+    <sect2>
+      <title>Fixing a case conflict</title>
+
+      <para id="x_574">If you are using Windows or a Mac in a mixed environment
+	where some of your collaborators are using Linux or Unix, and
+	Mercurial reports a case folding conflict when you try to
+	<command role="hg-cmd">hg update</command> or <command
+	  role="hg-cmd">hg merge</command>, the procedure to fix the
+	problem is simple.</para>
+
+      <para id="x_575">Just find a nearby Linux or Unix box, clone the problem
+	repository onto it, and use Mercurial's <command
+	  role="hg-cmd">hg rename</command> command to change the
+	names of any offending files or directories so that they will
+	no longer cause case folding conflicts.  Commit this change,
+	<command role="hg-cmd">hg pull</command> or <command
+	  role="hg-cmd">hg push</command> it across to your Windows or
+	MacOS system, and <command role="hg-cmd">hg update</command>
+	to the revision with the non-conflicting names.</para>
+
+      <para id="x_576">The changeset with case-conflicting names will remain in
+	your project's history, and you still won't be able to
+	<command role="hg-cmd">hg update</command> your working
+	directory to that changeset on a Windows or MacOS system, but
+	you can continue development unimpeded.</para>
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch07-branch.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,532 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:branch">
+  <?dbhtml filename="managing-releases-and-branchy-development.html"?>
+  <title>Managing releases and branchy development</title>
+
+  <para id="x_369">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.</para>
+
+  <para id="x_36a">Many software projects issue periodic <quote>major</quote>
+    releases that contain substantial new features.  In parallel, they
+    may issue <quote>minor</quote> releases.  These are usually
+    identical to the major releases off which they're based, but with
+    a few bugs fixed.</para>
+
+  <para id="x_36b">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.</para>
+
+  <sect1>
+    <title>Giving a persistent name to a revision</title>
+
+    <para id="x_36c">Once you decide that you'd like to call a particular
+      revision a <quote>release</quote>, 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;</para>
+
+    <para id="x_36d">Mercurial lets you give a permanent name to any revision
+      using the <command role="hg-cmd">hg tag</command> command.  Not
+      surprisingly, these names are called <quote>tags</quote>.</para>
+
+    &interaction.tag.tag;
+
+    <para id="x_36e">A tag is nothing more than a <quote>symbolic name</quote>
+      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:</para>
+    <itemizedlist>
+      <listitem><para id="x_36f">Colon (ASCII 58,
+	  <quote><literal>:</literal></quote>)</para>
+      </listitem>
+      <listitem><para id="x_370">Carriage return (ASCII 13,
+	  <quote><literal>\r</literal></quote>)</para>
+      </listitem>
+      <listitem><para id="x_371">Newline (ASCII 10,
+	  <quote><literal>\n</literal></quote>)</para>
+      </listitem></itemizedlist>
+
+    <para id="x_372">You can use the <command role="hg-cmd">hg tags</command>
+      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.</para>
+
+    &interaction.tag.tags;
+
+    <para id="x_373">Notice that <literal>tip</literal> is listed in the output
+      of <command role="hg-cmd">hg tags</command>.  The
+      <literal>tip</literal> tag is a special <quote>floating</quote>
+      tag, which always identifies the newest revision in the
+      repository.</para>
+
+    <para id="x_374">In the output of the <command role="hg-cmd">hg
+	tags</command> 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 <literal>tip</literal> is
+      always going to be the first tag listed in the output of
+      <command role="hg-cmd">hg tags</command>.</para>
+
+    <para id="x_375">When you run <command role="hg-cmd">hg log</command>, if it
+      displays a revision that has tags associated with it, it will
+      print those tags.</para>
+
+    &interaction.tag.log;
+
+    <para id="x_376">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.</para>
+
+    &interaction.tag.log.v1.0;
+
+    <para id="x_377">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
+      <quote>too many</quote> (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.</para>
+
+    <para id="x_378">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.</para>
+
+    <para id="x_379">If you want to remove a tag that you no longer want, use
+      <command role="hg-cmd">hg tag --remove</command>.</para>
+
+    &interaction.tag.remove;
+
+    <para id="x_37a">You can also modify a tag at any time, so that it identifies
+      a different revision, by simply issuing a new <command
+	role="hg-cmd">hg tag</command> command. You'll have to use the
+      <option role="hg-opt-tag">-f</option> option to tell Mercurial
+      that you <emphasis>really</emphasis> want to update the
+      tag.</para>
+
+    &interaction.tag.replace;
+
+    <para id="x_37b">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.</para>
+
+    <para id="x_37c">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 in the root of your repository named <filename
+	role="special">.hgtags</filename>.  When you run the <command
+	role="hg-cmd">hg tag</command> command, Mercurial modifies
+      this file, then automatically commits the change to it.  This
+      means that every time you run <command role="hg-cmd">hg
+	tag</command>, you'll see a corresponding changeset in the
+      output of <command role="hg-cmd">hg log</command>.</para>
+
+    &interaction.tag.tip;
+
+    <sect2>
+      <title>Handling tag conflicts during a merge</title>
+
+      <para id="x_37d">You won't often need to care about the <filename
+	  role="special">.hgtags</filename> 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.</para>
+
+      <para id="x_37e">If you're resolving a conflict in the <filename
+	  role="special">.hgtags</filename> file during a merge,
+	there's one twist to modifying the <filename
+	  role="special">.hgtags</filename> file: when Mercurial is
+	parsing the tags in a repository, it
+	<emphasis>never</emphasis> reads the working copy of the
+	<filename role="special">.hgtags</filename> file.  Instead, it
+	reads the <emphasis>most recently committed</emphasis>
+	revision of the file.</para>
+
+      <para id="x_37f">An unfortunate consequence of this design is that you
+	can't actually verify that your merged <filename
+	  role="special">.hgtags</filename> file is correct until
+	<emphasis>after</emphasis> you've committed a change.  So if
+	you find yourself resolving a conflict on <filename
+	  role="special">.hgtags</filename> during a merge, be sure to
+	run <command role="hg-cmd">hg tags</command> after you commit.
+	If it finds an error in the <filename
+	  role="special">.hgtags</filename> file, it will report the
+	location of the error, which you can then fix and commit.  You
+	should then run <command role="hg-cmd">hg tags</command>
+	again, just to be sure that your fix is correct.</para>
+    </sect2>
+
+    <sect2>
+      <title>Tags and cloning</title>
+
+      <para id="x_380">You may have noticed that the <command role="hg-cmd">hg
+	  clone</command> command has a <option
+	  role="hg-opt-clone">-r</option> 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.</para>
+
+      <para id="x_381">Recall that a tag is stored as a revision to the <filename
+	  role="special">.hgtags</filename> file, so that when you
+	create a tag, the changeset in which it's recorded necessarily
+	refers to an older changeset.  When you run <command
+	  role="hg-cmd">hg clone -r foo</command> to clone a
+	repository as of tag <literal>foo</literal>, the new clone
+	<emphasis>will not contain the history that created the
+	  tag</emphasis> 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
+	<emphasis>not</emphasis> the tag you might have
+	expected.</para>
+    </sect2>
+
+    <sect2>
+      <title>When permanent tags are too much</title>
+
+      <para id="x_382">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
+	<literal>4237e45506ee</literal> is really
+	<literal>v2.0.2</literal>.  If you're trying to track down a
+	subtle bug, you might want a tag to remind you of something
+	like <quote>Anne saw the symptoms with this
+	  revision</quote>.</para>
+
+      <para id="x_383">For cases like this, what you might want to use are
+	<emphasis>local</emphasis> tags. You can create a local tag
+	with the <option role="hg-opt-tag">-l</option> option to the
+	<command role="hg-cmd">hg tag</command> command.  This will
+	store the tag in a file called <filename
+	  role="special">.hg/localtags</filename>.  Unlike <filename
+	  role="special">.hgtags</filename>, <filename
+	  role="special">.hg/localtags</filename> is not revision
+	controlled.  Any tags you create using <option
+	  role="hg-opt-tag">-l</option> remain strictly local to the
+	repository you're currently working in.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>The flow of changes&emdash;big picture vs. little</title>
+
+    <para id="x_384">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.</para>
+
+    <para id="x_385">There might be a push for a new <quote>main</quote> release;
+      a new minor bugfix release to the last main release; and an
+      unexpected <quote>hot fix</quote> to an old release that is now
+      in maintenance mode.</para>
+
+    <para id="x_386">The usual way people refer to these different concurrent
+      directions of development is as <quote>branches</quote>.
+      However, we've already seen numerous times that Mercurial treats
+      <emphasis>all of history</emphasis> 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.</para>
+    <itemizedlist>
+      <listitem><para id="x_387"><quote>Big picture</quote> branches represent
+	  the sweep of a project's evolution; people give them names,
+	  and talk about them in conversation.</para>
+      </listitem>
+      <listitem><para id="x_388"><quote>Little picture</quote> branches are
+	  artefacts of the day-to-day activity of developing and
+	  merging changes.  They expose the narrative of how the code
+	  was developed.</para>
+      </listitem></itemizedlist>
+  </sect1>
+
+  <sect1>
+    <title>Managing big-picture branches in repositories</title>
+
+    <para id="x_389">The easiest way to isolate a <quote>big picture</quote>
+      branch in Mercurial is in a dedicated repository.  If you have
+      an existing shared repository&emdash;let's call it
+      <literal>myproject</literal>&emdash;that reaches a
+      <quote>1.0</quote> 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.</para>
+
+    &interaction.branch-repo.tag;
+
+    <para id="x_38a">You can then clone a new shared
+      <literal>myproject-1.0.1</literal> repository as of that
+      tag.</para>
+
+    &interaction.branch-repo.clone;
+
+    <para id="x_38b">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
+      <literal>myproject-1.0.1</literal> repository, make their
+      changes, and push them back.</para>
+
+    &interaction.branch-repo.bugfix;
+
+    <para id="x_38c">Meanwhile, development for
+      the next major release can continue, isolated and unabated, in
+      the <literal>myproject</literal> repository.</para>
+
+    &interaction.branch-repo.new;
+  </sect1>
+
+  <sect1>
+    <title>Don't repeat yourself: merging across branches</title>
+
+    <para id="x_38d">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.</para>
+
+    <para id="x_38e">In the simplest instance, all you need to do is pull changes
+      from your maintenance branch into your local clone of the target
+      branch.</para>
+
+    &interaction.branch-repo.pull;
+
+    <para id="x_38f">You'll then need to merge the heads of the two branches, and
+      push back to the main branch.</para>
+
+    &interaction.branch-repo.merge;
+  </sect1>
+
+  <sect1>
+    <title>Naming branches within one repository</title>
+
+    <para id="x_390">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.</para>
+
+    <para id="x_391">If you're more in the <quote>power user</quote> category
+      (<emphasis>and</emphasis> 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
+      <quote>small picture</quote> and <quote>big picture</quote>
+      branches.  While Mercurial works with multiple <quote>small
+	picture</quote> branches in a repository all the time (for
+      example after you pull changes in, but before you merge them),
+      it can <emphasis>also</emphasis> work with multiple <quote>big
+	picture</quote> branches.</para>
+
+    <para id="x_392">The key to working this way is that Mercurial lets you
+      assign a persistent <emphasis>name</emphasis> to a branch.
+      There always exists a branch named <literal>default</literal>.
+      Even before you start naming branches yourself, you can find
+      traces of the <literal>default</literal> branch if you look for
+      them.</para>
+
+    <para id="x_393">As an example, when you run the <command role="hg-cmd">hg
+	commit</command> command, and it pops up your editor so that
+      you can enter a commit message, look for a line that contains
+      the text <quote><literal>HG: branch default</literal></quote> at
+      the bottom. This is telling you that your commit will occur on
+      the branch named <literal>default</literal>.</para>
+
+    <para id="x_394">To start working with named branches, use the <command
+	role="hg-cmd">hg branches</command> command.  This command
+      lists the named branches already present in your repository,
+      telling you which changeset is the tip of each.</para>
+
+    &interaction.branch-named.branches;
+
+    <para id="x_395">Since you haven't created any named branches yet, the only
+      one that exists is <literal>default</literal>.</para>
+
+    <para id="x_396">To find out what the <quote>current</quote> branch is, run
+      the <command role="hg-cmd">hg branch</command> command, giving
+      it no arguments.  This tells you what branch the parent of the
+      current changeset is on.</para>
+
+    &interaction.branch-named.branch;
+
+    <para id="x_397">To create a new branch, run the <command role="hg-cmd">hg
+	branch</command> command again.  This time, give it one
+      argument: the name of the branch you want to create.</para>
+
+    &interaction.branch-named.create;
+
+    <para id="x_398">After you've created a branch, you might wonder what effect
+      the <command role="hg-cmd">hg branch</command> command has had.
+      What do the <command role="hg-cmd">hg status</command> and
+      <command role="hg-cmd">hg tip</command> commands report?</para>
+
+    &interaction.branch-named.status;
+
+    <para id="x_399">Nothing has changed in the
+      working directory, and there's been no new history created.  As
+      this suggests, running the <command role="hg-cmd">hg
+	branch</command> command has no permanent effect; it only
+      tells Mercurial what branch name to use the
+      <emphasis>next</emphasis> time you commit a changeset.</para>
+
+    <para id="x_39a">When you commit a change, Mercurial records the name of the
+      branch on which you committed.  Once you've switched from the
+      <literal>default</literal> branch to another and committed,
+      you'll see the name of the new branch show up in the output of
+      <command role="hg-cmd">hg log</command>, <command
+	role="hg-cmd">hg tip</command>, and other commands that
+      display the same kind of output.</para>
+
+    &interaction.branch-named.commit;
+
+    <para id="x_39b">The <command role="hg-cmd">hg log</command>-like commands
+      will print the branch name of every changeset that's not on the
+      <literal>default</literal> branch.  As a result, if you never
+      use named branches, you'll never see this information.</para>
+
+    <para id="x_39c">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 <command role="hg-cmd">hg
+	branch</command> command.</para>
+
+    &interaction.branch-named.rebranch;
+
+    <para id="x_39d">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.)</para>
+  </sect1>
+
+  <sect1>
+    <title>Dealing with multiple named branches in a
+      repository</title>
+
+    <para id="x_39e">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 <command role="hg-cmd">hg
+	update</command> or <command role="hg-cmd">hg pull
+	-u</command>.  It will update the working directory to the tip
+      of this branch, no matter what the <quote>repo-wide</quote> tip
+      is.  To update to a revision that's on a different named branch,
+      you may need to use the <option role="hg-opt-update">-C</option>
+      option to <command role="hg-cmd">hg update</command>.</para>
+
+    <para id="x_39f">This behavior 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.</para>
+
+    &interaction.branch-named.parents;
+
+    <para id="x_3a0">We're on the <literal>bar</literal> branch, but there also
+      exists an older <command role="hg-cmd">hg foo</command>
+      branch.</para>
+
+    <para id="x_3a1">We can <command role="hg-cmd">hg update</command> back and
+      forth between the tips of the <literal>foo</literal> and
+      <literal>bar</literal> branches without needing to use the
+      <option role="hg-opt-update">-C</option> option, because this
+      only involves going backwards and forwards linearly through our
+      change history.</para>
+
+    &interaction.branch-named.update-switchy;
+
+    <para id="x_3a2">If we go back to the <literal>foo</literal> branch and then
+      run <command role="hg-cmd">hg update</command>, it will keep us
+      on <literal>foo</literal>, not move us to the tip of
+      <literal>bar</literal>.</para>
+
+    &interaction.branch-named.update-nothing;
+
+    <para id="x_3a3">Committing a new change on the <literal>foo</literal> branch
+      introduces a new head.</para>
+
+    &interaction.branch-named.foo-commit;
+  </sect1>
+
+  <sect1>
+    <title>Branch names and merging</title>
+
+    <para id="x_3a4">As you've probably noticed, merges in Mercurial are not
+      symmetrical. Let's say our repository has two heads, 17 and 23.
+      If I <command role="hg-cmd">hg update</command> to 17 and then
+      <command role="hg-cmd">hg merge</command> with 23, Mercurial
+      records 17 as the first parent of the merge, and 23 as the
+      second.  Whereas if I <command role="hg-cmd">hg update</command>
+      to 23 and then <command role="hg-cmd">hg merge</command> with
+      17, it records 23 as the first parent, and 17 as the
+      second.</para>
+
+    <para id="x_3a5">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 <literal>foo</literal>, and
+      you merge with <literal>bar</literal>, the branch name will
+      still be <literal>foo</literal> after you merge.</para>
+
+    <para id="x_3a6">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
+      <literal>foo</literal> branch, and so are you.  We commit
+      different changes; I pull your changes; I now have two heads,
+      each claiming to be on the <literal>foo</literal> branch.  The
+      result of a merge will be a single head on the
+      <literal>foo</literal> branch, as you might hope.</para>
+
+    <para id="x_3a7">But if I'm working on the <literal>bar</literal> branch, and
+      I merge work from the <literal>foo</literal> branch, the result
+      will remain on the <literal>bar</literal> branch.</para>
+
+    &interaction.branch-named.merge;
+
+    <para id="x_3a8">To give a more concrete example, if I'm working on the
+      <literal>bleeding-edge</literal> branch, and I want to bring in
+      the latest fixes from the <literal>stable</literal> branch,
+      Mercurial will choose the <quote>right</quote>
+      (<literal>bleeding-edge</literal>) branch name when I pull and
+      merge from <literal>stable</literal>.</para>
+  </sect1>
+
+  <sect1>
+    <title>Branch naming is generally useful</title>
+
+    <para id="x_3a9">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.</para>
+
+    <para id="x_3aa">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.</para>
+
+    <para id="x_3ab">If you're working with shared repositories, you can set up a
+      <literal role="hook">pretxnchangegroup</literal> hook on each
+      that will block incoming changes that have the
+      <quote>wrong</quote> branch name.  This provides a simple, but
+      effective, defence against people accidentally pushing changes
+      from a <quote>bleeding edge</quote> branch to a
+      <quote>stable</quote> branch.  Such a hook might look like this
+      inside the shared repo's <filename role="special">
+	/.hgrc</filename>.</para>
+    <programlisting>[hooks]
+pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch08-undo.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1069 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:undo">
+  <?dbhtml filename="finding-and-fixing-mistakes.html"?>
+  <title>Finding and fixing mistakes</title>
+
+  <para id="x_d2">To err might be human, but to really handle the consequences
+    well takes a top-notch revision control system.  In this chapter,
+    we'll discuss some of the techniques you can use when you find
+    that a problem has crept into your project.  Mercurial has some
+    highly capable features that will help you to isolate the sources
+    of problems, and to handle them appropriately.</para>
+
+  <sect1>
+    <title>Erasing local history</title>
+
+    <sect2>
+      <title>The accidental commit</title>
+
+      <para id="x_d3">I have the occasional but persistent problem of typing
+	rather more quickly than I can think, which sometimes results
+	in me committing a changeset that is either incomplete or
+	plain wrong.  In my case, the usual kind of incomplete
+	changeset is one in which I've created a new source file, but
+	forgotten to <command role="hg-cmd">hg add</command> it.  A
+	<quote>plain wrong</quote> changeset is not as common, but no
+	less annoying.</para>
+
+    </sect2>
+    <sect2 id="sec:undo:rollback">
+      <title>Rolling back a transaction</title>
+
+      <para id="x_d4">In <xref linkend="sec:concepts:txn"/>, I
+	mentioned that Mercurial treats each modification of a
+	repository as a <emphasis>transaction</emphasis>.  Every time
+	you commit a changeset or pull changes from another
+	repository, Mercurial remembers what you did.  You can undo,
+	or <emphasis>roll back</emphasis>, exactly one of these
+	actions using the <command role="hg-cmd">hg rollback</command>
+	command.  (See <xref linkend="sec:undo:rollback-after-push"/>
+	for an important caveat about the use of this command.)</para>
+
+      <para id="x_d5">Here's a mistake that I often find myself making:
+	committing a change in which I've created a new file, but
+	forgotten to <command role="hg-cmd">hg add</command>
+	it.</para>
+
+      &interaction.rollback.commit;
+
+      <para id="x_d6">Looking at the output of <command role="hg-cmd">hg
+	  status</command> after the commit immediately confirms the
+	error.</para>
+
+      &interaction.rollback.status;
+
+      <para id="x_d7">The commit captured the changes to the file
+	<filename>a</filename>, but not the new file
+	<filename>b</filename>.  If I were to push this changeset to a
+	repository that I shared with a colleague, the chances are
+	high that something in <filename>a</filename> would refer to
+	<filename>b</filename>, which would not be present in their
+	repository when they pulled my changes.  I would thus become
+	the object of some indignation.</para>
+
+      <para id="x_d8">However, luck is with me&emdash;I've caught my error
+	before I pushed the changeset.  I use the <command
+	  role="hg-cmd">hg rollback</command> command, and Mercurial
+	makes that last changeset vanish.</para>
+
+      &interaction.rollback.rollback;
+
+      <para id="x_d9">Notice that the changeset is no longer present in the
+	repository's history, and the working directory once again
+	thinks that the file <filename>a</filename> is modified.  The
+	commit and rollback have left the working directory exactly as
+	it was prior to the commit; the changeset has been completely
+	erased.  I can now safely <command role="hg-cmd">hg
+	  add</command> the file <filename>b</filename>, and rerun my
+	commit.</para>
+
+      &interaction.rollback.add;
+
+    </sect2>
+    <sect2>
+      <title>The erroneous pull</title>
+
+      <para id="x_da">It's common practice with Mercurial to maintain separate
+	development branches of a project in different repositories.
+	Your development team might have one shared repository for
+	your project's <quote>0.9</quote> release, and another,
+	containing different changes, for the <quote>1.0</quote>
+	release.</para>
+
+      <para id="x_db">Given this, you can imagine that the consequences could be
+	messy if you had a local <quote>0.9</quote> repository, and
+	accidentally pulled changes from the shared <quote>1.0</quote>
+	repository into it.  At worst, you could be paying
+	insufficient attention, and push those changes into the shared
+	<quote>0.9</quote> tree, confusing your entire team (but don't
+	worry, we'll return to this horror scenario later).  However,
+	it's more likely that you'll notice immediately, because
+	Mercurial will display the URL it's pulling from, or you will
+	see it pull a suspiciously large number of changes into the
+	repository.</para>
+
+      <para id="x_dc">The <command role="hg-cmd">hg rollback</command> command
+	will work nicely to expunge all of the changesets that you
+	just pulled.  Mercurial groups all changes from one <command
+	  role="hg-cmd">hg pull</command> into a single transaction,
+	so one <command role="hg-cmd">hg rollback</command> is all you
+	need to undo this mistake.</para>
+
+    </sect2>
+    <sect2 id="sec:undo:rollback-after-push">
+      <title>Rolling back is useless once you've pushed</title>
+
+      <para id="x_dd">The value of the <command role="hg-cmd">hg
+	  rollback</command> command drops to zero once you've pushed
+	your changes to another repository.  Rolling back a change
+	makes it disappear entirely, but <emphasis>only</emphasis> in
+	the repository in which you perform the <command
+	  role="hg-cmd">hg rollback</command>.  Because a rollback
+	eliminates history, there's no way for the disappearance of a
+	change to propagate between repositories.</para>
+
+      <para id="x_de">If you've pushed a change to another
+	repository&emdash;particularly if it's a shared
+	repository&emdash;it has essentially <quote>escaped into the
+	  wild,</quote> and you'll have to recover from your mistake
+	in a different way.  What will happen if you push a changeset
+	somewhere, then roll it back, then pull from the repository
+	you pushed to, is that the changeset will reappear in your
+	repository.</para>
+
+      <para id="x_df">(If you absolutely know for sure that the change you want
+	to roll back is the most recent change in the repository that
+	you pushed to, <emphasis>and</emphasis> you know that nobody
+	else could have pulled it from that repository, you can roll
+	back the changeset there, too, but you really should really
+	not rely on this working reliably.  If you do this, sooner or
+	later a change really will make it into a repository that you
+	don't directly control (or have forgotten about), and come
+	back to bite you.)</para>
+
+    </sect2>
+    <sect2>
+      <title>You can only roll back once</title>
+
+      <para id="x_e0">Mercurial stores exactly one transaction in its
+	transaction log; that transaction is the most recent one that
+	occurred in the repository. This means that you can only roll
+	back one transaction.  If you expect to be able to roll back
+	one transaction, then its predecessor, this is not the
+	behavior you will get.</para>
+
+      &interaction.rollback.twice;
+
+      <para id="x_e1">Once you've rolled back one transaction in a repository,
+	you can't roll back again in that repository until you perform
+	another commit or pull.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Reverting the mistaken change</title>
+
+    <para id="x_e2">If you make a modification to a file, and decide that you
+      really didn't want to change the file at all, and you haven't
+      yet committed your changes, the <command role="hg-cmd">hg
+	revert</command> command is the one you'll need.  It looks at
+      the changeset that's the parent of the working directory, and
+      restores the contents of the file to their state as of that
+      changeset. (That's a long-winded way of saying that, in the
+      normal case, it undoes your modifications.)</para>
+
+    <para id="x_e3">Let's illustrate how the <command role="hg-cmd">hg
+	revert</command> command works with yet another small example.
+      We'll begin by modifying a file that Mercurial is already
+      tracking.</para>
+
+    &interaction.daily.revert.modify;
+
+    <para id="x_e4">If we don't
+      want that change, we can simply <command role="hg-cmd">hg
+	revert</command> the file.</para>
+
+      &interaction.daily.revert.unmodify;
+
+    <para id="x_e5">The <command role="hg-cmd">hg revert</command> command
+      provides us with an extra degree of safety by saving our
+      modified file with a <filename>.orig</filename>
+      extension.</para>
+
+    &interaction.daily.revert.status;
+
+    <para id="x_e6">Here is a summary of the cases that the <command
+	role="hg-cmd">hg revert</command> command can deal with.  We
+      will describe each of these in more detail in the section that
+      follows.</para>
+    <itemizedlist>
+      <listitem><para id="x_e7">If you modify a file, it will restore the file
+	  to its unmodified state.</para>
+      </listitem>
+      <listitem><para id="x_e8">If you <command role="hg-cmd">hg add</command> a
+	  file, it will undo the <quote>added</quote> state of the
+	  file, but leave the file itself untouched.</para>
+      </listitem>
+      <listitem><para id="x_e9">If you delete a file without telling Mercurial,
+	  it will restore the file to its unmodified contents.</para>
+      </listitem>
+      <listitem><para id="x_ea">If you use the <command role="hg-cmd">hg
+	    remove</command> command to remove a file, it will undo
+	  the <quote>removed</quote> state of the file, and restore
+	  the file to its unmodified contents.</para>
+      </listitem></itemizedlist>
+
+    <sect2 id="sec:undo:mgmt">
+      <title>File management errors</title>
+
+      <para id="x_eb">The <command role="hg-cmd">hg revert</command> command is
+	useful for more than just modified files.  It lets you reverse
+	the results of all of Mercurial's file management
+	commands&emdash;<command role="hg-cmd">hg add</command>,
+	<command role="hg-cmd">hg remove</command>, and so on.</para>
+
+      <para id="x_ec">If you <command role="hg-cmd">hg add</command> a file,
+	then decide that in fact you don't want Mercurial to track it,
+	use <command role="hg-cmd">hg revert</command> to undo the
+	add.  Don't worry; Mercurial will not modify the file in any
+	way.  It will just <quote>unmark</quote> the file.</para>
+
+      &interaction.daily.revert.add;
+
+      <para id="x_ed">Similarly, if you ask Mercurial to <command
+	  role="hg-cmd">hg remove</command> a file, you can use
+	<command role="hg-cmd">hg revert</command> to restore it to
+	the contents it had as of the parent of the working directory.
+	&interaction.daily.revert.remove; This works just as
+	well for a file that you deleted by hand, without telling
+	Mercurial (recall that in Mercurial terminology, this kind of
+	file is called <quote>missing</quote>).</para>
+
+      &interaction.daily.revert.missing;
+
+      <para id="x_ee">If you revert a <command role="hg-cmd">hg copy</command>,
+	the copied-to file remains in your working directory
+	afterwards, untracked.  Since a copy doesn't affect the
+	copied-from file in any way, Mercurial doesn't do anything
+	with the copied-from file.</para>
+
+      &interaction.daily.revert.copy;
+
+      <sect3>
+	<title>A slightly special case: reverting a rename</title>
+
+	<para id="x_ef">If you <command role="hg-cmd">hg rename</command> a
+	  file, there is one small detail that you should remember.
+	  When you <command role="hg-cmd">hg revert</command> a
+	  rename, it's not enough to provide the name of the
+	  renamed-to file, as you can see here.</para>
+
+	&interaction.daily.revert.rename;
+
+	<para id="x_f0">As you can see from the output of <command
+	    role="hg-cmd">hg status</command>, the renamed-to file is
+	  no longer identified as added, but the
+	  renamed-<emphasis>from</emphasis> file is still removed!
+	  This is counter-intuitive (at least to me), but at least
+	  it's easy to deal with.</para>
+
+	&interaction.daily.revert.rename-orig;
+
+	<para id="x_f1">So remember, to revert a <command role="hg-cmd">hg
+	    rename</command>, you must provide
+	  <emphasis>both</emphasis> the source and destination
+	  names.</para>
+
+	<para id="x_f2">% TODO: the output doesn't look like it will be
+	  removed!</para>
+
+	<para id="x_f3">(By the way, if you rename a file, then modify the
+	  renamed-to file, then revert both components of the rename,
+	  when Mercurial restores the file that was removed as part of
+	  the rename, it will be unmodified. If you need the
+	  modifications in the renamed-to file to show up in the
+	  renamed-from file, don't forget to copy them over.)</para>
+
+	<para id="x_f4">These fiddly aspects of reverting a rename arguably
+	  constitute a small bug in Mercurial.</para>
+
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Dealing with committed changes</title>
+
+    <para id="x_f5">Consider a case where you have committed a change $a$, and
+      another change $b$ on top of it; you then realise that change
+      $a$ was incorrect.  Mercurial lets you <quote>back out</quote>
+      an entire changeset automatically, and building blocks that let
+      you reverse part of a changeset by hand.</para>
+
+    <para id="x_f6">Before you read this section, here's something to
+      keep in mind: the <command role="hg-cmd">hg backout</command>
+      command undoes changes by <emphasis>adding</emphasis> history,
+      not by modifying or erasing it.  It's the right tool to use if
+      you're fixing bugs, but not if you're trying to undo some change
+      that has catastrophic consequences.  To deal with those, see
+      <xref linkend="sec:undo:aaaiiieee"/>.</para>
+
+    <sect2>
+      <title>Backing out a changeset</title>
+
+      <para id="x_f7">The <command role="hg-cmd">hg backout</command> command
+	lets you <quote>undo</quote> the effects of an entire
+	changeset in an automated fashion.  Because Mercurial's
+	history is immutable, this command <emphasis>does
+	  not</emphasis> get rid of the changeset you want to undo.
+	Instead, it creates a new changeset that
+	<emphasis>reverses</emphasis> the effect of the to-be-undone
+	changeset.</para>
+
+      <para id="x_f8">The operation of the <command role="hg-cmd">hg
+	  backout</command> command is a little intricate, so let's
+	illustrate it with some examples.  First, we'll create a
+	repository with some simple changes.</para>
+
+      &interaction.backout.init;
+
+      <para id="x_f9">The <command role="hg-cmd">hg backout</command> command
+	takes a single changeset ID as its argument; this is the
+	changeset to back out.  Normally, <command role="hg-cmd">hg
+	  backout</command> will drop you into a text editor to write
+	a commit message, so you can record why you're backing the
+	change out.  In this example, we provide a commit message on
+	the command line using the <option
+	  role="hg-opt-backout">-m</option> option.</para>
+
+    </sect2>
+    <sect2>
+      <title>Backing out the tip changeset</title>
+
+      <para id="x_fa">We're going to start by backing out the last changeset we
+	committed.</para>
+
+      &interaction.backout.simple;
+
+      <para id="x_fb">You can see that the second line from
+	<filename>myfile</filename> is no longer present.  Taking a
+	look at the output of <command role="hg-cmd">hg log</command>
+	gives us an idea of what the <command role="hg-cmd">hg
+	  backout</command> command has done.
+	&interaction.backout.simple.log; Notice that the new changeset
+	that <command role="hg-cmd">hg backout</command> has created
+	is a child of the changeset we backed out.  It's easier to see
+	this in <xref linkend="fig:undo:backout"/>, which presents a
+	graphical view of the change history.  As you can see, the
+	history is nice and linear.</para>
+
+      <figure id="fig:undo:backout">
+	<title>Backing out a change using the <command
+	    role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-simple.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Backing out a non-tip change</title>
+
+      <para id="x_fd">If you want to back out a change other than the last one
+	you committed, pass the <option
+	  role="hg-opt-backout">--merge</option> option to the
+	<command role="hg-cmd">hg backout</command> command.</para>
+
+      &interaction.backout.non-tip.clone;
+
+      <para id="x_fe">This makes backing out any changeset a
+	<quote>one-shot</quote> operation that's usually simple and
+	fast.</para>
+
+      &interaction.backout.non-tip.backout;
+
+      <para id="x_ff">If you take a look at the contents of
+	<filename>myfile</filename> after the backout finishes, you'll
+	see that the first and third changes are present, but not the
+	second.</para>
+
+      &interaction.backout.non-tip.cat;
+
+      <para id="x_100">As the graphical history in <xref
+	  linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial
+	actually commits <emphasis>two</emphasis> changes in this kind
+	of situation (the box-shaped nodes are the ones that Mercurial
+	commits automatically).  Before Mercurial begins the backout
+	process, it first remembers what the current parent of the
+	working directory is.  It then backs out the target changeset,
+	and commits that as a changeset.  Finally, it merges back to
+	the previous parent of the working directory, and commits the
+	result of the merge.</para>
+
+      <para id="x_101">% TODO: to me it looks like mercurial doesn't commit the
+	second merge automatically!</para>
+
+      <figure id="fig:undo:backout-non-tip">
+	<title>Automated backout of a non-tip change using the
+	  <command role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-non-tip.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_103">The result is that you end up <quote>back where you
+	  were</quote>, only with some extra history that undoes the
+	effect of the changeset you wanted to back out.</para>
+
+      <sect3>
+	<title>Always use the <option
+	    role="hg-opt-backout">--merge</option> option</title>
+
+	<para id="x_104">In fact, since the <option
+	    role="hg-opt-backout">--merge</option> option will do the
+	  <quote>right thing</quote> whether or not the changeset
+	  you're backing out is the tip (i.e. it won't try to merge if
+	  it's backing out the tip, since there's no need), you should
+	  <emphasis>always</emphasis> use this option when you run the
+	  <command role="hg-cmd">hg backout</command> command.</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title>Gaining more control of the backout process</title>
+
+      <para id="x_105">While I've recommended that you always use the <option
+	  role="hg-opt-backout">--merge</option> option when backing
+	out a change, the <command role="hg-cmd">hg backout</command>
+	command lets you decide how to merge a backout changeset.
+	Taking control of the backout process by hand is something you
+	will rarely need to do, but it can be useful to understand
+	what the <command role="hg-cmd">hg backout</command> command
+	is doing for you automatically.  To illustrate this, let's
+	clone our first repository, but omit the backout change that
+	it contains.</para>
+
+      &interaction.backout.manual.clone;
+
+      <para id="x_106">As with our
+	earlier example, We'll commit a third changeset, then back out
+	its parent, and see what happens.</para>
+
+      &interaction.backout.manual.backout;
+
+      <para id="x_107">Our new changeset is again a descendant of the changeset
+	we backout out; it's thus a new head, <emphasis>not</emphasis>
+	a descendant of the changeset that was the tip.  The <command
+	  role="hg-cmd">hg backout</command> command was quite
+	explicit in telling us this.</para>
+
+      &interaction.backout.manual.log;
+
+      <para id="x_108">Again, it's easier to see what has happened by looking at
+	a graph of the revision history, in <xref
+	  linkend="fig:undo:backout-manual"/>.  This makes it clear
+	that when we use <command role="hg-cmd">hg backout</command>
+	to back out a change other than the tip, Mercurial adds a new
+	head to the repository (the change it committed is
+	box-shaped).</para>
+
+      <figure id="fig:undo:backout-manual">
+	<title>Backing out a change using the <command
+	    role="hg-cmd">hg backout</command> command</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-manual.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_10a">After the <command role="hg-cmd">hg backout</command>
+	command has completed, it leaves the new
+	<quote>backout</quote> changeset as the parent of the working
+	directory.</para>
+
+      &interaction.backout.manual.parents;
+
+      <para id="x_10b">Now we have two isolated sets of changes.</para>
+
+      &interaction.backout.manual.heads;
+
+      <para id="x_10c">Let's think about what we expect to see as the contents of
+	<filename>myfile</filename> now.  The first change should be
+	present, because we've never backed it out.  The second change
+	should be missing, as that's the change we backed out.  Since
+	the history graph shows the third change as a separate head,
+	we <emphasis>don't</emphasis> expect to see the third change
+	present in <filename>myfile</filename>.</para>
+
+      &interaction.backout.manual.cat;
+
+      <para id="x_10d">To get the third change back into the file, we just do a
+	normal merge of our two heads.</para>
+
+      &interaction.backout.manual.merge;
+
+      <para id="x_10e">Afterwards, the graphical history of our
+	repository looks like
+	<xref linkend="fig:undo:backout-manual-merge"/>.</para>
+
+      <figure id="fig:undo:backout-manual-merge">
+	<title>Manually merging a backout change</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/undo-manual-merge.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+    </sect2>
+    <sect2>
+      <title>Why <command role="hg-cmd">hg backout</command> works as
+	it does</title>
+
+      <para id="x_110">Here's a brief description of how the <command
+	  role="hg-cmd">hg backout</command> command works.</para>
+      <orderedlist>
+	<listitem><para id="x_111">It ensures that the working directory is
+	    <quote>clean</quote>, i.e. that the output of <command
+	      role="hg-cmd">hg status</command> would be empty.</para>
+	</listitem>
+	<listitem><para id="x_112">It remembers the current parent of the working
+	    directory.  Let's call this changeset
+	    <literal>orig</literal></para>
+	</listitem>
+	<listitem><para id="x_113">It does the equivalent of a <command
+	      role="hg-cmd">hg update</command> to sync the working
+	    directory to the changeset you want to back out.  Let's
+	    call this changeset <literal>backout</literal></para>
+	</listitem>
+	<listitem><para id="x_114">It finds the parent of that changeset.  Let's
+	    call that changeset <literal>parent</literal>.</para>
+	</listitem>
+	<listitem><para id="x_115">For each file that the
+	    <literal>backout</literal> changeset affected, it does the
+	    equivalent of a <command role="hg-cmd">hg revert -r
+	      parent</command> on that file, to restore it to the
+	    contents it had before that changeset was
+	    committed.</para>
+	</listitem>
+	<listitem><para id="x_116">It commits the result as a new changeset.
+	    This changeset has <literal>backout</literal> as its
+	    parent.</para>
+	</listitem>
+	<listitem><para id="x_117">If you specify <option
+	      role="hg-opt-backout">--merge</option> on the command
+	    line, it merges with <literal>orig</literal>, and commits
+	    the result of the merge.</para>
+	</listitem></orderedlist>
+
+      <para id="x_118">An alternative way to implement the <command
+	  role="hg-cmd">hg backout</command> command would be to
+	<command role="hg-cmd">hg export</command> the
+	to-be-backed-out changeset as a diff, then use the <option
+	  role="cmd-opt-patch">--reverse</option> option to the
+	<command>patch</command> command to reverse the effect of the
+	change without fiddling with the working directory.  This
+	sounds much simpler, but it would not work nearly as
+	well.</para>
+
+      <para id="x_119">The reason that <command role="hg-cmd">hg
+	  backout</command> does an update, a commit, a merge, and
+	another commit is to give the merge machinery the best chance
+	to do a good job when dealing with all the changes
+	<emphasis>between</emphasis> the change you're backing out and
+	the current tip.</para>
+
+      <para id="x_11a">If you're backing out a changeset that's 100 revisions
+	back in your project's history, the chances that the
+	<command>patch</command> command will be able to apply a
+	reverse diff cleanly are not good, because intervening changes
+	are likely to have <quote>broken the context</quote> that
+	<command>patch</command> uses to determine whether it can
+	apply a patch (if this sounds like gibberish, see <xref
+	  linkend="sec:mq:patch"/> for a
+	discussion of the <command>patch</command> command).  Also,
+	Mercurial's merge machinery will handle files and directories
+	being renamed, permission changes, and modifications to binary
+	files, none of which <command>patch</command> can deal
+	with.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:undo:aaaiiieee">
+    <title>Changes that should never have been</title>
+
+    <para id="x_11b">Most of the time, the <command role="hg-cmd">hg
+	backout</command> command is exactly what you need if you want
+      to undo the effects of a change.  It leaves a permanent record
+      of exactly what you did, both when committing the original
+      changeset and when you cleaned up after it.</para>
+
+    <para id="x_11c">On rare occasions, though, you may find that you've
+      committed a change that really should not be present in the
+      repository at all.  For example, it would be very unusual, and
+      usually considered a mistake, to commit a software project's
+      object files as well as its source files.  Object files have
+      almost no intrinsic value, and they're <emphasis>big</emphasis>,
+      so they increase the size of the repository and the amount of
+      time it takes to clone or pull changes.</para>
+
+    <para id="x_11d">Before I discuss the options that you have if you commit a
+      <quote>brown paper bag</quote> change (the kind that's so bad
+      that you want to pull a brown paper bag over your head), let me
+      first discuss some approaches that probably won't work.</para>
+
+    <para id="x_11e">Since Mercurial treats history as
+      accumulative&emdash;every change builds on top of all changes
+      that preceded it&emdash;you generally can't just make disastrous
+      changes disappear.  The one exception is when you've just
+      committed a change, and it hasn't been pushed or pulled into
+      another repository.  That's when you can safely use the <command
+	role="hg-cmd">hg rollback</command> command, as I detailed in
+      <xref linkend="sec:undo:rollback"/>.</para>
+
+    <para id="x_11f">After you've pushed a bad change to another repository, you
+      <emphasis>could</emphasis> still use <command role="hg-cmd">hg
+	rollback</command> to make your local copy of the change
+      disappear, but it won't have the consequences you want.  The
+      change will still be present in the remote repository, so it
+      will reappear in your local repository the next time you
+      pull.</para>
+
+    <para id="x_120">If a situation like this arises, and you know which
+      repositories your bad change has propagated into, you can
+      <emphasis>try</emphasis> to get rid of the changeefrom
+      <emphasis>every</emphasis> one of those repositories.  This is,
+      of course, not a satisfactory solution: if you miss even a
+      single repository while you're expunging, the change is still
+      <quote>in the wild</quote>, and could propagate further.</para>
+
+    <para id="x_121">If you've committed one or more changes
+      <emphasis>after</emphasis> the change that you'd like to see
+      disappear, your options are further reduced. Mercurial doesn't
+      provide a way to <quote>punch a hole</quote> in history, leaving
+      changesets intact.</para>
+
+    <para id="x_122">XXX This needs filling out.  The
+      <literal>hg-replay</literal> script in the
+      <literal>examples</literal> directory works, but doesn't handle
+      merge changesets.  Kind of an important omission.</para>
+
+    <sect2>
+      <title>Protect yourself from <quote>escaped</quote>
+	changes</title>
+
+      <para id="x_123">If you've committed some changes to your local repository
+	and they've been pushed or pulled somewhere else, this isn't
+	necessarily a disaster.  You can protect yourself ahead of
+	time against some classes of bad changeset.  This is
+	particularly easy if your team usually pulls changes from a
+	central repository.</para>
+
+      <para id="x_124">By configuring some hooks on that repository to validate
+	incoming changesets (see chapter <xref linkend="chap:hook"/>),
+	you can
+	automatically prevent some kinds of bad changeset from being
+	pushed to the central repository at all.  With such a
+	configuration in place, some kinds of bad changeset will
+	naturally tend to <quote>die out</quote> because they can't
+	propagate into the central repository.  Better yet, this
+	happens without any need for explicit intervention.</para>
+
+      <para id="x_125">For instance, an incoming change hook that verifies that a
+	changeset will actually compile can prevent people from
+	inadvertantly <quote>breaking the build</quote>.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:undo:bisect">
+    <title>Finding the source of a bug</title>
+
+    <para id="x_126">While it's all very well to be able to back out a changeset
+      that introduced a bug, this requires that you know which
+      changeset to back out.  Mercurial provides an invaluable
+      command, called <command role="hg-cmd">hg bisect</command>, that
+      helps you to automate this process and accomplish it very
+      efficiently.</para>
+
+    <para id="x_127">The idea behind the <command role="hg-cmd">hg
+	bisect</command> command is that a changeset has introduced
+      some change of behavior that you can identify with a simple
+      binary test.  You don't know which piece of code introduced the
+      change, but you know how to test for the presence of the bug.
+      The <command role="hg-cmd">hg bisect</command> command uses your
+      test to direct its search for the changeset that introduced the
+      code that caused the bug.</para>
+
+    <para id="x_128">Here are a few scenarios to help you understand how you
+      might apply this command.</para>
+    <itemizedlist>
+      <listitem><para id="x_129">The most recent version of your software has a
+	  bug that you remember wasn't present a few weeks ago, but
+	  you don't know when it was introduced.  Here, your binary
+	  test checks for the presence of that bug.</para>
+      </listitem>
+      <listitem><para id="x_12a">You fixed a bug in a rush, and now it's time to
+	  close the entry in your team's bug database.  The bug
+	  database requires a changeset ID when you close an entry,
+	  but you don't remember which changeset you fixed the bug in.
+	  Once again, your binary test checks for the presence of the
+	  bug.</para>
+      </listitem>
+      <listitem><para id="x_12b">Your software works correctly, but runs 15%
+	  slower than the last time you measured it.  You want to know
+	  which changeset introduced the performance regression.  In
+	  this case, your binary test measures the performance of your
+	  software, to see whether it's <quote>fast</quote> or
+	  <quote>slow</quote>.</para>
+      </listitem>
+      <listitem><para id="x_12c">The sizes of the components of your project that
+	  you ship exploded recently, and you suspect that something
+	  changed in the way you build your project.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_12d">From these examples, it should be clear that the <command
+	role="hg-cmd">hg bisect</command> command is not useful only
+      for finding the sources of bugs.  You can use it to find any
+      <quote>emergent property</quote> of a repository (anything that
+      you can't find from a simple text search of the files in the
+      tree) for which you can write a binary test.</para>
+
+    <para id="x_12e">We'll introduce a little bit of terminology here, just to
+      make it clear which parts of the search process are your
+      responsibility, and which are Mercurial's.  A
+      <emphasis>test</emphasis> is something that
+      <emphasis>you</emphasis> run when <command role="hg-cmd">hg
+	bisect</command> chooses a changeset.  A
+      <emphasis>probe</emphasis> is what <command role="hg-cmd">hg
+	bisect</command> runs to tell whether a revision is good.
+      Finally, we'll use the word <quote>bisect</quote>, as both a
+      noun and a verb, to stand in for the phrase <quote>search using
+	the <command role="hg-cmd">hg bisect</command>
+	command</quote>.</para>
+
+    <para id="x_12f">One simple way to automate the searching process would be
+      simply to probe every changeset.  However, this scales poorly.
+      If it took ten minutes to test a single changeset, and you had
+      10,000 changesets in your repository, the exhaustive approach
+      would take on average 35 <emphasis>days</emphasis> to find the
+      changeset that introduced a bug.  Even if you knew that the bug
+      was introduced by one of the last 500 changesets, and limited
+      your search to those, you'd still be looking at over 40 hours to
+      find the changeset that introduced your bug.</para>
+
+    <para id="x_130">What the <command role="hg-cmd">hg bisect</command> command
+      does is use its knowledge of the <quote>shape</quote> of your
+      project's revision history to perform a search in time
+      proportional to the <emphasis>logarithm</emphasis> of the number
+      of changesets to check (the kind of search it performs is called
+      a dichotomic search).  With this approach, searching through
+      10,000 changesets will take less than three hours, even at ten
+      minutes per test (the search will require about 14 tests).
+      Limit your search to the last hundred changesets, and it will
+      take only about an hour (roughly seven tests).</para>
+
+    <para id="x_131">The <command role="hg-cmd">hg bisect</command> command is
+      aware of the <quote>branchy</quote> nature of a Mercurial
+      project's revision history, so it has no problems dealing with
+      branches, merges, or multiple heads in a repository.  It can
+      prune entire branches of history with a single probe, which is
+      how it operates so efficiently.</para>
+
+    <sect2>
+      <title>Using the <command role="hg-cmd">hg bisect</command>
+	command</title>
+
+      <para id="x_132">Here's an example of <command role="hg-cmd">hg
+	  bisect</command> in action.</para>
+
+      <note>
+	<para id="x_133">  In versions 0.9.5 and earlier of Mercurial, <command
+	    role="hg-cmd">hg bisect</command> was not a core command:
+	  it was distributed with Mercurial as an extension. This
+	  section describes the built-in command, not the old
+	  extension.</para>
+      </note>
+
+      <para id="x_134">Now let's create a repository, so that we can try out the
+	<command role="hg-cmd">hg bisect</command> command in
+	isolation.</para>
+
+      &interaction.bisect.init;
+
+      <para id="x_135">We'll simulate a project that has a bug in it in a
+	simple-minded way: create trivial changes in a loop, and
+	nominate one specific change that will have the
+	<quote>bug</quote>.  This loop creates 35 changesets, each
+	adding a single file to the repository. We'll represent our
+	<quote>bug</quote> with a file that contains the text <quote>i
+	  have a gub</quote>.</para>
+
+      &interaction.bisect.commits;
+
+      <para id="x_136">The next thing that we'd like to do is figure out how to
+	use the <command role="hg-cmd">hg bisect</command> command.
+	We can use Mercurial's normal built-in help mechanism for
+	this.</para>
+
+      &interaction.bisect.help;
+
+      <para id="x_137">The <command role="hg-cmd">hg bisect</command> command
+	works in steps.  Each step proceeds as follows.</para>
+      <orderedlist>
+	<listitem><para id="x_138">You run your binary test.</para>
+	  <itemizedlist>
+	    <listitem><para id="x_139">If the test succeeded, you tell <command
+		  role="hg-cmd">hg bisect</command> by running the
+		<command role="hg-cmd">hg bisect good</command>
+		command.</para>
+	    </listitem>
+	    <listitem><para id="x_13a">If it failed, run the <command
+		  role="hg-cmd">hg bisect bad</command>
+		command.</para></listitem></itemizedlist>
+	</listitem>
+	<listitem><para id="x_13b">The command uses your information to decide
+	    which changeset to test next.</para>
+	</listitem>
+	<listitem><para id="x_13c">It updates the working directory to that
+	    changeset, and the process begins again.</para>
+	</listitem></orderedlist>
+      <para id="x_13d">The process ends when <command role="hg-cmd">hg
+	  bisect</command> identifies a unique changeset that marks
+	the point where your test transitioned from
+	<quote>succeeding</quote> to <quote>failing</quote>.</para>
+
+      <para id="x_13e">To start the search, we must run the <command
+	  role="hg-cmd">hg bisect --reset</command> command.</para>
+
+      &interaction.bisect.search.init;
+
+      <para id="x_13f">In our case, the binary test we use is simple: we check to
+	see if any file in the repository contains the string <quote>i
+	  have a gub</quote>.  If it does, this changeset contains the
+	change that <quote>caused the bug</quote>.  By convention, a
+	changeset that has the property we're searching for is
+	<quote>bad</quote>, while one that doesn't is
+	<quote>good</quote>.</para>
+
+      <para id="x_140">Most of the time, the revision to which the working
+	directory is synced (usually the tip) already exhibits the
+	problem introduced by the buggy change, so we'll mark it as
+	<quote>bad</quote>.</para>
+
+      &interaction.bisect.search.bad-init;
+
+      <para id="x_141">Our next task is to nominate a changeset that we know
+	<emphasis>doesn't</emphasis> have the bug; the <command
+	  role="hg-cmd">hg bisect</command> command will
+	<quote>bracket</quote> its search between the first pair of
+	good and bad changesets.  In our case, we know that revision
+	10 didn't have the bug.  (I'll have more words about choosing
+	the first <quote>good</quote> changeset later.)</para>
+
+      &interaction.bisect.search.good-init;
+
+      <para id="x_142">Notice that this command printed some output.</para>
+      <itemizedlist>
+	<listitem><para id="x_143">It told us how many changesets it must
+	    consider before it can identify the one that introduced
+	    the bug, and how many tests that will require.</para>
+	</listitem>
+	<listitem><para id="x_144">It updated the working directory to the next
+	    changeset to test, and told us which changeset it's
+	    testing.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_145">We now run our test in the working directory.  We use the
+	<command>grep</command> command to see if our
+	<quote>bad</quote> file is present in the working directory.
+	If it is, this revision is bad; if not, this revision is good.
+	&interaction.bisect.search.step1;</para>
+
+      <para id="x_146">This test looks like a perfect candidate for automation,
+	so let's turn it into a shell function.</para>
+      &interaction.bisect.search.mytest;
+
+      <para id="x_147">We can now run an entire test step with a single command,
+	<literal>mytest</literal>.</para>
+
+      &interaction.bisect.search.step2;
+
+      <para id="x_148">A few more invocations of our canned test step command,
+	and we're done.</para>
+
+      &interaction.bisect.search.rest;
+
+      <para id="x_149">Even though we had 40 changesets to search through, the
+	<command role="hg-cmd">hg bisect</command> command let us find
+	the changeset that introduced our <quote>bug</quote> with only
+	five tests.  Because the number of tests that the <command
+	  role="hg-cmd">hg bisect</command> command performs grows
+	logarithmically with the number of changesets to search, the
+	advantage that it has over the <quote>brute force</quote>
+	search approach increases with every changeset you add.</para>
+
+    </sect2>
+    <sect2>
+      <title>Cleaning up after your search</title>
+
+      <para id="x_14a">When you're finished using the <command role="hg-cmd">hg
+	  bisect</command> command in a repository, you can use the
+	<command role="hg-cmd">hg bisect reset</command> command to
+	drop the information it was using to drive your search.  The
+	command doesn't use much space, so it doesn't matter if you
+	forget to run this command.  However, <command
+	  role="hg-cmd">hg bisect</command> won't let you start a new
+	search in that repository until you do a <command
+	  role="hg-cmd">hg bisect reset</command>.</para>
+
+      &interaction.bisect.search.reset;
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Tips for finding bugs effectively</title>
+
+    <sect2>
+      <title>Give consistent input</title>
+
+      <para id="x_14b">The <command role="hg-cmd">hg bisect</command> command
+	requires that you correctly report the result of every test
+	you perform.  If you tell it that a test failed when it really
+	succeeded, it <emphasis>might</emphasis> be able to detect the
+	inconsistency.  If it can identify an inconsistency in your
+	reports, it will tell you that a particular changeset is both
+	good and bad. However, it can't do this perfectly; it's about
+	as likely to report the wrong changeset as the source of the
+	bug.</para>
+
+    </sect2>
+    <sect2>
+      <title>Automate as much as possible</title>
+
+      <para id="x_14c">When I started using the <command role="hg-cmd">hg
+	  bisect</command> command, I tried a few times to run my
+	tests by hand, on the command line.  This is an approach that
+	I, at least, am not suited to.  After a few tries, I found
+	that I was making enough mistakes that I was having to restart
+	my searches several times before finally getting correct
+	results.</para>
+
+      <para id="x_14d">My initial problems with driving the <command
+	  role="hg-cmd">hg bisect</command> command by hand occurred
+	even with simple searches on small repositories; if the
+	problem you're looking for is more subtle, or the number of
+	tests that <command role="hg-cmd">hg bisect</command> must
+	perform increases, the likelihood of operator error ruining
+	the search is much higher.  Once I started automating my
+	tests, I had much better results.</para>
+
+      <para id="x_14e">The key to automated testing is twofold:</para>
+      <itemizedlist>
+	<listitem><para id="x_14f">always test for the same symptom, and</para>
+	</listitem>
+	<listitem><para id="x_150">always feed consistent input to the <command
+	      role="hg-cmd">hg bisect</command> command.</para>
+	</listitem></itemizedlist>
+      <para id="x_151">In my tutorial example above, the <command>grep</command>
+	command tests for the symptom, and the <literal>if</literal>
+	statement takes the result of this check and ensures that we
+	always feed the same input to the <command role="hg-cmd">hg
+	  bisect</command> command.  The <literal>mytest</literal>
+	function marries these together in a reproducible way, so that
+	every test is uniform and consistent.</para>
+
+    </sect2>
+    <sect2>
+      <title>Check your results</title>
+
+      <para id="x_152">Because the output of a <command role="hg-cmd">hg
+	  bisect</command> search is only as good as the input you
+	give it, don't take the changeset it reports as the absolute
+	truth.  A simple way to cross-check its report is to manually
+	run your test at each of the following changesets:</para>
+      <itemizedlist>
+	<listitem><para id="x_153">The changeset that it reports as the first bad
+	    revision.  Your test should still report this as
+	    bad.</para>
+	</listitem>
+	<listitem><para id="x_154">The parent of that changeset (either parent,
+	    if it's a merge). Your test should report this changeset
+	    as good.</para>
+	</listitem>
+	<listitem><para id="x_155">A child of that changeset.  Your test should
+	    report this changeset as bad.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Beware interference between bugs</title>
+
+      <para id="x_156">It's possible that your search for one bug could be
+	disrupted by the presence of another.  For example, let's say
+	your software crashes at revision 100, and worked correctly at
+	revision 50.  Unknown to you, someone else introduced a
+	different crashing bug at revision 60, and fixed it at
+	revision 80.  This could distort your results in one of
+	several ways.</para>
+
+      <para id="x_157">It is possible that this other bug completely
+	<quote>masks</quote> yours, which is to say that it occurs
+	before your bug has a chance to manifest itself.  If you can't
+	avoid that other bug (for example, it prevents your project
+	from building), and so can't tell whether your bug is present
+	in a particular changeset, the <command role="hg-cmd">hg
+	  bisect</command> command cannot help you directly.  Instead,
+	you can mark a changeset as untested by running <command
+	  role="hg-cmd">hg bisect --skip</command>.</para>
+
+      <para id="x_158">A different problem could arise if your test for a bug's
+	presence is not specific enough.  If you check for <quote>my
+	  program crashes</quote>, then both your crashing bug and an
+	unrelated crashing bug that masks it will look like the same
+	thing, and mislead <command role="hg-cmd">hg
+	  bisect</command>.</para>
+
+      <para id="x_159">Another useful situation in which to use <command
+	  role="hg-cmd">hg bisect --skip</command> is if you can't
+	test a revision because your project was in a broken and hence
+	untestable state at that revision, perhaps because someone
+	checked in a change that prevented the project from
+	building.</para>
+
+    </sect2>
+    <sect2>
+      <title>Bracket your search lazily</title>
+
+      <para id="x_15a">Choosing the first <quote>good</quote> and
+	<quote>bad</quote> changesets that will mark the end points of
+	your search is often easy, but it bears a little discussion
+	nevertheless.  From the perspective of <command
+	  role="hg-cmd">hg bisect</command>, the <quote>newest</quote>
+	changeset is conventionally <quote>bad</quote>, and the older
+	changeset is <quote>good</quote>.</para>
+
+      <para id="x_15b">If you're having trouble remembering when a suitable
+	<quote>good</quote> change was, so that you can tell <command
+	  role="hg-cmd">hg bisect</command>, you could do worse than
+	testing changesets at random.  Just remember to eliminate
+	contenders that can't possibly exhibit the bug (perhaps
+	because the feature with the bug isn't present yet) and those
+	where another problem masks the bug (as I discussed
+	above).</para>
+
+      <para id="x_15c">Even if you end up <quote>early</quote> by thousands of
+	changesets or months of history, you will only add a handful
+	of tests to the total number that <command role="hg-cmd">hg
+	  bisect</command> must perform, thanks to its logarithmic
+	behavior.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch09-hook.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2038 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:hook">
+  <?dbhtml filename="handling-repository-events-with-hooks.html"?>
+  <title>Handling repository events with hooks</title>
+
+  <para id="x_1e6">Mercurial offers a powerful mechanism to let you perform
+    automated actions in response to events that occur in a
+    repository.  In some cases, you can even control Mercurial's
+    response to those events.</para>
+
+  <para id="x_1e7">The name Mercurial uses for one of these actions is a
+    <emphasis>hook</emphasis>. Hooks are called
+    <quote>triggers</quote> in some revision control systems, but the
+    two names refer to the same idea.</para>
+
+  <sect1>
+    <title>An overview of hooks in Mercurial</title>
+
+    <para id="x_1e8">Here is a brief list of the hooks that Mercurial
+      supports. We will revisit each of these hooks in more detail
+      later, in <xref linkend="sec:hook:ref"/>.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_1e9"><literal role="hook">changegroup</literal>: This
+	  is run after a group of changesets has been brought into the
+	  repository from elsewhere.</para>
+      </listitem>
+      <listitem><para id="x_1ea"><literal role="hook">commit</literal>: This is
+	  run after a new changeset has been created in the local
+	  repository.</para>
+      </listitem>
+      <listitem><para id="x_1eb"><literal role="hook">incoming</literal>: This is
+	  run once for each new changeset that is brought into the
+	  repository from elsewhere.  Notice the difference from
+	  <literal role="hook">changegroup</literal>, which is run
+	  once per <emphasis>group</emphasis> of changesets brought
+	  in.</para>
+      </listitem>
+      <listitem><para id="x_1ec"><literal role="hook">outgoing</literal>: This is
+	  run after a group of changesets has been transmitted from
+	  this repository.</para>
+      </listitem>
+      <listitem><para id="x_1ed"><literal role="hook">prechangegroup</literal>:
+	  This is run before starting to bring a group of changesets
+	  into the repository.
+	</para>
+      </listitem>
+      <listitem><para id="x_1ee"><literal role="hook">precommit</literal>:
+	  Controlling. This is run before starting a commit.
+	</para>
+      </listitem>
+      <listitem><para id="x_1ef"><literal role="hook">preoutgoing</literal>:
+	  Controlling. This is run before starting to transmit a group
+	  of changesets from this repository.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f0"><literal role="hook">pretag</literal>:
+	  Controlling. This is run before creating a tag.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f1"><literal
+	    role="hook">pretxnchangegroup</literal>: Controlling. This
+	  is run after a group of changesets has been brought into the
+	  local repository from another, but before the transaction
+	  completes that will make the changes permanent in the
+	  repository.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f2"><literal role="hook">pretxncommit</literal>:
+	  Controlling. This is run after a new changeset has been
+	  created in the local repository, but before the transaction
+	  completes that will make it permanent.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f3"><literal role="hook">preupdate</literal>:
+	  Controlling. This is run before starting an update or merge
+	  of the working directory.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f4"><literal role="hook">tag</literal>: This is run
+	  after a tag is created.
+	</para>
+      </listitem>
+      <listitem><para id="x_1f5"><literal role="hook">update</literal>: This is
+	  run after an update or merge of the working directory has
+	  finished.
+	</para>
+      </listitem></itemizedlist>
+    <para id="x_1f6">Each of the hooks whose description begins with the word
+      <quote>Controlling</quote> has the ability to determine whether
+      an activity can proceed.  If the hook succeeds, the activity may
+      proceed; if it fails, the activity is either not permitted or
+      undone, depending on the hook.
+    </para>
+
+  </sect1>
+  <sect1>
+    <title>Hooks and security</title>
+
+    <sect2>
+      <title>Hooks are run with your privileges</title>
+
+      <para id="x_1f7">When you run a Mercurial command in a repository, and the
+	command causes a hook to run, that hook runs on
+	<emphasis>your</emphasis> system, under
+	<emphasis>your</emphasis> user account, with
+	<emphasis>your</emphasis> privilege level.  Since hooks are
+	arbitrary pieces of executable code, you should treat them
+	with an appropriate level of suspicion.  Do not install a hook
+	unless you are confident that you know who created it and what
+	it does.
+      </para>
+
+      <para id="x_1f8">In some cases, you may be exposed to hooks that you did
+	not install yourself.  If you work with Mercurial on an
+	unfamiliar system, Mercurial will run hooks defined in that
+	system's global <filename role="special">~/.hgrc</filename>
+	file.
+      </para>
+
+      <para id="x_1f9">If you are working with a repository owned by another
+	user, Mercurial can run hooks defined in that user's
+	repository, but it will still run them as <quote>you</quote>.
+	For example, if you <command role="hg-cmd">hg pull</command>
+	from that repository, and its <filename
+	  role="special">.hg/hgrc</filename> defines a local <literal
+	  role="hook">outgoing</literal> hook, that hook will run
+	under your user account, even though you don't own that
+	repository.
+      </para>
+
+      <note>
+	<para id="x_1fa">  This only applies if you are pulling from a repository
+	  on a local or network filesystem.  If you're pulling over
+	  http or ssh, any <literal role="hook">outgoing</literal>
+	  hook will run under whatever account is executing the server
+	  process, on the server.
+	</para>
+      </note>
+
+      <para id="x_1fb">XXX To see what hooks are defined in a repository, use the
+	<command role="hg-cmd">hg config hooks</command> command.  If
+	you are working in one repository, but talking to another that
+	you do not own (e.g. using <command role="hg-cmd">hg
+	  pull</command> or <command role="hg-cmd">hg
+	  incoming</command>), remember that it is the other
+	repository's hooks you should be checking, not your own.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Hooks do not propagate</title>
+
+      <para id="x_1fc">In Mercurial, hooks are not revision controlled, and do
+	not propagate when you clone, or pull from, a repository.  The
+	reason for this is simple: a hook is a completely arbitrary
+	piece of executable code.  It runs under your user identity,
+	with your privilege level, on your machine.
+      </para>
+
+      <para id="x_1fd">It would be extremely reckless for any distributed
+	revision control system to implement revision-controlled
+	hooks, as this would offer an easily exploitable way to
+	subvert the accounts of users of the revision control system.
+      </para>
+
+      <para id="x_1fe">Since Mercurial does not propagate hooks, if you are
+	collaborating with other people on a common project, you
+	should not assume that they are using the same Mercurial hooks
+	as you are, or that theirs are correctly configured.  You
+	should document the hooks you expect people to use.
+      </para>
+
+      <para id="x_1ff">In a corporate intranet, this is somewhat easier to
+	control, as you can for example provide a
+	<quote>standard</quote> installation of Mercurial on an NFS
+	filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will
+	see.  However, this too has its limits; see below.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Hooks can be overridden</title>
+
+      <para id="x_200">Mercurial allows you to override a hook definition by
+	redefining the hook.  You can disable it by setting its value
+	to the empty string, or change its behavior as you wish.
+      </para>
+
+      <para id="x_201">If you deploy a system- or site-wide <filename
+	  role="special">~/.hgrc</filename> file that defines some
+	hooks, you should thus understand that your users can disable
+	or override those hooks.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Ensuring that critical hooks are run</title>
+
+      <para id="x_202">Sometimes you may want to enforce a policy that you do not
+	want others to be able to work around.  For example, you may
+	have a requirement that every changeset must pass a rigorous
+	set of tests.  Defining this requirement via a hook in a
+	site-wide <filename role="special">~/.hgrc</filename> won't
+	work for remote users on laptops, and of course local users
+	can subvert it at will by overriding the hook.
+      </para>
+
+      <para id="x_203">Instead, you can set up your policies for use of Mercurial
+	so that people are expected to propagate changes through a
+	well-known <quote>canonical</quote> server that you have
+	locked down and configured appropriately.
+      </para>
+
+      <para id="x_204">One way to do this is via a combination of social
+	engineering and technology.  Set up a restricted-access
+	account; users can push changes over the network to
+	repositories managed by this account, but they cannot log into
+	the account and run normal shell commands.  In this scenario,
+	a user can commit a changeset that contains any old garbage
+	they want.
+      </para>
+
+      <para id="x_205">When someone pushes a changeset to the server that
+	everyone pulls from, the server will test the changeset before
+	it accepts it as permanent, and reject it if it fails to pass
+	the test suite.  If people only pull changes from this
+	filtering server, it will serve to ensure that all changes
+	that people pull have been automatically vetted.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Care with <literal>pretxn</literal> hooks in a
+      shared-access repository</title>
+
+    <para id="x_206">If you want to use hooks to do some automated work in a
+      repository that a number of people have shared access to, you
+      need to be careful in how you do this.
+    </para>
+
+    <para id="x_207">Mercurial only locks a repository when it is writing to the
+      repository, and only the parts of Mercurial that write to the
+      repository pay attention to locks.  Write locks are necessary to
+      prevent multiple simultaneous writers from scribbling on each
+      other's work, corrupting the repository.
+    </para>
+
+    <para id="x_208">Because Mercurial is careful with the order in which it
+      reads and writes data, it does not need to acquire a lock when
+      it wants to read data from the repository.  The parts of
+      Mercurial that read from the repository never pay attention to
+      locks.  This lockless reading scheme greatly increases
+      performance and concurrency.
+    </para>
+
+    <para id="x_209">With great performance comes a trade-off, though, one which
+      has the potential to cause you trouble unless you're aware of
+      it.  To describe this requires a little detail about how
+      Mercurial adds changesets to a repository and reads those
+      changes.
+    </para>
+
+    <para id="x_20a">When Mercurial <emphasis>writes</emphasis> metadata, it
+      writes it straight into the destination file.  It writes file
+      data first, then manifest data (which contains pointers to the
+      new file data), then changelog data (which contains pointers to
+      the new manifest data).  Before the first write to each file, it
+      stores a record of where the end of the file was in its
+      transaction log.  If the transaction must be rolled back,
+      Mercurial simply truncates each file back to the size it was
+      before the transaction began.
+    </para>
+
+    <para id="x_20b">When Mercurial <emphasis>reads</emphasis> metadata, it reads
+      the changelog first, then everything else.  Since a reader will
+      only access parts of the manifest or file metadata that it can
+      see in the changelog, it can never see partially written data.
+    </para>
+
+    <para id="x_20c">Some controlling hooks (<literal
+	role="hook">pretxncommit</literal> and <literal
+	role="hook">pretxnchangegroup</literal>) run when a
+      transaction is almost complete. All of the metadata has been
+      written, but Mercurial can still roll the transaction back and
+      cause the newly-written data to disappear.
+    </para>
+
+    <para id="x_20d">If one of these hooks runs for long, it opens a window of
+      time during which a reader can see the metadata for changesets
+      that are not yet permanent, and should not be thought of as
+      <quote>really there</quote>.  The longer the hook runs, the
+      longer that window is open.
+    </para>
+
+    <sect2>
+      <title>The problem illustrated</title>
+
+      <para id="x_20e">In principle, a good use for the <literal
+	  role="hook">pretxnchangegroup</literal> hook would be to
+	automatically build and test incoming changes before they are
+	accepted into a central repository.  This could let you
+	guarantee that nobody can push changes to this repository that
+	<quote>break the build</quote>. But if a client can pull
+	changes while they're being tested, the usefulness of the test
+	is zero; an unsuspecting someone can pull untested changes,
+	potentially breaking their build.
+      </para>
+
+      <para id="x_20f">The safest technological answer to this challenge is to
+	set up such a <quote>gatekeeper</quote> repository as
+	<emphasis>unidirectional</emphasis>.  Let it take changes
+	pushed in from the outside, but do not allow anyone to pull
+	changes from it (use the <literal
+	  role="hook">preoutgoing</literal> hook to lock it down).
+	Configure a <literal role="hook">changegroup</literal> hook so
+	that if a build or test succeeds, the hook will push the new
+	changes out to another repository that people
+	<emphasis>can</emphasis> pull from.
+      </para>
+
+      <para id="x_210">In practice, putting a centralised bottleneck like this in
+	place is not often a good idea, and transaction visibility has
+	nothing to do with the problem.  As the size of a
+	project&emdash;and the time it takes to build and
+	test&emdash;grows, you rapidly run into a wall with this
+	<quote>try before you buy</quote> approach, where you have
+	more changesets to test than time in which to deal with them.
+	The inevitable result is frustration on the part of all
+	involved.
+      </para>
+
+      <para id="x_211">An approach that scales better is to get people to build
+	and test before they push, then run automated builds and tests
+	centrally <emphasis>after</emphasis> a push, to be sure all is
+	well.  The advantage of this approach is that it does not
+	impose a limit on the rate at which the repository can accept
+	changes.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:hook:simple">
+    <title>A short tutorial on using hooks</title>
+
+    <para id="x_212">It is easy to write a Mercurial hook.  Let's start with a
+      hook that runs when you finish a <command role="hg-cmd">hg
+	commit</command>, and simply prints the hash of the changeset
+      you just created.  The hook is called <literal
+	role="hook">commit</literal>.
+    </para>
+
+    <para id="x_213">All hooks follow the pattern in this example.</para>
+
+&interaction.hook.simple.init;
+
+    <para id="x_214">You add an entry to the <literal
+	role="rc-hooks">hooks</literal> section of your <filename
+	role="special">~/.hgrc</filename>.  On the left is the name of
+      the event to trigger on; on the right is the action to take.  As
+      you can see, you can run an arbitrary shell command in a hook.
+      Mercurial passes extra information to the hook using environment
+      variables (look for <envar>HG_NODE</envar> in the example).
+    </para>
+
+    <sect2>
+      <title>Performing multiple actions per event</title>
+
+      <para id="x_215">Quite often, you will want to define more than one hook
+	for a particular kind of event, as shown below.</para>
+
+&interaction.hook.simple.ext;
+
+      <para id="x_216">Mercurial lets you do this by adding an
+	<emphasis>extension</emphasis> to the end of a hook's name.
+	You extend a hook's name by giving the name of the hook,
+	followed by a full stop (the
+	<quote><literal>.</literal></quote> character), followed by
+	some more text of your choosing.  For example, Mercurial will
+	run both <literal>commit.foo</literal> and
+	<literal>commit.bar</literal> when the
+	<literal>commit</literal> event occurs.
+      </para>
+
+      <para id="x_217">To give a well-defined order of execution when there are
+	multiple hooks defined for an event, Mercurial sorts hooks by
+	extension, and executes the hook commands in this sorted
+	order.  In the above example, it will execute
+	<literal>commit.bar</literal> before
+	<literal>commit.foo</literal>, and <literal>commit</literal>
+	before both.
+      </para>
+
+      <para id="x_218">It is a good idea to use a somewhat descriptive
+	extension when you define a new hook.  This will help you to
+	remember what the hook was for.  If the hook fails, you'll get
+	an error message that contains the hook name and extension, so
+	using a descriptive extension could give you an immediate hint
+	as to why the hook failed (see <xref
+	  linkend="sec:hook:perm"/> for an example).
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:perm">
+      <title>Controlling whether an activity can proceed</title>
+
+      <para id="x_219">In our earlier examples, we used the <literal
+	  role="hook">commit</literal> hook, which is run after a
+	commit has completed.  This is one of several Mercurial hooks
+	that run after an activity finishes.  Such hooks have no way
+	of influencing the activity itself.
+      </para>
+
+      <para id="x_21a">Mercurial defines a number of events that occur before an
+	activity starts; or after it starts, but before it finishes.
+	Hooks that trigger on these events have the added ability to
+	choose whether the activity can continue, or will abort.
+      </para>
+
+      <para id="x_21b">The <literal role="hook">pretxncommit</literal> hook runs
+	after a commit has all but completed.  In other words, the
+	metadata representing the changeset has been written out to
+	disk, but the transaction has not yet been allowed to
+	complete.  The <literal role="hook">pretxncommit</literal>
+	hook has the ability to decide whether the transaction can
+	complete, or must be rolled back.
+      </para>
+
+      <para id="x_21c">If the <literal role="hook">pretxncommit</literal> hook
+	exits with a status code of zero, the transaction is allowed
+	to complete; the commit finishes; and the <literal
+	  role="hook">commit</literal> hook is run.  If the <literal
+	  role="hook">pretxncommit</literal> hook exits with a
+	non-zero status code, the transaction is rolled back; the
+	metadata representing the changeset is erased; and the
+	<literal role="hook">commit</literal> hook is not run.
+      </para>
+
+&interaction.hook.simple.pretxncommit;
+
+      <para id="x_21d">The hook in the example above checks that a commit comment
+	contains a bug ID.  If it does, the commit can complete.  If
+	not, the commit is rolled back.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Writing your own hooks</title>
+
+    <para id="x_21e">When you are writing a hook, you might find it useful to run
+      Mercurial either with the <option
+	role="hg-opt-global">-v</option> option, or the <envar
+	role="rc-item-ui">verbose</envar> config item set to
+      <quote>true</quote>.  When you do so, Mercurial will print a
+      message before it calls each hook.
+    </para>
+
+    <sect2 id="sec:hook:lang">
+      <title>Choosing how your hook should run</title>
+
+      <para id="x_21f">You can write a hook either as a normal
+	program&emdash;typically a shell script&emdash;or as a Python
+	function that is executed within the Mercurial process.
+      </para>
+
+      <para id="x_220">Writing a hook as an external program has the advantage
+	that it requires no knowledge of Mercurial's internals.  You
+	can call normal Mercurial commands to get any added
+	information you need.  The trade-off is that external hooks
+	are slower than in-process hooks.
+      </para>
+
+      <para id="x_221">An in-process Python hook has complete access to the
+	Mercurial API, and does not <quote>shell out</quote> to
+	another process, so it is inherently faster than an external
+	hook.  It is also easier to obtain much of the information
+	that a hook requires by using the Mercurial API than by
+	running Mercurial commands.
+      </para>
+
+      <para id="x_222">If you are comfortable with Python, or require high
+	performance, writing your hooks in Python may be a good
+	choice.  However, when you have a straightforward hook to
+	write and you don't need to care about performance (probably
+	the majority of hooks), a shell script is perfectly fine.
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:param">
+      <title>Hook parameters</title>
+
+      <para id="x_223">Mercurial calls each hook with a set of well-defined
+	parameters.  In Python, a parameter is passed as a keyword
+	argument to your hook function.  For an external program, a
+	parameter is passed as an environment variable.
+      </para>
+
+      <para id="x_224">Whether your hook is written in Python or as a shell
+	script, the hook-specific parameter names and values will be
+	the same.  A boolean parameter will be represented as a
+	boolean value in Python, but as the number 1 (for
+	<quote>true</quote>) or 0 (for <quote>false</quote>) as an
+	environment variable for an external hook.  If a hook
+	parameter is named <literal>foo</literal>, the keyword
+	argument for a Python hook will also be named
+	<literal>foo</literal>, while the environment variable for an
+	external hook will be named <literal>HG_FOO</literal>.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Hook return values and activity control</title>
+
+      <para id="x_225">A hook that executes successfully must exit with a status
+	of zero if external, or return boolean <quote>false</quote> if
+	in-process.  Failure is indicated with a non-zero exit status
+	from an external hook, or an in-process hook returning boolean
+	<quote>true</quote>.  If an in-process hook raises an
+	exception, the hook is considered to have failed.
+      </para>
+
+      <para id="x_226">For a hook that controls whether an activity can proceed,
+	zero/false means <quote>allow</quote>, while
+	non-zero/true/exception means <quote>deny</quote>.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Writing an external hook</title>
+
+      <para id="x_227">When you define an external hook in your <filename
+	  role="special">~/.hgrc</filename> and the hook is run, its
+	value is passed to your shell, which interprets it.  This
+	means that you can use normal shell constructs in the body of
+	the hook.
+      </para>
+
+      <para id="x_228">An executable hook is always run with its current
+	directory set to a repository's root directory.
+      </para>
+
+      <para id="x_229">Each hook parameter is passed in as an environment
+	variable; the name is upper-cased, and prefixed with the
+	string <quote><literal>HG_</literal></quote>.
+      </para>
+
+      <para id="x_22a">With the exception of hook parameters, Mercurial does not
+	set or modify any environment variables when running a hook.
+	This is useful to remember if you are writing a site-wide hook
+	that may be run by a number of different users with differing
+	environment variables set. In multi-user situations, you
+	should not rely on environment variables being set to the
+	values you have in your environment when testing the hook.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Telling Mercurial to use an in-process hook</title>
+
+      <para id="x_22b">The <filename role="special">~/.hgrc</filename> syntax
+	for defining an in-process hook is slightly different than for
+	an executable hook.  The value of the hook must start with the
+	text <quote><literal>python:</literal></quote>, and continue
+	with the fully-qualified name of a callable object to use as
+	the hook's value.
+      </para>
+
+      <para id="x_22c">The module in which a hook lives is automatically imported
+	when a hook is run.  So long as you have the module name and
+	<envar>PYTHONPATH</envar> right, it should <quote>just
+	  work</quote>.
+      </para>
+
+      <para id="x_22d">The following <filename role="special">~/.hgrc</filename>
+	example snippet illustrates the syntax and meaning of the
+	notions we just described.
+      </para>
+      <programlisting>[hooks]
+commit.example = python:mymodule.submodule.myhook</programlisting>
+      <para id="x_22e">When Mercurial runs the <literal>commit.example</literal>
+	hook, it imports <literal>mymodule.submodule</literal>, looks
+	for the callable object named <literal>myhook</literal>, and
+	calls it.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Writing an in-process hook</title>
+
+      <para id="x_22f">The simplest in-process hook does nothing, but illustrates
+	the basic shape of the hook API:
+      </para>
+      <programlisting>def myhook(ui, repo, **kwargs):
+    pass</programlisting>
+      <para id="x_230">The first argument to a Python hook is always a <literal
+	  role="py-mod-mercurial.ui">ui</literal> object.  The second
+	is a repository object; at the moment, it is always an
+	instance of <literal
+	  role="py-mod-mercurial.localrepo">localrepository</literal>.
+	Following these two arguments are other keyword arguments.
+	Which ones are passed in depends on the hook being called, but
+	a hook can ignore arguments it doesn't care about by dropping
+	them into a keyword argument dict, as with
+	<literal>**kwargs</literal> above.
+      </para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Some hook examples</title>
+
+    <sect2>
+      <title>Writing meaningful commit messages</title>
+
+      <para id="x_231">It's hard to imagine a useful commit message being very
+	short. The simple <literal role="hook">pretxncommit</literal>
+	hook of the example below will prevent you from committing a
+	changeset with a message that is less than ten bytes long.
+      </para>
+
+&interaction.hook.msglen.go;
+
+    </sect2>
+    <sect2>
+      <title>Checking for trailing whitespace</title>
+
+      <para id="x_232">An interesting use of a commit-related hook is to help you
+	to write cleaner code.  A simple example of <quote>cleaner
+	  code</quote> is the dictum that a change should not add any
+	new lines of text that contain <quote>trailing
+	  whitespace</quote>.  Trailing whitespace is a series of
+	space and tab characters at the end of a line of text.  In
+	most cases, trailing whitespace is unnecessary, invisible
+	noise, but it is occasionally problematic, and people often
+	prefer to get rid of it.
+      </para>
+
+      <para id="x_233">You can use either the <literal
+	  role="hook">precommit</literal> or <literal
+	  role="hook">pretxncommit</literal> hook to tell whether you
+	have a trailing whitespace problem.  If you use the <literal
+	  role="hook">precommit</literal> hook, the hook will not know
+	which files you are committing, so it will have to check every
+	modified file in the repository for trailing white space.  If
+	you want to commit a change to just the file
+	<filename>foo</filename>, but the file
+	<filename>bar</filename> contains trailing whitespace, doing a
+	check in the <literal role="hook">precommit</literal> hook
+	will prevent you from committing <filename>foo</filename> due
+	to the problem with <filename>bar</filename>.  This doesn't
+	seem right.
+      </para>
+
+      <para id="x_234">Should you choose the <literal
+	  role="hook">pretxncommit</literal> hook, the check won't
+	occur until just before the transaction for the commit
+	completes.  This will allow you to check for problems only the
+	exact files that are being committed.  However, if you entered
+	the commit message interactively and the hook fails, the
+	transaction will roll back; you'll have to re-enter the commit
+	message after you fix the trailing whitespace and run <command
+	  role="hg-cmd">hg commit</command> again.
+      </para>
+
+&interaction.hook.ws.simple;
+
+      <para id="x_235">In this example, we introduce a simple <literal
+	  role="hook">pretxncommit</literal> hook that checks for
+	trailing whitespace.  This hook is short, but not very
+	helpful.  It exits with an error status if a change adds a
+	line with trailing whitespace to any file, but does not print
+	any information that might help us to identify the offending
+	file or line.  It also has the nice property of not paying
+	attention to unmodified lines; only lines that introduce new
+	trailing whitespace cause problems.
+      </para>
+
+      <para id="x_236">The above version is much more complex, but also more
+	useful.  It parses a unified diff to see if any lines add
+	trailing whitespace, and prints the name of the file and the
+	line number of each such occurrence.  Even better, if the
+	change adds trailing whitespace, this hook saves the commit
+	comment and prints the name of the save file before exiting
+	and telling Mercurial to roll the transaction back, so you can
+	use the <option role="hg-opt-commit">-l filename</option>
+	option to <command role="hg-cmd">hg commit</command> to reuse
+	the saved commit message once you've corrected the problem.
+      </para>
+
+&interaction.hook.ws.better;
+
+      <para id="x_237">As a final aside, note in the example above the use of
+	<command>perl</command>'s in-place editing feature to get rid
+	of trailing whitespace from a file.  This is concise and
+	useful enough that I will reproduce it here.
+      </para>
+      <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Bundled hooks</title>
+
+    <para id="x_238">Mercurial ships with several bundled hooks.  You can find
+      them in the <filename class="directory">hgext</filename>
+      directory of a Mercurial source tree.  If you are using a
+      Mercurial binary package, the hooks will be located in the
+      <filename class="directory">hgext</filename> directory of
+      wherever your package installer put Mercurial.
+    </para>
+
+    <sect2>
+      <title><literal role="hg-ext">acl</literal>&emdash;access
+	control for parts of a repository</title>
+
+      <para id="x_239">The <literal role="hg-ext">acl</literal> extension lets
+	you control which remote users are allowed to push changesets
+	to a networked server.  You can protect any portion of a
+	repository (including the entire repo), so that a specific
+	remote user can push changes that do not affect the protected
+	portion.
+      </para>
+
+      <para id="x_23a">This extension implements access control based on the
+	identity of the user performing a push,
+	<emphasis>not</emphasis> on who committed the changesets
+	they're pushing.  It makes sense to use this hook only if you
+	have a locked-down server environment that authenticates
+	remote users, and you want to be sure that only specific users
+	are allowed to push changes to that server.
+      </para>
+
+      <sect3>
+	<title>Configuring the <literal role="hook">acl</literal>
+	  hook</title>
+
+	<para id="x_23b">In order to manage incoming changesets, the <literal
+	    role="hg-ext">acl</literal> hook must be used as a
+	  <literal role="hook">pretxnchangegroup</literal> hook.  This
+	  lets it see which files are modified by each incoming
+	  changeset, and roll back a group of changesets if they
+	  modify <quote>forbidden</quote> files.  Example:
+	</para>
+	<programlisting>[hooks]
+pretxnchangegroup.acl = python:hgext.acl.hook</programlisting>
+
+	<para id="x_23c">The <literal role="hg-ext">acl</literal> extension is
+	  configured using three sections.
+	</para>
+
+	<para id="x_23d">The <literal role="rc-acl">acl</literal> section has
+	  only one entry, <envar role="rc-item-acl">sources</envar>,
+	  which lists the sources of incoming changesets that the hook
+	  should pay attention to.  You don't normally need to
+	  configure this section.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_23e"><envar role="rc-item-acl">serve</envar>:
+	      Control incoming changesets that are arriving from a
+	      remote repository over http or ssh.  This is the default
+	      value of <envar role="rc-item-acl">sources</envar>, and
+	      usually the only setting you'll need for this
+	      configuration item.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_23f"><envar role="rc-item-acl">pull</envar>:
+	      Control incoming changesets that are arriving via a pull
+	      from a local repository.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_240"><envar role="rc-item-acl">push</envar>:
+	      Control incoming changesets that are arriving via a push
+	      from a local repository.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_241"><envar role="rc-item-acl">bundle</envar>:
+	      Control incoming changesets that are arriving from
+	      another repository via a bundle.
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_242">The <literal role="rc-acl.allow">acl.allow</literal>
+	  section controls the users that are allowed to add
+	  changesets to the repository.  If this section is not
+	  present, all users that are not explicitly denied are
+	  allowed.  If this section is present, all users that are not
+	  explicitly allowed are denied (so an empty section means
+	  that all users are denied).
+	</para>
+
+	<para id="x_243">The <literal role="rc-acl.deny">acl.deny</literal>
+	  section determines which users are denied from adding
+	  changesets to the repository.  If this section is not
+	  present or is empty, no users are denied.
+	</para>
+
+	<para id="x_244">The syntaxes for the <literal
+	    role="rc-acl.allow">acl.allow</literal> and <literal
+	    role="rc-acl.deny">acl.deny</literal> sections are
+	  identical.  On the left of each entry is a glob pattern that
+	  matches files or directories, relative to the root of the
+	  repository; on the right, a user name.
+	</para>
+
+	<para id="x_245">In the following example, the user
+	  <literal>docwriter</literal> can only push changes to the
+	  <filename class="directory">docs</filename> subtree of the
+	  repository, while <literal>intern</literal> can push changes
+	  to any file or directory except <filename
+	    class="directory">source/sensitive</filename>.
+	</para>
+	<programlisting>[acl.allow]
+docs/** = docwriter
+[acl.deny]
+source/sensitive/** = intern</programlisting>
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_246">If you want to test the <literal
+	    role="hg-ext">acl</literal> hook, run it with Mercurial's
+	  debugging output enabled.  Since you'll probably be running
+	  it on a server where it's not convenient (or sometimes
+	  possible) to pass in the <option
+	    role="hg-opt-global">--debug</option> option, don't forget
+	  that you can enable debugging output in your <filename
+	    role="special">~/.hgrc</filename>:
+	</para>
+	<programlisting>[ui]
+debug = true</programlisting>
+	<para id="x_247">With this enabled, the <literal
+	    role="hg-ext">acl</literal> hook will print enough
+	  information to let you figure out why it is allowing or
+	  forbidding pushes from specific users.
+	</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title><literal
+	  role="hg-ext">bugzilla</literal>&emdash;integration with
+	Bugzilla</title>
+
+      <para id="x_248">The <literal role="hg-ext">bugzilla</literal> extension
+	adds a comment to a Bugzilla bug whenever it finds a reference
+	to that bug ID in a commit comment.  You can install this hook
+	on a shared server, so that any time a remote user pushes
+	changes to this server, the hook gets run.
+      </para>
+
+      <para id="x_249">It adds a comment to the bug that looks like this (you can
+	configure the contents of the comment&emdash;see below):
+      </para>
+      <programlisting>Changeset aad8b264143a, made by Joe User
+	&lt;joe.user@domain.com&gt; in the frobnitz repository, refers
+	to this bug. For complete details, see
+	http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
+	Changeset description: Fix bug 10483 by guarding against some
+	NULL pointers</programlisting>
+      <para id="x_24a">The value of this hook is that it automates the process of
+	updating a bug any time a changeset refers to it.  If you
+	configure the hook properly, it makes it easy for people to
+	browse straight from a Bugzilla bug to a changeset that refers
+	to that bug.
+      </para>
+
+      <para id="x_24b">You can use the code in this hook as a starting point for
+	some more exotic Bugzilla integration recipes.  Here are a few
+	possibilities:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_24c">Require that every changeset pushed to the
+	    server have a valid bug ID in its commit comment.  In this
+	    case, you'd want to configure the hook as a <literal
+	      role="hook">pretxncommit</literal> hook.  This would
+	    allow the hook to reject changes that didn't contain bug
+	    IDs.
+	  </para>
+	</listitem>
+	<listitem><para id="x_24d">Allow incoming changesets to automatically
+	    modify the <emphasis>state</emphasis> of a bug, as well as
+	    simply adding a comment.  For example, the hook could
+	    recognise the string <quote>fixed bug 31337</quote> as
+	    indicating that it should update the state of bug 31337 to
+	    <quote>requires testing</quote>.
+	  </para>
+	</listitem></itemizedlist>
+
+      <sect3 id="sec:hook:bugzilla:config">
+	<title>Configuring the <literal role="hook">bugzilla</literal>
+	  hook</title>
+
+	<para id="x_24e">You should configure this hook in your server's
+	  <filename role="special">~/.hgrc</filename> as an <literal
+	    role="hook">incoming</literal> hook, for example as
+	  follows:
+	</para>
+	<programlisting>[hooks]
+incoming.bugzilla = python:hgext.bugzilla.hook</programlisting>
+
+	<para id="x_24f">Because of the specialised nature of this hook, and
+	  because Bugzilla was not written with this kind of
+	  integration in mind, configuring this hook is a somewhat
+	  involved process.
+	</para>
+
+	<para id="x_250">Before you begin, you must install the MySQL bindings
+	  for Python on the host(s) where you'll be running the hook.
+	  If this is not available as a binary package for your
+	  system, you can download it from
+	  <citation>web:mysql-python</citation>.
+	</para>
+
+	<para id="x_251">Configuration information for this hook lives in the
+	  <literal role="rc-bugzilla">bugzilla</literal> section of
+	  your <filename role="special">~/.hgrc</filename>.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_252"><envar
+		role="rc-item-bugzilla">version</envar>: The version
+	      of Bugzilla installed on the server.  The database
+	      schema that Bugzilla uses changes occasionally, so this
+	      hook has to know exactly which schema to use. At the
+	      moment, the only version supported is
+	      <literal>2.16</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_253"><envar role="rc-item-bugzilla">host</envar>:
+	      The hostname of the MySQL server that stores your
+	      Bugzilla data.  The database must be configured to allow
+	      connections from whatever host you are running the
+	      <literal role="hook">bugzilla</literal> hook on.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_254"><envar role="rc-item-bugzilla">user</envar>:
+	      The username with which to connect to the MySQL server.
+	      The database must be configured to allow this user to
+	      connect from whatever host you are running the <literal
+		role="hook">bugzilla</literal> hook on.  This user
+	      must be able to access and modify Bugzilla tables.  The
+	      default value of this item is <literal>bugs</literal>,
+	      which is the standard name of the Bugzilla user in a
+	      MySQL database.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_255"><envar
+		role="rc-item-bugzilla">password</envar>: The MySQL
+	      password for the user you configured above.  This is
+	      stored as plain text, so you should make sure that
+	      unauthorised users cannot read the <filename
+		role="special">~/.hgrc</filename> file where you
+	      store this information.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_256"><envar role="rc-item-bugzilla">db</envar>:
+	      The name of the Bugzilla database on the MySQL server.
+	      The default value of this item is
+	      <literal>bugs</literal>, which is the standard name of
+	      the MySQL database where Bugzilla stores its data.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_257"><envar
+		role="rc-item-bugzilla">notify</envar>: If you want
+	      Bugzilla to send out a notification email to subscribers
+	      after this hook has added a comment to a bug, you will
+	      need this hook to run a command whenever it updates the
+	      database.  The command to run depends on where you have
+	      installed Bugzilla, but it will typically look something
+	      like this, if you have Bugzilla installed in <filename
+		class="directory">/var/www/html/bugzilla</filename>:
+	    </para>
+	    <programlisting>cd /var/www/html/bugzilla &amp;&amp;
+	      ./processmail %s nobody@nowhere.com</programlisting>
+	  </listitem>
+	  <listitem><para id="x_258">  The Bugzilla
+	      <literal>processmail</literal> program expects to be
+	      given a bug ID (the hook replaces
+	      <quote><literal>%s</literal></quote> with the bug ID)
+	      and an email address.  It also expects to be able to
+	      write to some files in the directory that it runs in.
+	      If Bugzilla and this hook are not installed on the same
+	      machine, you will need to find a way to run
+	      <literal>processmail</literal> on the server where
+	      Bugzilla is installed.
+	    </para>
+	  </listitem></itemizedlist>
+
+      </sect3>
+      <sect3>
+	<title>Mapping committer names to Bugzilla user names</title>
+
+	<para id="x_259">By default, the <literal
+	    role="hg-ext">bugzilla</literal> hook tries to use the
+	  email address of a changeset's committer as the Bugzilla
+	  user name with which to update a bug.  If this does not suit
+	  your needs, you can map committer email addresses to
+	  Bugzilla user names using a <literal
+	    role="rc-usermap">usermap</literal> section.
+	</para>
+
+	<para id="x_25a">Each item in the <literal
+	    role="rc-usermap">usermap</literal> section contains an
+	  email address on the left, and a Bugzilla user name on the
+	  right.
+	</para>
+	<programlisting>[usermap]
+jane.user@example.com = jane</programlisting>
+	<para id="x_25b">You can either keep the <literal
+	    role="rc-usermap">usermap</literal> data in a normal
+	  <filename role="special">~/.hgrc</filename>, or tell the
+	  <literal role="hg-ext">bugzilla</literal> hook to read the
+	  information from an external <filename>usermap</filename>
+	  file.  In the latter case, you can store
+	  <filename>usermap</filename> data by itself in (for example)
+	  a user-modifiable repository.  This makes it possible to let
+	  your users maintain their own <envar
+	    role="rc-item-bugzilla">usermap</envar> entries.  The main
+	  <filename role="special">~/.hgrc</filename> file might look
+	  like this:
+	</para>
+	<programlisting># regular hgrc file refers to external usermap file
+[bugzilla]
+usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting>
+	<para id="x_25c">While the <filename>usermap</filename> file that it
+	  refers to might look like this:
+	</para>
+	<programlisting># bugzilla-usermap.conf - inside a hg repository
+[usermap] stephanie@example.com = steph</programlisting>
+
+      </sect3>
+      <sect3>
+	<title>Configuring the text that gets added to a bug</title>
+
+	<para id="x_25d">You can configure the text that this hook adds as a
+	  comment; you specify it in the form of a Mercurial template.
+	  Several <filename role="special">~/.hgrc</filename> entries
+	  (still in the <literal role="rc-bugzilla">bugzilla</literal>
+	  section) control this behavior.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_25e"><literal>strip</literal>: The number of
+	      leading path elements to strip from a repository's path
+	      name to construct a partial path for a URL. For example,
+	      if the repositories on your server live under <filename
+		class="directory">/home/hg/repos</filename>, and you
+	      have a repository whose path is <filename
+		class="directory">/home/hg/repos/app/tests</filename>,
+	      then setting <literal>strip</literal> to
+	      <literal>4</literal> will give a partial path of
+	      <filename class="directory">app/tests</filename>.  The
+	      hook will make this partial path available when
+	      expanding a template, as <literal>webroot</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_25f"><literal>template</literal>: The text of the
+	      template to use.  In addition to the usual
+	      changeset-related variables, this template can use
+	      <literal>hgweb</literal> (the value of the
+	      <literal>hgweb</literal> configuration item above) and
+	      <literal>webroot</literal> (the path constructed using
+	      <literal>strip</literal> above).
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_260">In addition, you can add a <envar
+	    role="rc-item-web">baseurl</envar> item to the <literal
+	    role="rc-web">web</literal> section of your <filename
+	    role="special">~/.hgrc</filename>.  The <literal
+	    role="hg-ext">bugzilla</literal> hook will make this
+	  available when expanding a template, as the base string to
+	  use when constructing a URL that will let users browse from
+	  a Bugzilla comment to view a changeset.  Example:
+	</para>
+	<programlisting>[web]
+baseurl = http://hg.domain.com/</programlisting>
+
+	<para id="x_261">Here is an example set of <literal
+	    role="hg-ext">bugzilla</literal> hook config information.
+	</para>
+
+	&ch10-bugzilla-config.lst;
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_262">The most common problems with configuring the <literal
+	    role="hg-ext">bugzilla</literal> hook relate to running
+	  Bugzilla's <filename>processmail</filename> script and
+	  mapping committer names to user names.
+	</para>
+
+	<para id="x_263">Recall from <xref
+	    linkend="sec:hook:bugzilla:config"/> above that the user
+	  that runs the Mercurial process on the server is also the
+	  one that will run the <filename>processmail</filename>
+	  script.  The <filename>processmail</filename> script
+	  sometimes causes Bugzilla to write to files in its
+	  configuration directory, and Bugzilla's configuration files
+	  are usually owned by the user that your web server runs
+	  under.
+	</para>
+
+	<para id="x_264">You can cause <filename>processmail</filename> to be run
+	  with the suitable user's identity using the
+	  <command>sudo</command> command.  Here is an example entry
+	  for a <filename>sudoers</filename> file.
+	</para>
+	<programlisting>hg_user = (httpd_user)
+NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting>
+	<para id="x_265">This allows the <literal>hg_user</literal> user to run a
+	  <filename>processmail-wrapper</filename> program under the
+	  identity of <literal>httpd_user</literal>.
+	</para>
+
+	<para id="x_266">This indirection through a wrapper script is necessary,
+	  because <filename>processmail</filename> expects to be run
+	  with its current directory set to wherever you installed
+	  Bugzilla; you can't specify that kind of constraint in a
+	  <filename>sudoers</filename> file.  The contents of the
+	  wrapper script are simple:
+	</para>
+	<programlisting>#!/bin/sh
+cd `dirname $0` &amp;&amp; ./processmail "$1" nobody@example.com</programlisting>
+	<para id="x_267">It doesn't seem to matter what email address you pass to
+	  <filename>processmail</filename>.
+	</para>
+
+	<para id="x_268">If your <literal role="rc-usermap">usermap</literal> is
+	  not set up correctly, users will see an error message from
+	  the <literal role="hg-ext">bugzilla</literal> hook when they
+	  push changes to the server.  The error message will look
+	  like this:
+	</para>
+	<programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting>
+	<para id="x_269">What this means is that the committer's address,
+	  <literal>john.q.public@example.com</literal>, is not a valid
+	  Bugzilla user name, nor does it have an entry in your
+	  <literal role="rc-usermap">usermap</literal> that maps it to
+	  a valid Bugzilla user name.
+	</para>
+
+      </sect3>
+    </sect2>
+    <sect2>
+      <title><literal role="hg-ext">notify</literal>&emdash;send email
+	notifications</title>
+
+      <para id="x_26a">Although Mercurial's built-in web server provides RSS
+	feeds of changes in every repository, many people prefer to
+	receive change notifications via email.  The <literal
+	  role="hg-ext">notify</literal> hook lets you send out
+	notifications to a set of email addresses whenever changesets
+	arrive that those subscribers are interested in.
+      </para>
+
+      <para id="x_26b">As with the <literal role="hg-ext">bugzilla</literal>
+	hook, the <literal role="hg-ext">notify</literal> hook is
+	template-driven, so you can customise the contents of the
+	notification messages that it sends.
+      </para>
+
+      <para id="x_26c">By default, the <literal role="hg-ext">notify</literal>
+	hook includes a diff of every changeset that it sends out; you
+	can limit the size of the diff, or turn this feature off
+	entirely.  It is useful for letting subscribers review changes
+	immediately, rather than clicking to follow a URL.
+      </para>
+
+      <sect3>
+	<title>Configuring the <literal role="hg-ext">notify</literal>
+	  hook</title>
+
+	<para id="x_26d">You can set up the <literal
+	    role="hg-ext">notify</literal> hook to send one email
+	  message per incoming changeset, or one per incoming group of
+	  changesets (all those that arrived in a single pull or
+	  push).
+	</para>
+	<programlisting>[hooks]
+# send one email per group of changes
+changegroup.notify = python:hgext.notify.hook
+# send one email per change
+incoming.notify = python:hgext.notify.hook</programlisting>
+
+	<para id="x_26e">Configuration information for this hook lives in the
+	  <literal role="rc-notify">notify</literal> section of a
+	  <filename role="special">~/.hgrc</filename> file.
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_26f"><envar role="rc-item-notify">test</envar>:
+	      By default, this hook does not send out email at all;
+	      instead, it prints the message that it
+	      <emphasis>would</emphasis> send.  Set this item to
+	      <literal>false</literal> to allow email to be sent. The
+	      reason that sending of email is turned off by default is
+	      that it takes several tries to configure this extension
+	      exactly as you would like, and it would be bad form to
+	      spam subscribers with a number of <quote>broken</quote>
+	      notifications while you debug your configuration.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_270"><envar role="rc-item-notify">config</envar>:
+	      The path to a configuration file that contains
+	      subscription information.  This is kept separate from
+	      the main <filename role="special">~/.hgrc</filename> so
+	      that you can maintain it in a repository of its own.
+	      People can then clone that repository, update their
+	      subscriptions, and push the changes back to your server.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_271"><envar role="rc-item-notify">strip</envar>:
+	      The number of leading path separator characters to strip
+	      from a repository's path, when deciding whether a
+	      repository has subscribers.  For example, if the
+	      repositories on your server live in <filename
+		class="directory">/home/hg/repos</filename>, and
+	      <literal role="hg-ext">notify</literal> is considering a
+	      repository named <filename
+		class="directory">/home/hg/repos/shared/test</filename>, 
+	      setting <envar role="rc-item-notify">strip</envar> to
+	      <literal>4</literal> will cause <literal
+		role="hg-ext">notify</literal> to trim the path it
+	      considers down to <filename
+		class="directory">shared/test</filename>, and it will
+	      match subscribers against that.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_272"><envar
+		role="rc-item-notify">template</envar>: The template
+	      text to use when sending messages.  This specifies both
+	      the contents of the message header and its body.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_273"><envar
+		role="rc-item-notify">maxdiff</envar>: The maximum
+	      number of lines of diff data to append to the end of a
+	      message.  If a diff is longer than this, it is
+	      truncated.  By default, this is set to 300.  Set this to
+	      <literal>0</literal> to omit diffs from notification
+	      emails.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_274"><envar
+		role="rc-item-notify">sources</envar>: A list of
+	      sources of changesets to consider.  This lets you limit
+	      <literal role="hg-ext">notify</literal> to only sending
+	      out email about changes that remote users pushed into
+	      this repository via a server, for example.  See 
+	      <xref linkend="sec:hook:sources"/> for the sources you
+	      can specify here.
+	    </para>
+	  </listitem></itemizedlist>
+
+	<para id="x_275">If you set the <envar role="rc-item-web">baseurl</envar>
+	  item in the <literal role="rc-web">web</literal> section,
+	  you can use it in a template; it will be available as
+	  <literal>webroot</literal>.
+	</para>
+
+	<para id="x_276">Here is an example set of <literal
+	    role="hg-ext">notify</literal> configuration information.
+	</para>
+
+	&ch10-notify-config.lst;
+
+	<para id="x_277">This will produce a message that looks like the
+	  following:
+	</para>
+
+	&ch10-notify-config-mail.lst;
+
+      </sect3>
+      <sect3>
+	<title>Testing and troubleshooting</title>
+
+	<para id="x_278">Do not forget that by default, the <literal
+		role="hg-ext">notify</literal> extension <emphasis>will not
+	  send any mail</emphasis> until you explicitly configure it to do so,
+	  by setting <envar role="rc-item-notify">test</envar> to
+	  <literal>false</literal>.  Until you do that, it simply
+	  prints the message it <emphasis>would</emphasis> send.
+	</para>
+
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1 id="sec:hook:ref">
+    <title>Information for writers of hooks</title>
+
+    <sect2>
+      <title>In-process hook execution</title>
+
+      <para id="x_279">An in-process hook is called with arguments of the
+	following form:
+      </para>
+      <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting>
+      <para id="x_27a">The <literal>ui</literal> parameter is a <literal
+	  role="py-mod-mercurial.ui">ui</literal> object. The
+	<literal>repo</literal> parameter is a <literal
+	  role="py-mod-mercurial.localrepo">localrepository</literal>
+	object.  The names and values of the
+	<literal>**kwargs</literal> parameters depend on the hook
+	being invoked, with the following common features:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_27b">If a parameter is named
+	    <literal>node</literal> or <literal>parentN</literal>, it
+	    will contain a hexadecimal changeset ID. The empty string
+	    is used to represent <quote>null changeset ID</quote>
+	    instead of a string of zeroes.
+	  </para>
+	</listitem>
+	<listitem><para id="x_27c">If a parameter is named
+	    <literal>url</literal>, it will contain the URL of a
+	    remote repository, if that can be determined.
+	  </para>
+	</listitem>
+	<listitem><para id="x_27d">Boolean-valued parameters are represented as
+	    Python <literal>bool</literal> objects.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_27e">An in-process hook is called without a change to the
+	process's working directory (unlike external hooks, which are
+	run in the root of the repository).  It must not change the
+	process's working directory, or it will cause any calls it
+	makes into the Mercurial API to fail.
+      </para>
+
+      <para id="x_27f">If a hook returns a boolean <quote>false</quote> value, it
+	is considered to have succeeded.  If it returns a boolean
+	<quote>true</quote> value or raises an exception, it is
+	considered to have failed.  A useful way to think of the
+	calling convention is <quote>tell me if you fail</quote>.
+      </para>
+
+      <para id="x_280">Note that changeset IDs are passed into Python hooks as
+	hexadecimal strings, not the binary hashes that Mercurial's
+	APIs normally use.  To convert a hash from hex to binary, use
+	the <literal>bin</literal> function.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>External hook execution</title>
+
+      <para id="x_281">An external hook is passed to the shell of the user
+	running Mercurial. Features of that shell, such as variable
+	substitution and command redirection, are available.  The hook
+	is run in the root directory of the repository (unlike
+	in-process hooks, which are run in the same directory that
+	Mercurial was run in).
+      </para>
+
+      <para id="x_282">Hook parameters are passed to the hook as environment
+	variables.  Each environment variable's name is converted in
+	upper case and prefixed with the string
+	<quote><literal>HG_</literal></quote>.  For example, if the
+	name of a parameter is <quote><literal>node</literal></quote>,
+	the name of the environment variable representing that
+	parameter will be <quote><literal>HG_NODE</literal></quote>.
+      </para>
+
+      <para id="x_283">A boolean parameter is represented as the string
+	<quote><literal>1</literal></quote> for <quote>true</quote>,
+	<quote><literal>0</literal></quote> for <quote>false</quote>.
+	If an environment variable is named <envar>HG_NODE</envar>,
+	<envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it
+	contains a changeset ID represented as a hexadecimal string.
+	The empty string is used to represent <quote>null changeset
+	  ID</quote> instead of a string of zeroes.  If an environment
+	variable is named <envar>HG_URL</envar>, it will contain the
+	URL of a remote repository, if that can be determined.
+      </para>
+
+      <para id="x_284">If a hook exits with a status of zero, it is considered to
+	have succeeded.  If it exits with a non-zero status, it is
+	considered to have failed.
+      </para>
+
+    </sect2>
+    <sect2>
+      <title>Finding out where changesets come from</title>
+
+      <para id="x_285">A hook that involves the transfer of changesets between a
+	local repository and another may be able to find out
+	information about the <quote>far side</quote>.  Mercurial
+	knows <emphasis>how</emphasis> changes are being transferred,
+	and in many cases <emphasis>where</emphasis> they are being
+	transferred to or from.
+      </para>
+
+      <sect3 id="sec:hook:sources">
+	<title>Sources of changesets</title>
+
+	<para id="x_286">Mercurial will tell a hook what means are, or were, used
+	  to transfer changesets between repositories.  This is
+	  provided by Mercurial in a Python parameter named
+	  <literal>source</literal>, or an environment variable named
+	  <envar>HG_SOURCE</envar>.
+	</para>
+
+	<itemizedlist>
+	  <listitem><para id="x_287"><literal>serve</literal>: Changesets are
+	      transferred to or from a remote repository over http or
+	      ssh.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_288"><literal>pull</literal>: Changesets are
+	      being transferred via a pull from one repository into
+	      another.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_289"><literal>push</literal>: Changesets are
+	      being transferred via a push from one repository into
+	      another.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28a"><literal>bundle</literal>: Changesets are
+	      being transferred to or from a bundle.
+	    </para>
+	  </listitem></itemizedlist>
+
+      </sect3>
+      <sect3 id="sec:hook:url">
+	<title>Where changes are going&emdash;remote repository
+	  URLs</title>
+
+	<para id="x_28b">When possible, Mercurial will tell a hook the location
+	  of the <quote>far side</quote> of an activity that transfers
+	  changeset data between repositories.  This is provided by
+	  Mercurial in a Python parameter named
+	  <literal>url</literal>, or an environment variable named
+	  <envar>HG_URL</envar>.
+	</para>
+
+	<para id="x_28c">This information is not always known.  If a hook is
+	  invoked in a repository that is being served via http or
+	  ssh, Mercurial cannot tell where the remote repository is,
+	  but it may know where the client is connecting from.  In
+	  such cases, the URL will take one of the following forms:
+	</para>
+	<itemizedlist>
+	  <listitem><para id="x_28d"><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 
+	      ssh client, at the IP address
+	      <literal>1.2.3.4</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28e"><literal>remote:http:1.2.3.4</literal>&emdash;remote 
+	      http client, at the IP address
+	      <literal>1.2.3.4</literal>.  If the client is using SSL,
+	      this will be of the form
+	      <literal>remote:https:1.2.3.4</literal>.
+	    </para>
+	  </listitem>
+	  <listitem><para id="x_28f">Empty&emdash;no information could be
+	      discovered about the remote client.
+	    </para>
+	  </listitem></itemizedlist>
+
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Hook reference</title>
+
+    <sect2 id="sec:hook:changegroup">
+      <title><literal role="hook">changegroup</literal>&emdash;after
+	remote changesets added</title>
+
+      <para id="x_290">This hook is run after a group of pre-existing changesets
+	has been added to the repository, for example via a <command
+	  role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg
+	  unbundle</command>.  This hook is run once per operation
+	that added one or more changesets.  This is in contrast to the
+	<literal role="hook">incoming</literal> hook, which is run
+	once per changeset, regardless of whether the changesets
+	arrive in a group.
+      </para>
+
+      <para id="x_291">Some possible uses for this hook include kicking off an
+	automated build or test of the added changesets, updating a
+	bug database, or notifying subscribers that a repository
+	contains new changes.
+      </para>
+
+      <para id="x_292">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_293"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset in the group that was
+	    added.  All changesets between this and
+	    <literal role="tag">tip</literal>, inclusive, were added by a single
+	    <command role="hg-cmd">hg pull</command>, <command
+	      role="hg-cmd">hg push</command> or <command
+	      role="hg-cmd">hg unbundle</command>.
+	  </para>
+	</listitem>
+	<listitem><para id="x_294"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_295"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_296">See also: <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:commit">
+      <title><literal role="hook">commit</literal>&emdash;after a new
+	changeset is created</title>
+
+      <para id="x_297">This hook is run after a new changeset has been created.
+      </para>
+
+      <para id="x_298">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_299"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the newly committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_29a"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_29b"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_29c">See also: <literal
+	  role="hook">precommit</literal> (<xref
+	  linkend="sec:hook:precommit"/>), <literal
+	  role="hook">pretxncommit</literal> (<xref
+	  linkend="sec:hook:pretxncommit"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:incoming">
+      <title><literal role="hook">incoming</literal>&emdash;after one
+	remote changeset is added</title>
+
+      <para id="x_29d">This hook is run after a pre-existing changeset has been
+	added to the repository, for example via a <command
+	  role="hg-cmd">hg push</command>.  If a group of changesets
+	was added in a single operation, this hook is called once for
+	each added changeset.
+      </para>
+
+      <para id="x_29e">You can use this hook for the same purposes as
+	the <literal role="hook">changegroup</literal> hook (<xref
+	  linkend="sec:hook:changegroup"/>); it's simply more
+	convenient sometimes to run a hook once per group of
+	changesets, while other times it's handier once per changeset.
+      </para>
+
+      <para id="x_29f">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2a0"><literal>node</literal>: A changeset ID.  The
+	    ID of the newly added changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a1"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a2"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2a3">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>) <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:outgoing">
+      <title><literal role="hook">outgoing</literal>&emdash;after
+	changesets are propagated</title>
+
+      <para id="x_2a4">This hook is run after a group of changesets has been
+	propagated out of this repository, for example by a <command
+	  role="hg-cmd">hg push</command> or <command role="hg-cmd">hg
+	  bundle</command> command.
+      </para>
+
+      <para id="x_2a5">One possible use for this hook is to notify administrators
+	that changes have been pulled.
+      </para>
+
+      <para id="x_2a6">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2a7"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset of the group that was
+	    sent.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a8"><literal>source</literal>: A string.  The
+	    source of the of the operation (see <xref
+	      linkend="sec:hook:sources"/>).  If a remote
+	    client pulled changes from this repository,
+	    <literal>source</literal> will be
+	    <literal>serve</literal>.  If the client that obtained
+	    changes from this repository was local,
+	    <literal>source</literal> will be
+	    <literal>bundle</literal>, <literal>pull</literal>, or
+	    <literal>push</literal>, depending on the operation the
+	    client performed.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2a9"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2aa">See also: <literal
+	  role="hook">preoutgoing</literal> (<xref
+	  linkend="sec:hook:preoutgoing"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:prechangegroup">
+      <title><literal
+	  role="hook">prechangegroup</literal>&emdash;before starting
+	to add remote changesets</title>
+
+      <para id="x_2ab">This controlling hook is run before Mercurial begins to
+	add a group of changesets from another repository.
+      </para>
+
+      <para id="x_2ac">This hook does not have any information about the
+	changesets to be added, because it is run before transmission
+	of those changesets is allowed to begin.  If this hook fails,
+	the changesets will not be transmitted.
+      </para>
+
+      <para id="x_2ad">One use for this hook is to prevent external changes from
+	being added to a repository.  For example, you could use this
+	to <quote>freeze</quote> a server-hosted branch temporarily or
+	permanently so that users cannot push to it, while still
+	allowing a local administrator to modify the repository.
+      </para>
+
+      <para id="x_2ae">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2af"><literal>source</literal>: A string.  The
+	    source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2b0"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2b1">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>), <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">pretxnchangegroup</literal> (<xref
+	  linkend="sec:hook:pretxnchangegroup"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:precommit">
+      <title><literal role="hook">precommit</literal>&emdash;before
+	starting to commit a changeset</title>
+
+      <para id="x_2b2">This hook is run before Mercurial begins to commit a new
+	changeset. It is run before Mercurial has any of the metadata
+	for the commit, such as the files to be committed, the commit
+	message, or the commit date.
+      </para>
+
+      <para id="x_2b3">One use for this hook is to disable the ability to commit
+	new changesets, while still allowing incoming changesets.
+	Another is to run a build or test, and only allow the commit
+	to begin if the build or test succeeds.
+      </para>
+
+      <para id="x_2b4">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2b5"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the working
+	    directory.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2b6"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the working
+	    directory.
+	  </para>
+	</listitem></itemizedlist>
+      <para id="x_2b7">If the commit proceeds, the parents of the working
+	directory will become the parents of the new changeset.
+      </para>
+
+      <para id="x_2b8">See also: <literal role="hook">commit</literal>
+	(<xref linkend="sec:hook:commit"/>), <literal
+	  role="hook">pretxncommit</literal> (<xref
+	  linkend="sec:hook:pretxncommit"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:preoutgoing">
+      <title><literal role="hook">preoutgoing</literal>&emdash;before
+	starting to propagate changesets</title>
+
+      <para id="x_2b9">This hook is invoked before Mercurial knows the identities
+	of the changesets to be transmitted.
+      </para>
+
+      <para id="x_2ba">One use for this hook is to prevent changes from being
+	transmitted to another repository.
+      </para>
+
+      <para id="x_2bb">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2bc"><literal>source</literal>: A
+	    string.  The source of the operation that is attempting to
+	    obtain changes from this repository (see <xref
+	      linkend="sec:hook:sources"/>).  See the documentation
+	    for the <literal>source</literal> parameter to the
+	    <literal role="hook">outgoing</literal> hook, in
+	    <xref linkend="sec:hook:outgoing"/>, for possible values
+	    of this parameter.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2bd"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2be">See also: <literal
+	  role="hook">outgoing</literal> (<xref
+	  linkend="sec:hook:outgoing"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:pretag">
+      <title><literal role="hook">pretag</literal>&emdash;before
+	tagging a changeset</title>
+
+      <para id="x_2bf">This controlling hook is run before a tag is created.  If
+	the hook succeeds, creation of the tag proceeds.  If the hook
+	fails, the tag is not created.
+      </para>
+
+      <para id="x_2c0">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2c1"><literal>local</literal>: A boolean.  Whether
+	    the tag is local to this repository instance (i.e. stored
+	    in <filename role="special">.hg/localtags</filename>) or
+	    managed by Mercurial (stored in <filename
+	      role="special">.hgtags</filename>).
+	  </para>
+	</listitem>
+	<listitem><para id="x_2c2"><literal>node</literal>: A changeset ID.  The
+	    ID of the changeset to be tagged.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2c3"><literal>tag</literal>: A string.  The name of
+	    the tag to be created.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2c4">If the tag to be created is
+	revision-controlled, the <literal
+	  role="hook">precommit</literal> and <literal
+	  role="hook">pretxncommit</literal> hooks (<xref
+	  linkend="sec:hook:commit"/> and <xref
+	  linkend="sec:hook:pretxncommit"/>) will also be run.
+      </para>
+
+      <para id="x_2c5">See also: <literal role="hook">tag</literal>
+	(<xref linkend="sec:hook:tag"/>)
+      </para>
+    </sect2>
+    <sect2 id="sec:hook:pretxnchangegroup">
+      <title><literal
+	  role="hook">pretxnchangegroup</literal>&emdash;before
+	completing addition of remote changesets</title>
+
+      <para id="x_2c6">This controlling hook is run before a
+	transaction&emdash;that manages the addition of a group of new
+	changesets from outside the repository&emdash;completes.  If
+	the hook succeeds, the transaction completes, and all of the
+	changesets become permanent within this repository.  If the
+	hook fails, the transaction is rolled back, and the data for
+	the changesets is erased.
+      </para>
+
+      <para id="x_2c7">This hook can access the metadata associated with the
+	almost-added changesets, but it should not do anything
+	permanent with this data. It must also not modify the working
+	directory.
+      </para>
+
+      <para id="x_2c8">While this hook is running, if other Mercurial processes
+	access this repository, they will be able to see the
+	almost-added changesets as if they are permanent.  This may
+	lead to race conditions if you do not take steps to avoid
+	them.
+      </para>
+
+      <para id="x_2c9">This hook can be used to automatically vet a group of
+	changesets.  If the hook fails, all of the changesets are
+	<quote>rejected</quote> when the transaction rolls back.
+      </para>
+
+      <para id="x_2ca">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2cb"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the first changeset in the group that was
+	    added.  All changesets between this and
+	    <literal role="tag">tip</literal>,
+	    inclusive, were added by a single <command
+	      role="hg-cmd">hg pull</command>, <command
+	      role="hg-cmd">hg push</command> or <command
+	      role="hg-cmd">hg unbundle</command>.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2cc"><literal>source</literal>: A
+	    string.  The source of these changes.  See <xref
+	      linkend="sec:hook:sources"/> for details.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2cd"><literal>url</literal>: A URL.  The
+	    location of the remote repository, if known.  See <xref
+	      linkend="sec:hook:url"/> for more information.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2ce">See also: <literal
+	  role="hook">changegroup</literal> (<xref
+	  linkend="sec:hook:changegroup"/>), <literal
+	  role="hook">incoming</literal> (<xref
+	  linkend="sec:hook:incoming"/>), <literal
+	  role="hook">prechangegroup</literal> (<xref
+	  linkend="sec:hook:prechangegroup"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:pretxncommit">
+      <title><literal role="hook">pretxncommit</literal>&emdash;before
+	completing commit of new changeset</title>
+
+      <para id="x_2cf">This controlling hook is run before a
+	transaction&emdash;that manages a new commit&emdash;completes.
+	If the hook succeeds, the transaction completes and the
+	changeset becomes permanent within this repository.  If the
+	hook fails, the transaction is rolled back, and the commit
+	data is erased.
+      </para>
+
+      <para id="x_2d0">This hook can access the metadata associated with the
+	almost-new changeset, but it should not do anything permanent
+	with this data.  It must also not modify the working
+	directory.
+      </para>
+
+      <para id="x_2d1">While this hook is running, if other Mercurial processes
+	access this repository, they will be able to see the
+	almost-new changeset as if it is permanent.  This may lead to
+	race conditions if you do not take steps to avoid them.
+      </para>
+
+      <para id="x_2d2">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2d3"><literal>node</literal>: A changeset ID.  The
+	    changeset ID of the newly committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2d4"><literal>parent1</literal>: A changeset ID.
+	    The changeset ID of the first parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2d5"><literal>parent2</literal>: A changeset ID.
+	    The changeset ID of the second parent of the newly
+	    committed changeset.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2d6">See also: <literal
+	  role="hook">precommit</literal> (<xref
+	  linkend="sec:hook:precommit"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:preupdate">
+      <title><literal role="hook">preupdate</literal>&emdash;before
+	updating or merging working directory</title>
+
+      <para id="x_2d7">This controlling hook is run before an update
+	or merge of the working directory begins.  It is run only if
+	Mercurial's normal pre-update checks determine that the update
+	or merge can proceed.  If the hook succeeds, the update or
+	merge may proceed; if it fails, the update or merge does not
+	start.
+      </para>
+
+      <para id="x_2d8">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2d9"><literal>parent1</literal>: A
+	    changeset ID. The ID of the parent that the working
+	    directory is to be updated to.  If the working directory
+	    is being merged, it will not change this parent.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2da"><literal>parent2</literal>: A
+	    changeset ID. Only set if the working directory is being
+	    merged.  The ID of the revision that the working directory
+	    is being merged with.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2db">See also: <literal role="hook">update</literal>
+	(<xref linkend="sec:hook:update"/>)</para>
+
+    </sect2>
+    <sect2 id="sec:hook:tag">
+      <title><literal role="hook">tag</literal>&emdash;after tagging a
+	changeset</title>
+
+      <para id="x_2dc">This hook is run after a tag has been created.
+      </para>
+
+      <para id="x_2dd">Parameters to this hook:
+      </para>
+      <itemizedlist>
+	<listitem><para id="x_2de"><literal>local</literal>: A boolean.  Whether
+	    the new tag is local to this repository instance (i.e.
+	    stored in <filename
+	      role="special">.hg/localtags</filename>) or managed by
+	    Mercurial (stored in <filename
+	      role="special">.hgtags</filename>).
+	  </para>
+	</listitem>
+	<listitem><para id="x_2df"><literal>node</literal>: A changeset ID.  The
+	    ID of the changeset that was tagged.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e0"><literal>tag</literal>: A string.  The name of
+	    the tag that was created.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2e1">If the created tag is revision-controlled, the <literal
+	  role="hook">commit</literal> hook (section <xref
+	  linkend="sec:hook:commit"/>) is run before this hook.
+      </para>
+
+      <para id="x_2e2">See also: <literal role="hook">pretag</literal>
+	(<xref linkend="sec:hook:pretag"/>)
+      </para>
+
+    </sect2>
+    <sect2 id="sec:hook:update">
+      <title><literal role="hook">update</literal>&emdash;after
+	updating or merging working directory</title>
+
+      <para id="x_2e3">This hook is run after an update or merge of the working
+	directory completes.  Since a merge can fail (if the external
+	<command>hgmerge</command> command fails to resolve conflicts
+	in a file), this hook communicates whether the update or merge
+	completed cleanly.
+      </para>
+
+      <itemizedlist>
+	<listitem><para id="x_2e4"><literal>error</literal>: A boolean.
+	    Indicates whether the update or merge completed
+	    successfully.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e5"><literal>parent1</literal>: A changeset ID.
+	    The ID of the parent that the working directory was
+	    updated to.  If the working directory was merged, it will
+	    not have changed this parent.
+	  </para>
+	</listitem>
+	<listitem><para id="x_2e6"><literal>parent2</literal>: A changeset ID.
+	    Only set if the working directory was merged.  The ID of
+	    the revision that the working directory was merged with.
+	  </para>
+	</listitem></itemizedlist>
+
+      <para id="x_2e7">See also: <literal role="hook">preupdate</literal>
+	(<xref linkend="sec:hook:preupdate"/>)
+      </para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch10-template.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,673 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:template">
+  <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
+  <title>Customising the output of Mercurial</title>
+
+  <para id="x_578">Mercurial provides a powerful mechanism to let you control how
+    it displays information.  The mechanism is based on templates.
+    You can use templates to generate specific output for a single
+    command, or to customise the entire appearance of the built-in web
+    interface.</para>
+
+  <sect1 id="sec:style">
+    <title>Using precanned output styles</title>
+
+    <para id="x_579">Packaged with Mercurial are some output styles that you can
+      use immediately.  A style is simply a precanned template that
+      someone wrote and installed somewhere that Mercurial can
+      find.</para>
+
+    <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
+      review its normal output.</para>
+
+    &interaction.template.simple.normal;
+
+    <para id="x_57b">This is somewhat informative, but it takes up a lot of
+      space&emdash;five lines of output per changeset.  The
+      <literal>compact</literal> style reduces this to three lines,
+      presented in a sparse manner.</para>
+
+    &interaction.template.simple.compact;
+
+    <para id="x_57c">The <literal>changelog</literal> style hints at the
+      expressive power of Mercurial's templating engine.  This style
+      attempts to follow the GNU Project's changelog
+      guidelines<citation>web:changelog</citation>.</para>
+
+    &interaction.template.simple.changelog;
+
+    <para id="x_57d">You will not be shocked to learn that Mercurial's default
+      output style is named <literal>default</literal>.</para>
+
+    <sect2>
+      <title>Setting a default style</title>
+
+      <para id="x_57e">You can modify the output style that Mercurial will use
+	for every command by editing your <filename
+	  role="special">~/.hgrc</filename> file, naming the style
+	you would prefer to use.</para>
+
+      <programlisting>[ui]
+style = compact</programlisting>
+
+      <para id="x_57f">If you write a style of your own, you can use it by either
+	providing the path to your style file, or copying your style
+	file into a location where Mercurial can find it (typically
+	the <literal>templates</literal> subdirectory of your
+	Mercurial install directory).</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Commands that support styles and templates</title>
+
+    <para id="x_580">All of Mercurial's
+      <quote><literal>log</literal>-like</quote> commands let you use
+      styles and templates: <command role="hg-cmd">hg
+	incoming</command>, <command role="hg-cmd">hg log</command>,
+      <command role="hg-cmd">hg outgoing</command>, and <command
+	role="hg-cmd">hg tip</command>.</para>
+
+    <para id="x_581">As I write this manual, these are so far the only commands
+      that support styles and templates.  Since these are the most
+      important commands that need customisable output, there has been
+      little pressure from the Mercurial user community to add style
+      and template support to other commands.</para>
+
+  </sect1>
+  <sect1>
+    <title>The basics of templating</title>
+
+    <para id="x_582">At its simplest, a Mercurial template is a piece of text.
+      Some of the text never changes, while other parts are
+      <emphasis>expanded</emphasis>, or replaced with new text, when
+      necessary.</para>
+
+    <para id="x_583">Before we continue, let's look again at a simple example of
+      Mercurial's normal output.</para>
+
+    &interaction.template.simple.normal;
+
+    <para id="x_584">Now, let's run the same command, but using a template to
+      change its output.</para>
+
+    &interaction.template.simple.simplest;
+
+    <para id="x_585">The example above illustrates the simplest possible
+      template; it's just a piece of static text, printed once for
+      each changeset.  The <option
+	role="hg-opt-log">--template</option> option to the <command
+	role="hg-cmd">hg log</command> command tells Mercurial to use
+      the given text as the template when printing each
+      changeset.</para>
+
+    <para id="x_586">Notice that the template string above ends with the text
+      <quote><literal>\n</literal></quote>.  This is an
+      <emphasis>escape sequence</emphasis>, telling Mercurial to print
+      a newline at the end of each template item.  If you omit this
+      newline, Mercurial will run each piece of output together.  See
+      <xref linkend="sec:template:escape"/> for more details
+      of escape sequences.</para>
+
+    <para id="x_587">A template that prints a fixed string of text all the time
+      isn't very useful; let's try something a bit more
+      complex.</para>
+
+    &interaction.template.simple.simplesub;
+
+    <para id="x_588">As you can see, the string
+      <quote><literal>{desc}</literal></quote> in the template has
+      been replaced in the output with the description of each
+      changeset.  Every time Mercurial finds text enclosed in curly
+      braces (<quote><literal>{</literal></quote> and
+      <quote><literal>}</literal></quote>), it will try to replace the
+      braces and text with the expansion of whatever is inside.  To
+      print a literal curly brace, you must escape it, as described in
+      <xref linkend="sec:template:escape"/>.</para>
+
+  </sect1>
+  <sect1 id="sec:template:keyword">
+    <title>Common template keywords</title>
+
+    <para id="x_589">You can start writing simple templates immediately using the
+      keywords below.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_58a"><literal
+	    role="template-keyword">author</literal>: String.  The
+	  unmodified author of the changeset.</para>
+      </listitem>
+      <listitem><para id="x_58b"><literal
+	    role="template-keyword">branches</literal>: String.  The
+	  name of the branch on which the changeset was committed.
+	  Will be empty if the branch name was
+	  <literal>default</literal>.</para>
+      </listitem>
+      <listitem><para id="x_58c"><literal role="template-keyword">date</literal>:
+	  Date information.  The date when the changeset was
+	  committed.  This is <emphasis>not</emphasis> human-readable;
+	  you must pass it through a filter that will render it
+	  appropriately.  See <xref
+	    linkend="sec:template:filter"/> for more information
+	  on filters. The date is expressed as a pair of numbers.  The
+	  first number is a Unix UTC timestamp (seconds since January
+	  1, 1970); the second is the offset of the committer's
+	  timezone from UTC, in seconds.</para>
+      </listitem>
+      <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>:
+	  String.  The text of the changeset description.</para>
+      </listitem>
+      <listitem><para id="x_58e"><literal
+	    role="template-keyword">files</literal>: List of strings.
+	  All files modified, added, or removed by this
+	  changeset.</para>
+      </listitem>
+      <listitem><para id="x_58f"><literal
+	    role="template-keyword">file_adds</literal>: List of
+	  strings.  Files added by this changeset.</para>
+      </listitem>
+      <listitem><para id="x_590"><literal
+	    role="template-keyword">file_dels</literal>: List of
+	  strings.  Files removed by this changeset.</para>
+      </listitem>
+      <listitem><para id="x_591"><literal role="template-keyword">node</literal>:
+	  String.  The changeset identification hash, as a
+	  40-character hexadecimal string.</para>
+      </listitem>
+      <listitem><para id="x_592"><literal
+	    role="template-keyword">parents</literal>: List of
+	  strings.  The parents of the changeset.</para>
+      </listitem>
+      <listitem><para id="x_593"><literal role="template-keyword">rev</literal>:
+	  Integer.  The repository-local changeset revision
+	  number.</para>
+      </listitem>
+      <listitem><para id="x_594"><literal role="template-keyword">tags</literal>:
+	  List of strings.  Any tags associated with the
+	  changeset.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_595">A few simple experiments will show us what to expect when we
+      use these keywords; you can see the results below.</para>
+
+&interaction.template.simple.keywords;
+
+    <para id="x_596">As we noted above, the date keyword does not produce
+      human-readable output, so we must treat it specially.  This
+      involves using a <emphasis>filter</emphasis>, about which more
+      in <xref linkend="sec:template:filter"/>.</para>
+
+    &interaction.template.simple.datekeyword;
+
+  </sect1>
+  <sect1 id="sec:template:escape">
+    <title>Escape sequences</title>
+
+    <para id="x_597">Mercurial's templating engine recognises the most commonly
+      used escape sequences in strings.  When it sees a backslash
+      (<quote><literal>\</literal></quote>) character, it looks at the
+      following character and substitutes the two characters with a
+      single replacement, as described below.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_598"><literal>\</literal>:
+	  Backslash, <quote><literal>\</literal></quote>, ASCII
+	  134.</para>
+      </listitem>
+      <listitem><para id="x_599"><literal>\n</literal>: Newline,
+	  ASCII 12.</para>
+      </listitem>
+      <listitem><para id="x_59a"><literal>\r</literal>: Carriage
+	  return, ASCII 15.</para>
+      </listitem>
+      <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
+	  11.</para>
+      </listitem>
+      <listitem><para id="x_59c"><literal>\v</literal>: Vertical
+	  tab, ASCII 13.</para>
+      </listitem>
+      <listitem><para id="x_59d"><literal>{</literal>: Open curly
+	  brace, <quote><literal>{</literal></quote>, ASCII
+	  173.</para>
+      </listitem>
+      <listitem><para id="x_59e"><literal>}</literal>: Close curly
+	  brace, <quote><literal>}</literal></quote>, ASCII
+	  175.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_59f">As indicated above, if you want the expansion of a template
+      to contain a literal <quote><literal>\</literal></quote>,
+      <quote><literal>{</literal></quote>, or
+      <quote><literal>{</literal></quote> character, you must escape
+      it.</para>
+
+  </sect1>
+  <sect1 id="sec:template:filter">
+    <title>Filtering keywords to change their results</title>
+
+    <para id="x_5a0">Some of the results of template expansion are not
+      immediately easy to use.  Mercurial lets you specify an optional
+      chain of <emphasis>filters</emphasis> to modify the result of
+      expanding a keyword.  You have already seen a common filter,
+      <literal role="template-kw-filt-date">isodate</literal>, in
+      action above, to make a date readable.</para>
+
+    <para id="x_5a1">Below is a list of the most commonly used filters that
+      Mercurial supports.  While some filters can be applied to any
+      text, others can only be used in specific circumstances.  The
+      name of each filter is followed first by an indication of where
+      it can be used, then a description of its effect.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_5a2"><literal
+	    role="template-filter">addbreaks</literal>: Any text. Add
+	  an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
+	  before the end of every line except the last.  For example,
+	  <quote><literal>foo\nbar</literal></quote> becomes
+	  <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a3"><literal
+	    role="template-kw-filt-date">age</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the age of the date, relative to the current time.  Yields a
+	  string like <quote><literal>10
+	      minutes</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a4"><literal
+	    role="template-filter">basename</literal>: Any text, but
+	  most useful for the <literal
+	    role="template-keyword">files</literal> keyword and its
+	  relatives.  Treat the text as a path, and return the
+	  basename. For example,
+	  <quote><literal>foo/bar/baz</literal></quote> becomes
+	  <quote><literal>baz</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a5"><literal
+	    role="template-kw-filt-date">date</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render a
+	  date in a similar format to the Unix <literal
+	    role="template-keyword">date</literal> command, but with
+	  timezone included.  Yields a string like <quote><literal>Mon
+	      Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a6"><literal
+	    role="template-kw-filt-author">domain</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Finds
+	  the first string that looks like an email address, and
+	  extract just the domain component.  For example,
+	  <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>serpentine.com</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a7"><literal
+	    role="template-kw-filt-author">email</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Extract
+	  the first string that looks like an email address.  For
+	  example, <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>bos@serpentine.com</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5a8"><literal
+	    role="template-filter">escape</literal>: Any text.
+	  Replace the special XML/XHTML characters
+	  <quote><literal>&amp;</literal></quote>,
+	  <quote><literal>&lt;</literal></quote> and
+	  <quote><literal>&gt;</literal></quote> with XML
+	  entities.</para>
+      </listitem>
+      <listitem><para id="x_5a9"><literal
+	    role="template-filter">fill68</literal>: Any text.  Wrap
+	  the text to fit in 68 columns.  This is useful before you
+	  pass text through the <literal
+	    role="template-filter">tabindent</literal> filter, and
+	  still want it to fit in an 80-column fixed-font
+	  window.</para>
+      </listitem>
+      <listitem><para id="x_5aa"><literal
+	    role="template-filter">fill76</literal>: Any text.  Wrap
+	  the text to fit in 76 columns.</para>
+      </listitem>
+      <listitem><para id="x_5ab"><literal
+	    role="template-filter">firstline</literal>: Any text.
+	  Yield the first line of text, without any trailing
+	  newlines.</para>
+      </listitem>
+      <listitem><para id="x_5ac"><literal
+	    role="template-kw-filt-date">hgdate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the date as a pair of readable numbers.  Yields a string
+	  like <quote><literal>1157407993
+	      25200</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5ad"><literal
+	    role="template-kw-filt-date">isodate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the date as a text string in ISO 8601 format.  Yields a
+	  string like <quote><literal>2006-09-04 15:13:13
+	      -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5ae"><literal
+	    role="template-filter">obfuscate</literal>: Any text, but
+	  most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Yield
+	  the input text rendered as a sequence of XML entities.  This
+	  helps to defeat some particularly stupid screen-scraping
+	  email harvesting spambots.</para>
+      </listitem>
+      <listitem><para id="x_5af"><literal
+	    role="template-kw-filt-author">person</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Yield
+	  the text before an email address. For example,
+	  <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b0"><literal
+	    role="template-kw-filt-date">rfc822date</literal>:
+	  <literal role="template-keyword">date</literal> keyword.
+	  Render a date using the same format used in email headers.
+	  Yields a string like <quote><literal>Mon, 04 Sep 2006
+	      15:13:13 -0700</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b1"><literal
+	    role="template-kw-filt-node">short</literal>: Changeset
+	  hash.  Yield the short form of a changeset hash, i.e. a
+	  12-character hexadecimal string.</para>
+      </listitem>
+      <listitem><para id="x_5b2"><literal
+	    role="template-kw-filt-date">shortdate</literal>: <literal
+	    role="template-keyword">date</literal> keyword.  Render
+	  the year, month, and day of the date.  Yields a string like
+	  <quote><literal>2006-09-04</literal></quote>.</para>
+      </listitem>
+      <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
+	  Any text.  Strip all leading and trailing whitespace from
+	  the string.</para>
+      </listitem>
+      <listitem><para id="x_5b4"><literal
+	    role="template-filter">tabindent</literal>: Any text.
+	  Yield the text, with every line except the first starting
+	  with a tab character.</para>
+      </listitem>
+      <listitem><para id="x_5b5"><literal
+	    role="template-filter">urlescape</literal>: Any text.
+	  Escape all characters that are considered
+	  <quote>special</quote> by URL parsers.  For example,
+	  <literal>foo bar</literal> becomes
+	  <literal>foo%20bar</literal>.</para>
+      </listitem>
+      <listitem><para id="x_5b6"><literal
+	    role="template-kw-filt-author">user</literal>: Any text,
+	  but most useful for the <literal
+	    role="template-keyword">author</literal> keyword.  Return
+	  the <quote>user</quote> portion of an email address.  For
+	  example, <quote><literal>Bryan O'Sullivan
+	      &lt;bos@serpentine.com&gt;</literal></quote> becomes
+	  <quote><literal>bos</literal></quote>.</para>
+      </listitem></itemizedlist>
+
+&interaction.template.simple.manyfilters;
+
+    <note>
+      <para id="x_5b7">  If you try to apply a filter to a piece of data that it
+	cannot process, Mercurial will fail and print a Python
+	exception.  For example, trying to run the output of the
+	<literal role="template-keyword">desc</literal> keyword into
+	the <literal role="template-kw-filt-date">isodate</literal>
+	filter is not a good idea.</para>
+    </note>
+
+    <sect2>
+      <title>Combining filters</title>
+
+      <para id="x_5b8">It is easy to combine filters to yield output in the form
+	you would like.  The following chain of filters tidies up a
+	description, then makes sure that it fits cleanly into 68
+	columns, then indents it by a further 8 characters (at least
+	on Unix-like systems, where a tab is conventionally 8
+	characters wide).</para>
+
+      &interaction.template.simple.combine;
+
+      <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
+	tab character) in the template to force the first line to be
+	indented; this is necessary since <literal
+	  role="template-keyword">tabindent</literal> indents all
+	lines <emphasis>except</emphasis> the first.</para>
+
+      <para id="x_5ba">Keep in mind that the order of filters in a chain is
+	significant.  The first filter is applied to the result of the
+	keyword; the second to the result of the first filter; and so
+	on.  For example, using <literal>fill68|tabindent</literal>
+	gives very different results from
+	<literal>tabindent|fill68</literal>.</para>
+
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>From templates to styles</title>
+
+    <para id="x_5bb">A command line template provides a quick and simple way to
+      format some output.  Templates can become verbose, though, and
+      it's useful to be able to give a template a name.  A style file
+      is a template with a name, stored in a file.</para>
+
+    <para id="x_5bc">More than that, using a style file unlocks the power of
+      Mercurial's templating engine in ways that are not possible
+      using the command line <option
+	role="hg-opt-log">--template</option> option.</para>
+
+    <sect2>
+      <title>The simplest of style files</title>
+
+      <para id="x_5bd">Our simple style file contains just one line:</para>
+
+      &interaction.template.simple.rev;
+
+      <para id="x_5be">This tells Mercurial, <quote>if you're printing a
+	  changeset, use the text on the right as the
+	  template</quote>.</para>
+
+    </sect2>
+    <sect2>
+      <title>Style file syntax</title>
+
+      <para id="x_5bf">The syntax rules for a style file are simple.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_5c0">The file is processed one line at a
+	    time.</para>
+	</listitem>
+	<listitem><para id="x_5c1">Leading and trailing white space are
+	    ignored.</para>
+	</listitem>
+	<listitem><para id="x_5c2">Empty lines are skipped.</para>
+	</listitem>
+	<listitem><para id="x_5c3">If a line starts with either of the characters
+	    <quote><literal>#</literal></quote> or
+	    <quote><literal>;</literal></quote>, the entire line is
+	    treated as a comment, and skipped as if empty.</para>
+	</listitem>
+	<listitem><para id="x_5c4">A line starts with a keyword.  This must start
+	    with an alphabetic character or underscore, and can
+	    subsequently contain any alphanumeric character or
+	    underscore.  (In regexp notation, a keyword must match
+	    <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
+	</listitem>
+	<listitem><para id="x_5c5">The next element must be an
+	    <quote><literal>=</literal></quote> character, which can
+	    be preceded or followed by an arbitrary amount of white
+	    space.</para>
+	</listitem>
+	<listitem><para id="x_5c6">If the rest of the line starts and ends with
+	    matching quote characters (either single or double quote),
+	    it is treated as a template body.</para>
+	</listitem>
+	<listitem><para id="x_5c7">If the rest of the line <emphasis>does
+	      not</emphasis> start with a quote character, it is
+	    treated as the name of a file; the contents of this file
+	    will be read and used as a template body.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Style files by example</title>
+
+    <para id="x_5c8">To illustrate how to write a style file, we will construct a
+      few by example.  Rather than provide a complete style file and
+      walk through it, we'll mirror the usual process of developing a
+      style file by starting with something very simple, and walking
+      through a series of successively more complete examples.</para>
+
+    <sect2>
+      <title>Identifying mistakes in style files</title>
+
+      <para id="x_5c9">If Mercurial encounters a problem in a style file you are
+	working on, it prints a terse error message that, once you
+	figure out what it means, is actually quite useful.</para>
+
+&interaction.template.svnstyle.syntax.input;
+
+      <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
+	define a <literal>changeset</literal> keyword, but forgets to
+	give any content for it. When instructed to use this style
+	file, Mercurial promptly complains.</para>
+
+      &interaction.template.svnstyle.syntax.error;
+
+      <para id="x_5cb">This error message looks intimidating, but it is not too
+	hard to follow.</para>
+
+      <itemizedlist>
+	<listitem><para id="x_5cc">The first component is simply Mercurial's way
+	    of saying <quote>I am giving up</quote>.</para>
+	  <programlisting>___abort___: broken.style:1: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5cd">Next comes the name of the style file that
+	    contains the error.</para>
+	  <programlisting>abort: ___broken.style___:1: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5ce">Following the file name is the line number
+	    where the error was encountered.</para>
+	  <programlisting>abort: broken.style:___1___: parse error</programlisting>
+	</listitem>
+	<listitem><para id="x_5cf">Finally, a description of what went
+	    wrong.</para>
+	  <programlisting>abort: broken.style:1: ___parse error___</programlisting>
+	</listitem>
+	<listitem><para id="x_5d0">The description of the problem is not always
+	    clear (as in this case), but even when it is cryptic, it
+	    is almost always trivial to visually inspect the offending
+	    line in the style file and see what is wrong.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Uniquely identifying a repository</title>
+
+      <para id="x_5d1">If you would like to be able to identify a Mercurial
+	repository <quote>fairly uniquely</quote> using a short string
+	as an identifier, you can use the first revision in the
+	repository.</para>
+
+      &interaction.template.svnstyle.id;
+
+      <para id="x_5d2">This is not guaranteed to be unique, but it is
+	nevertheless useful in many cases.</para>
+      <itemizedlist>
+	<listitem><para id="x_5d3">It will not work in a completely empty
+	    repository, because such a repository does not have a
+	    revision zero.</para>
+	</listitem>
+	<listitem><para id="x_5d4">Neither will it work in the (extremely rare)
+	    case where a repository is a merge of two or more formerly
+	    independent repositories, and you still have those
+	    repositories around.</para>
+	</listitem></itemizedlist>
+      <para id="x_5d5">Here are some uses to which you could put this
+	identifier:</para>
+      <itemizedlist>
+	<listitem><para id="x_5d6">As a key into a table for a database that
+	    manages repositories on a server.</para>
+	</listitem>
+	<listitem><para id="x_5d7">As half of a {<emphasis>repository
+	      ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
+	    Save this information away when you run an automated build
+	    or other activity, so that you can <quote>replay</quote>
+	    the build later if necessary.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Mimicking Subversion's output</title>
+
+      <para id="x_5d8">Let's try to emulate the default output format used by
+	another revision control tool, Subversion.</para>
+
+      &interaction.template.svnstyle.short;
+
+      <para id="x_5d9">Since Subversion's output style is fairly simple, it is
+	easy to copy-and-paste a hunk of its output into a file, and
+	replace the text produced above by Subversion with the
+	template values we'd like to see expanded.</para>
+
+      &interaction.template.svnstyle.template;
+
+      <para id="x_5da">There are a few small ways in which this template deviates
+	from the output produced by Subversion.</para>
+      <itemizedlist>
+	<listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
+	    date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
+	    example output above) in parentheses.  Mercurial's
+	    templating engine does not provide a way to display a date
+	    in this format without also printing the time and time
+	    zone.</para>
+	</listitem>
+	<listitem><para id="x_5dc">We emulate Subversion's printing of
+	    <quote>separator</quote> lines full of
+	    <quote><literal>-</literal></quote> characters by ending
+	    the template with such a line. We use the templating
+	    engine's <literal role="template-keyword">header</literal>
+	    keyword to print a separator line as the first line of
+	    output (see below), thus achieving similar output to
+	    Subversion.</para>
+	</listitem>
+	<listitem><para id="x_5dd">Subversion's output includes a count in the
+	    header of the number of lines in the commit message.  We
+	    cannot replicate this in Mercurial; the templating engine
+	    does not currently provide a filter that counts the number
+	    of lines the template generates.</para>
+	</listitem></itemizedlist>
+      <para id="x_5de">It took me no more than a minute or two of work to replace
+	literal text from an example of Subversion's output with some
+	keywords and filters to give the template above.  The style
+	file simply refers to the template.</para>
+
+      &interaction.template.svnstyle.style;
+
+      <para id="x_5df">We could have included the text of the template file
+	directly in the style file by enclosing it in quotes and
+	replacing the newlines with
+	<quote><literal>\n</literal></quote> sequences, but it would
+	have made the style file too difficult to read.  Readability
+	is a good guide when you're trying to decide whether some text
+	belongs in a style file, or in a template file that the style
+	file points to.  If the style file will look too big or
+	cluttered if you insert a literal piece of text, drop it into
+	a template instead.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch11-mq.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1321 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:mq">
+  <?dbhtml filename="managing-change-with-mercurial-queues.html"?>
+  <title>Managing change with Mercurial Queues</title>
+
+  <sect1 id="sec:mq:patch-mgmt">
+    <title>The patch management problem</title>
+
+    <para id="x_3ac">Here is a common scenario: you need to install a software
+      package from source, but you find a bug that you must fix in the
+      source before you can start using the package.  You make your
+      changes, forget about the package for a while, and a few months
+      later you need to upgrade to a newer version of the package.  If
+      the newer version of the package still has the bug, you must
+      extract your fix from the older source tree and apply it against
+      the newer version.  This is a tedious task, and it's easy to
+      make mistakes.</para>
+
+    <para id="x_3ad">This is a simple case of the <quote>patch management</quote>
+      problem.  You have an <quote>upstream</quote> source tree that
+      you can't change; you need to make some local changes on top of
+      the upstream tree; and you'd like to be able to keep those
+      changes separate, so that you can apply them to newer versions
+      of the upstream source.</para>
+
+    <para id="x_3ae">The patch management problem arises in many situations.
+      Probably the most visible is that a user of an open source
+      software project will contribute a bug fix or new feature to the
+      project's maintainers in the form of a patch.</para>
+
+    <para id="x_3af">Distributors of operating systems that include open source
+      software often need to make changes to the packages they
+      distribute so that they will build properly in their
+      environments.</para>
+
+    <para id="x_3b0">When you have few changes to maintain, it is easy to manage
+      a single patch using the standard <command>diff</command> and
+      <command>patch</command> programs (see <xref
+	linkend="sec:mq:patch"/> for a discussion of these
+      tools). Once the number of changes grows, it starts to make
+      sense to maintain patches as discrete <quote>chunks of
+	work,</quote> so that for example a single patch will contain
+      only one bug fix (the patch might modify several files, but it's
+      doing <quote>only one thing</quote>), and you may have a number
+      of such patches for different bugs you need fixed and local
+      changes you require.  In this situation, if you submit a bug fix
+      patch to the upstream maintainers of a package and they include
+      your fix in a subsequent release, you can simply drop that
+      single patch when you're updating to the newer release.</para>
+
+    <para id="x_3b1">Maintaining a single patch against an upstream tree is a
+      little tedious and error-prone, but not difficult.  However, the
+      complexity of the problem grows rapidly as the number of patches
+      you have to maintain increases.  With more than a tiny number of
+      patches in hand, understanding which ones you have applied and
+      maintaining them moves from messy to overwhelming.</para>
+
+    <para id="x_3b2">Fortunately, Mercurial includes a powerful extension,
+      Mercurial Queues (or simply <quote>MQ</quote>), that massively
+      simplifies the patch management problem.</para>
+
+  </sect1>
+  <sect1 id="sec:mq:history">
+    <title>The prehistory of Mercurial Queues</title>
+
+    <para id="x_3b3">During the late 1990s, several Linux kernel developers
+      started to maintain <quote>patch series</quote> that modified
+      the behavior of the Linux kernel.  Some of these series were
+      focused on stability, some on feature coverage, and others were
+      more speculative.</para>
+
+    <para id="x_3b4">The sizes of these patch series grew rapidly.  In 2002,
+      Andrew Morton published some shell scripts he had been using to
+      automate the task of managing his patch queues.  Andrew was
+      successfully using these scripts to manage hundreds (sometimes
+      thousands) of patches on top of the Linux kernel.</para>
+
+    <sect2 id="sec:mq:quilt">
+      <title>A patchwork quilt</title>
+
+      <para id="x_3b5">In early 2003, Andreas Gruenbacher and Martin Quinson
+	borrowed the approach of Andrew's scripts and published a tool
+	called <quote>patchwork quilt</quote>
+	<citation>web:quilt</citation>, or simply <quote>quilt</quote>
+	(see <citation>gruenbacher:2005</citation> for a paper
+	describing it).  Because quilt substantially automated patch
+	management, it rapidly gained a large following among open
+	source software developers.</para>
+
+      <para id="x_3b6">Quilt manages a <emphasis>stack of patches</emphasis> on
+	top of a directory tree. To begin, you tell quilt to manage a
+	directory tree, and tell it which files you want to manage; it
+	stores away the names and contents of those files.  To fix a
+	bug, you create a new patch (using a single command), edit the
+	files you need to fix, then <quote>refresh</quote> the
+	patch.</para>
+
+      <para id="x_3b7">The refresh step causes quilt to scan the directory tree;
+	it updates the patch with all of the changes you have made.
+	You can create another patch on top of the first, which will
+	track the changes required to modify the tree from <quote>tree
+	  with one patch applied</quote> to <quote>tree with two
+	  patches applied</quote>.</para>
+
+      <para id="x_3b8">You can <emphasis>change</emphasis> which patches are
+	applied to the tree.  If you <quote>pop</quote> a patch, the
+	changes made by that patch will vanish from the directory
+	tree.  Quilt remembers which patches you have popped, though,
+	so you can <quote>push</quote> a popped patch again, and the
+	directory tree will be restored to contain the modifications
+	in the patch.  Most importantly, you can run the
+	<quote>refresh</quote> command at any time, and the topmost
+	applied patch will be updated.  This means that you can, at
+	any time, change both which patches are applied and what
+	modifications those patches make.</para>
+
+      <para id="x_3b9">Quilt knows nothing about revision control tools, so it
+	works equally well on top of an unpacked tarball or a
+	Subversion working copy.</para>
+
+    </sect2>
+    <sect2 id="sec:mq:quilt-mq">
+      <title>From patchwork quilt to Mercurial Queues</title>
+
+      <para id="x_3ba">In mid-2005, Chris Mason took the features of quilt and
+	wrote an extension that he called Mercurial Queues, which
+	added quilt-like behavior to Mercurial.</para>
+
+      <para id="x_3bb">The key difference between quilt and MQ is that quilt
+	knows nothing about revision control systems, while MQ is
+	<emphasis>integrated</emphasis> into Mercurial.  Each patch
+	that you push is represented as a Mercurial changeset.  Pop a
+	patch, and the changeset goes away.</para>
+
+      <para id="x_3bc">Because quilt does not care about revision control tools,
+	it is still a tremendously useful piece of software to know
+	about for situations where you cannot use Mercurial and
+	MQ.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>The huge advantage of MQ</title>
+
+    <para id="x_3bd">I cannot overstate the value that MQ offers through the
+      unification of patches and revision control.</para>
+
+    <para id="x_3be">A major reason that patches have persisted in the free
+      software and open source world&emdash;in spite of the
+      availability of increasingly capable revision control tools over
+      the years&emdash;is the <emphasis>agility</emphasis> they
+      offer.</para>
+
+    <para id="x_3bf">Traditional revision control tools make a permanent,
+      irreversible record of everything that you do.  While this has
+      great value, it's also somewhat stifling.  If you want to
+      perform a wild-eyed experiment, you have to be careful in how
+      you go about it, or you risk leaving unneeded&emdash;or worse,
+      misleading or destabilising&emdash;traces of your missteps and
+      errors in the permanent revision record.</para>
+
+    <para id="x_3c0">By contrast, MQ's marriage of distributed revision control
+      with patches makes it much easier to isolate your work.  Your
+      patches live on top of normal revision history, and you can make
+      them disappear or reappear at will.  If you don't like a patch,
+      you can drop it.  If a patch isn't quite as you want it to be,
+      simply fix it&emdash;as many times as you need to, until you
+      have refined it into the form you desire.</para>
+
+    <para id="x_3c1">As an example, the integration of patches with revision
+      control makes understanding patches and debugging their
+      effects&emdash;and their interplay with the code they're based
+      on&emdash;<emphasis>enormously</emphasis> easier. Since every
+      applied patch has an associated changeset, you can give <command
+	role="hg-cmd">hg log</command> a file name to see which
+      changesets and patches affected the file.  You can use the
+      <command role="hg-cmd">hg bisect</command> command to
+      binary-search through all changesets and applied patches to see
+      where a bug got introduced or fixed.  You can use the <command
+	role="hg-cmd">hg annotate</command> command to see which
+      changeset or patch modified a particular line of a source file.
+      And so on.</para>
+
+  </sect1>
+  <sect1 id="sec:mq:patch">
+    <title>Understanding patches</title>
+
+    <para id="x_3c2">Because MQ doesn't hide its patch-oriented nature, it is
+      helpful to understand what patches are, and a little about the
+      tools that work with them.</para>
+
+    <para id="x_3c3">The traditional Unix <command>diff</command> command
+      compares two files, and prints a list of differences between
+      them. The <command>patch</command> command understands these
+      differences as <emphasis>modifications</emphasis> to make to a
+      file.  Take a look below for a simple example of these commands
+      in action.</para>
+
+&interaction.mq.dodiff.diff;
+
+    <para id="x_3c4">The type of file that <command>diff</command> generates (and
+      <command>patch</command> takes as input) is called a
+      <quote>patch</quote> or a <quote>diff</quote>; there is no
+      difference between a patch and a diff.  (We'll use the term
+      <quote>patch</quote>, since it's more commonly used.)</para>
+
+    <para id="x_3c5">A patch file can start with arbitrary text; the
+      <command>patch</command> command ignores this text, but MQ uses
+      it as the commit message when creating changesets.  To find the
+      beginning of the patch content, <command>patch</command>
+      searches for the first line that starts with the string
+      <quote><literal>diff -</literal></quote>.</para>
+
+    <para id="x_3c6">MQ works with <emphasis>unified</emphasis> diffs
+      (<command>patch</command> can accept several other diff formats,
+      but MQ doesn't).  A unified diff contains two kinds of header.
+      The <emphasis>file header</emphasis> describes the file being
+      modified; it contains the name of the file to modify.  When
+      <command>patch</command> sees a new file header, it looks for a
+      file with that name to start modifying.</para>
+
+    <para id="x_3c7">After the file header comes a series of
+      <emphasis>hunks</emphasis>.  Each hunk starts with a header;
+      this identifies the range of line numbers within the file that
+      the hunk should modify.  Following the header, a hunk starts and
+      ends with a few (usually three) lines of text from the
+      unmodified file; these are called the
+      <emphasis>context</emphasis> for the hunk.  If there's only a
+      small amount of context between successive hunks,
+      <command>diff</command> doesn't print a new hunk header; it just
+      runs the hunks together, with a few lines of context between
+      modifications.</para>
+
+    <para id="x_3c8">Each line of context begins with a space character.  Within
+      the hunk, a line that begins with
+      <quote><literal>-</literal></quote> means <quote>remove this
+	line,</quote> while a line that begins with
+      <quote><literal>+</literal></quote> means <quote>insert this
+	line.</quote>  For example, a line that is modified is
+      represented by one deletion and one insertion.</para>
+
+    <para id="x_3c9">We will return to some of the more subtle aspects of patches
+      later (in <xref linkend="sec:mq:adv-patch"/>), but you
+      should have
+      enough information now to use MQ.</para>
+
+  </sect1>
+  <sect1 id="sec:mq:start">
+    <title>Getting started with Mercurial Queues</title>
+
+    <para id="x_3ca">Because MQ is implemented as an extension, you must
+      explicitly enable before you can use it.  (You don't need to
+      download anything; MQ ships with the standard Mercurial
+      distribution.)  To enable MQ, edit your <filename
+	role="home">~/.hgrc</filename> file, and add the lines
+      below.</para>
+
+    <programlisting>[extensions]
+hgext.mq =</programlisting>
+
+    <para id="x_3cb">Once the extension is enabled, it will make a number of new
+      commands available.  To verify that the extension is working,
+      you can use <command role="hg-cmd">hg help</command> to see if
+      the <command role="hg-ext-mq">qinit</command> command is now
+      available.</para>
+
+&interaction.mq.qinit-help.help;
+
+    <para id="x_3cc">You can use MQ with <emphasis>any</emphasis> Mercurial
+      repository, and its commands only operate within that
+      repository.  To get started, simply prepare the repository using
+      the <command role="hg-ext-mq">qinit</command> command.</para>
+
+&interaction.mq.tutorial.qinit;
+
+    <para id="x_3cd">This command creates an empty directory called <filename
+	role="special" class="directory">.hg/patches</filename>, where
+      MQ will keep its metadata.  As with many Mercurial commands, the
+      <command role="hg-ext-mq">qinit</command> command prints nothing
+      if it succeeds.</para>
+
+    <sect2>
+      <title>Creating a new patch</title>
+
+      <para id="x_3ce">To begin work on a new patch, use the <command
+	  role="hg-ext-mq">qnew</command> command.  This command takes
+	one argument, the name of the patch to create.</para>
+
+      <para id="x_3cf">MQ will use this as the name of an actual file in the
+	<filename role="special"
+	  class="directory">.hg/patches</filename> directory, as you
+	can see below.</para>
+
+&interaction.mq.tutorial.qnew;
+
+      <para id="x_3d0">Also newly present in the <filename role="special"
+	  class="directory">.hg/patches</filename> directory are two
+	other files, <filename role="special">series</filename> and
+	<filename role="special">status</filename>.  The <filename
+	  role="special">series</filename> file lists all of the
+	patches that MQ knows about for this repository, with one
+	patch per line.  Mercurial uses the <filename
+	  role="special">status</filename> file for internal
+	book-keeping; it tracks all of the patches that MQ has
+	<emphasis>applied</emphasis> in this repository.</para>
+
+      <note>
+	<para id="x_3d1">  You may sometimes want to edit the <filename
+	    role="special">series</filename> file by hand; for
+	  example, to change the sequence in which some patches are
+	  applied.  However, manually editing the <filename
+	    role="special">status</filename> file is almost always a
+	  bad idea, as it's easy to corrupt MQ's idea of what is
+	  happening.</para>
+      </note>
+
+      <para id="x_3d2">Once you have created your new patch, you can edit files
+	in the working directory as you usually would.  All of the
+	normal Mercurial commands, such as <command role="hg-cmd">hg
+	  diff</command> and <command role="hg-cmd">hg
+	  annotate</command>, work exactly as they did before.</para>
+
+    </sect2>
+    <sect2>
+      <title>Refreshing a patch</title>
+
+      <para id="x_3d3">When you reach a point where you want to save your work,
+	use the <command role="hg-ext-mq">qrefresh</command> command
+	to update the patch you are working on.</para>
+
+&interaction.mq.tutorial.qrefresh;
+
+      <para id="x_3d4">This command folds the changes you have made in the
+	working directory into your patch, and updates its
+	corresponding changeset to contain those changes.</para>
+
+      <para id="x_3d5">You can run <command role="hg-ext-mq">qrefresh</command>
+	as often as you like, so it's a good way to
+	<quote>checkpoint</quote> your work.  Refresh your patch at an
+	opportune time; try an experiment; and if the experiment
+	doesn't work out, <command role="hg-cmd">hg revert</command>
+	your modifications back to the last time you refreshed.</para>
+
+&interaction.mq.tutorial.qrefresh2;
+
+    </sect2>
+    <sect2>
+      <title>Stacking and tracking patches</title>
+
+      <para id="x_3d6">Once you have finished working on a patch, or need to work
+	on another, you can use the <command
+	  role="hg-ext-mq">qnew</command> command again to create a
+	new patch. Mercurial will apply this patch on top of your
+	existing patch.</para>
+
+&interaction.mq.tutorial.qnew2;
+      <para id="x_3d7">Notice that the patch contains the changes in our prior
+	patch as part of its context (you can see this more clearly in
+	the output of <command role="hg-cmd">hg
+	  annotate</command>).</para>
+
+      <para id="x_3d8">So far, with the exception of <command
+	  role="hg-ext-mq">qnew</command> and <command
+	  role="hg-ext-mq">qrefresh</command>, we've been careful to
+	only use regular Mercurial commands.  However, MQ provides
+	many commands that are easier to use when you are thinking
+	about patches, as illustrated below.</para>
+
+&interaction.mq.tutorial.qseries;
+
+      <itemizedlist>
+	<listitem><para id="x_3d9">The <command
+	      role="hg-ext-mq">qseries</command> command lists every
+	    patch that MQ knows about in this repository, from oldest
+	    to newest (most recently
+	    <emphasis>created</emphasis>).</para>
+	</listitem>
+	<listitem><para id="x_3da">The <command
+	      role="hg-ext-mq">qapplied</command> command lists every
+	    patch that MQ has <emphasis>applied</emphasis> in this
+	    repository, again from oldest to newest (most recently
+	    applied).</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+    <sect2>
+      <title>Manipulating the patch stack</title>
+
+      <para id="x_3db">The previous discussion implied that there must be a
+	difference between <quote>known</quote> and
+	<quote>applied</quote> patches, and there is.  MQ can manage a
+	patch without it being applied in the repository.</para>
+
+      <para id="x_3dc">An <emphasis>applied</emphasis> patch has a corresponding
+	changeset in the repository, and the effects of the patch and
+	changeset are visible in the working directory.  You can undo
+	the application of a patch using the <command
+	  role="hg-ext-mq">qpop</command> command.  MQ still
+	<emphasis>knows about</emphasis>, or manages, a popped patch,
+	but the patch no longer has a corresponding changeset in the
+	repository, and the working directory does not contain the
+	changes made by the patch.  <xref
+	  linkend="fig:mq:stack"/> illustrates
+	the difference between applied and tracked patches.</para>
+
+      <figure id="fig:mq:stack">
+	<title>Applied and unapplied patches in the MQ patch
+	  stack</title>
+	<mediaobject>
+	  <imageobject><imagedata fileref="figs/mq-stack.png"/></imageobject>
+	  <textobject><phrase>XXX add text</phrase></textobject>
+	</mediaobject>
+      </figure>
+
+      <para id="x_3de">You can reapply an unapplied, or popped, patch using the
+	<command role="hg-ext-mq">qpush</command> command.  This
+	creates a new changeset to correspond to the patch, and the
+	patch's changes once again become present in the working
+	directory.  See below for examples of <command
+	  role="hg-ext-mq">qpop</command> and <command
+	  role="hg-ext-mq">qpush</command> in action.</para>
+&interaction.mq.tutorial.qpop;
+
+      <para id="x_3df">Notice that once we have popped a patch or two patches,
+	the output of <command role="hg-ext-mq">qseries</command>
+	remains the same, while that of <command
+	  role="hg-ext-mq">qapplied</command> has changed.</para>
+
+
+    </sect2>
+    <sect2>
+      <title>Pushing and popping many patches</title>
+
+      <para id="x_3e0">While <command role="hg-ext-mq">qpush</command> and
+	<command role="hg-ext-mq">qpop</command> each operate on a
+	single patch at a time by default, you can push and pop many
+	patches in one go.  The <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
+	<command role="hg-ext-mq">qpush</command> causes it to push
+	all unapplied patches, while the <option
+	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
+	  role="hg-ext-mq">qpop</command> causes it to pop all applied
+	patches.  (For some more ways to push and pop many patches,
+	see <xref linkend="sec:mq:perf"/> below.)</para>
+
+&interaction.mq.tutorial.qpush-a;
+
+    </sect2>
+    <sect2>
+      <title>Safety checks, and overriding them</title>
+
+      <para id="x_3e1">Several MQ commands check the working directory before
+	they do anything, and fail if they find any modifications.
+	They do this to ensure that you won't lose any changes that
+	you have made, but not yet incorporated into a patch.  The
+	example below illustrates this; the <command
+	  role="hg-ext-mq">qnew</command> command will not create a
+	new patch if there are outstanding changes, caused in this
+	case by the <command role="hg-cmd">hg add</command> of
+	<filename>file3</filename>.</para>
+
+&interaction.mq.tutorial.add;
+
+      <para id="x_3e2">Commands that check the working directory all take an
+	<quote>I know what I'm doing</quote> option, which is always
+	named <option>-f</option>.  The exact meaning of
+	<option>-f</option> depends on the command.  For example,
+	<command role="hg-cmd">hg qnew <option
+	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
+	will incorporate any outstanding changes into the new patch it
+	creates, but <command role="hg-cmd">hg qpop <option
+	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
+	will revert modifications to any files affected by the patch
+	that it is popping.  Be sure to read the documentation for a
+	command's <option>-f</option> option before you use it!</para>
+
+    </sect2>
+    <sect2>
+      <title>Working on several patches at once</title>
+
+      <para id="x_3e3">The <command role="hg-ext-mq">qrefresh</command> command
+	always refreshes the <emphasis>topmost</emphasis> applied
+	patch.  This means that you can suspend work on one patch (by
+	refreshing it), pop or push to make a different patch the top,
+	and work on <emphasis>that</emphasis> patch for a
+	while.</para>
+
+      <para id="x_3e4">Here's an example that illustrates how you can use this
+	ability. Let's say you're developing a new feature as two
+	patches.  The first is a change to the core of your software,
+	and the second&emdash;layered on top of the
+	first&emdash;changes the user interface to use the code you
+	just added to the core.  If you notice a bug in the core while
+	you're working on the UI patch, it's easy to fix the core.
+	Simply <command role="hg-ext-mq">qrefresh</command> the UI
+	patch to save your in-progress changes, and <command
+	  role="hg-ext-mq">qpop</command> down to the core patch.  Fix
+	the core bug, <command role="hg-ext-mq">qrefresh</command> the
+	core patch, and <command role="hg-ext-mq">qpush</command> back
+	to the UI patch to continue where you left off.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:mq:adv-patch">
+    <title>More about patches</title>
+
+    <para id="x_3e5">MQ uses the GNU <command>patch</command> command to apply
+      patches, so it's helpful to know a few more detailed aspects of
+      how <command>patch</command> works, and about patches
+      themselves.</para>
+
+    <sect2>
+      <title>The strip count</title>
+
+      <para id="x_3e6">If you look at the file headers in a patch, you will
+	notice that the pathnames usually have an extra component on
+	the front that isn't present in the actual path name.  This is
+	a holdover from the way that people used to generate patches
+	(people still do this, but it's somewhat rare with modern
+	revision control tools).</para>
+
+      <para id="x_3e7">Alice would unpack a tarball, edit her files, then decide
+	that she wanted to create a patch.  So she'd rename her
+	working directory, unpack the tarball again (hence the need
+	for the rename), and use the <option
+	  role="cmd-opt-diff">-r</option> and <option
+	  role="cmd-opt-diff">-N</option> options to
+	<command>diff</command> to recursively generate a patch
+	between the unmodified directory and the modified one.  The
+	result would be that the name of the unmodified directory
+	would be at the front of the left-hand path in every file
+	header, and the name of the modified directory would be at the
+	front of the right-hand path.</para>
+
+      <para id="x_3e8">Since someone receiving a patch from the Alices of the net
+	would be unlikely to have unmodified and modified directories
+	with exactly the same names, the <command>patch</command>
+	command has a <option role="cmd-opt-patch">-p</option> option
+	that indicates the number of leading path name components to
+	strip when trying to apply a patch.  This number is called the
+	<emphasis>strip count</emphasis>.</para>
+
+      <para id="x_3e9">An option of <quote><literal>-p1</literal></quote> means
+	<quote>use a strip count of one</quote>.  If
+	<command>patch</command> sees a file name
+	<filename>foo/bar/baz</filename> in a file header, it will
+	strip <filename>foo</filename> and try to patch a file named
+	<filename>bar/baz</filename>.  (Strictly speaking, the strip
+	count refers to the number of <emphasis>path
+	  separators</emphasis> (and the components that go with them
+	) to strip.  A strip count of one will turn
+	<filename>foo/bar</filename> into <filename>bar</filename>,
+	but <filename>/foo/bar</filename> (notice the extra leading
+	slash) into <filename>foo/bar</filename>.)</para>
+
+      <para id="x_3ea">The <quote>standard</quote> strip count for patches is
+	one; almost all patches contain one leading path name
+	component that needs to be stripped. Mercurial's <command
+	  role="hg-cmd">hg diff</command> command generates path names
+	in this form, and the <command role="hg-cmd">hg
+	  import</command> command and MQ expect patches to have a
+	strip count of one.</para>
+
+      <para id="x_3eb">If you receive a patch from someone that you want to add
+	to your patch queue, and the patch needs a strip count other
+	than one, you cannot just <command
+	  role="hg-ext-mq">qimport</command> the patch, because
+	<command role="hg-ext-mq">qimport</command> does not yet have
+	a <literal>-p</literal> option (see <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue311">issue
+	  311</ulink>).  Your best bet is to <command
+	  role="hg-ext-mq">qnew</command> a patch of your own, then
+	use <command>patch -pN</command> to apply their patch,
+	followed by <command role="hg-cmd">hg addremove</command> to
+	pick up any files added or removed by the patch, followed by
+	<command role="hg-ext-mq">hg qrefresh</command>. This
+	complexity may become unnecessary; see <ulink role="hg-bug"
+	  url="http://www.selenic.com/mercurial/bts/issue311">issue
+	  311</ulink> for details.
+      </para>
+    </sect2>
+    <sect2>
+      <title>Strategies for applying a patch</title>
+
+      <para id="x_3ec">When <command>patch</command> applies a hunk, it tries a
+	handful of successively less accurate strategies to try to
+	make the hunk apply. This falling-back technique often makes
+	it possible to take a patch that was generated against an old
+	version of a file, and apply it against a newer version of
+	that file.</para>
+
+      <para id="x_3ed">First, <command>patch</command> tries an exact match,
+	where the line numbers, the context, and the text to be
+	modified must apply exactly.  If it cannot make an exact
+	match, it tries to find an exact match for the context,
+	without honouring the line numbering information.  If this
+	succeeds, it prints a line of output saying that the hunk was
+	applied, but at some <emphasis>offset</emphasis> from the
+	original line number.</para>
+
+      <para id="x_3ee">If a context-only match fails, <command>patch</command>
+	removes the first and last lines of the context, and tries a
+	<emphasis>reduced</emphasis> context-only match.  If the hunk
+	with reduced context succeeds, it prints a message saying that
+	it applied the hunk with a <emphasis>fuzz factor</emphasis>
+	(the number after the fuzz factor indicates how many lines of
+	context <command>patch</command> had to trim before the patch
+	applied).</para>
+
+      <para id="x_3ef">When neither of these techniques works,
+	<command>patch</command> prints a message saying that the hunk
+	in question was rejected.  It saves rejected hunks (also
+	simply called <quote>rejects</quote>) to a file with the same
+	name, and an added <filename role="special">.rej</filename>
+	extension.  It also saves an unmodified copy of the file with
+	a <filename role="special">.orig</filename> extension; the
+	copy of the file without any extensions will contain any
+	changes made by hunks that <emphasis>did</emphasis> apply
+	cleanly.  If you have a patch that modifies
+	<filename>foo</filename> with six hunks, and one of them fails
+	to apply, you will have: an unmodified
+	<filename>foo.orig</filename>, a <filename>foo.rej</filename>
+	containing one hunk, and <filename>foo</filename>, containing
+	the changes made by the five successful hunks.</para>
+
+    </sect2>
+    <sect2>
+      <title>Some quirks of patch representation</title>
+
+      <para id="x_3f0">There are a few useful things to know about how
+	<command>patch</command> works with files.</para>
+      <itemizedlist>
+	<listitem><para id="x_3f1">This should already be obvious, but
+	    <command>patch</command> cannot handle binary
+	    files.</para>
+	</listitem>
+	<listitem><para id="x_3f2">Neither does it care about the executable bit;
+	    it creates new files as readable, but not
+	    executable.</para>
+	</listitem>
+	<listitem><para id="x_3f3"><command>patch</command> treats the removal of
+	    a file as a diff between the file to be removed and the
+	    empty file.  So your idea of <quote>I deleted this
+	      file</quote> looks like <quote>every line of this file
+	      was deleted</quote> in a patch.</para>
+	</listitem>
+	<listitem><para id="x_3f4">It treats the addition of a file as a diff
+	    between the empty file and the file to be added.  So in a
+	    patch, your idea of <quote>I added this file</quote> looks
+	    like <quote>every line of this file was
+	      added</quote>.</para>
+	</listitem>
+	<listitem><para id="x_3f5">It treats a renamed file as the removal of the
+	    old name, and the addition of the new name.  This means
+	    that renamed files have a big footprint in patches.  (Note
+	    also that Mercurial does not currently try to infer when
+	    files have been renamed or copied in a patch.)</para>
+	</listitem>
+	<listitem><para id="x_3f6"><command>patch</command> cannot represent
+	    empty files, so you cannot use a patch to represent the
+	    notion <quote>I added this empty file to the
+	      tree</quote>.</para>
+	</listitem></itemizedlist>
+    </sect2>
+    <sect2>
+      <title>Beware the fuzz</title>
+
+      <para id="x_3f7">While applying a hunk at an offset, or with a fuzz factor,
+	will often be completely successful, these inexact techniques
+	naturally leave open the possibility of corrupting the patched
+	file.  The most common cases typically involve applying a
+	patch twice, or at an incorrect location in the file.  If
+	<command>patch</command> or <command
+	  role="hg-ext-mq">qpush</command> ever mentions an offset or
+	fuzz factor, you should make sure that the modified files are
+	correct afterwards.</para>
+
+      <para id="x_3f8">It's often a good idea to refresh a patch that has applied
+	with an offset or fuzz factor; refreshing the patch generates
+	new context information that will make it apply cleanly.  I
+	say <quote>often,</quote> not <quote>always,</quote> because
+	sometimes refreshing a patch will make it fail to apply
+	against a different revision of the underlying files.  In some
+	cases, such as when you're maintaining a patch that must sit
+	on top of multiple versions of a source tree, it's acceptable
+	to have a patch apply with some fuzz, provided you've verified
+	the results of the patching process in such cases.</para>
+
+    </sect2>
+    <sect2>
+      <title>Handling rejection</title>
+
+      <para id="x_3f9">If <command role="hg-ext-mq">qpush</command> fails to
+	apply a patch, it will print an error message and exit.  If it
+	has left <filename role="special">.rej</filename> files
+	behind, it is usually best to fix up the rejected hunks before
+	you push more patches or do any further work.</para>
+
+      <para id="x_3fa">If your patch <emphasis>used to</emphasis> apply cleanly,
+	and no longer does because you've changed the underlying code
+	that your patches are based on, Mercurial Queues can help; see
+	<xref linkend="sec:mq:merge"/> for details.</para>
+
+      <para id="x_3fb">Unfortunately, there aren't any great techniques for
+	dealing with rejected hunks.  Most often, you'll need to view
+	the <filename role="special">.rej</filename> file and edit the
+	target file, applying the rejected hunks by hand.</para>
+
+      <para id="x_3fc">If you're feeling adventurous, Neil Brown, a Linux kernel
+	hacker, wrote a tool called <command>wiggle</command>
+	<citation>web:wiggle</citation>, which is more vigorous than
+	<command>patch</command> in its attempts to make a patch
+	apply.</para>
+
+      <para id="x_3fd">Another Linux kernel hacker, Chris Mason (the author of
+	Mercurial Queues), wrote a similar tool called
+	<command>mpatch</command> <citation>web:mpatch</citation>,
+	which takes a simple approach to automating the application of
+	hunks rejected by <command>patch</command>.  The
+	<command>mpatch</command> command can help with four common
+	reasons that a hunk may be rejected:</para>
+
+      <itemizedlist>
+	<listitem><para id="x_3fe">The context in the middle of a hunk has
+	    changed.</para>
+	</listitem>
+	<listitem><para id="x_3ff">A hunk is missing some context at the
+	    beginning or end.</para>
+	</listitem>
+	<listitem><para id="x_400">A large hunk might apply better&emdash;either
+	    entirely or in part&emdash;if it was broken up into
+	    smaller hunks.</para>
+	</listitem>
+	<listitem><para id="x_401">A hunk removes lines with slightly different
+	    content than those currently present in the file.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_402">If you use <command>wiggle</command> or
+	<command>mpatch</command>, you should be doubly careful to
+	check your results when you're done.  In fact,
+	<command>mpatch</command> enforces this method of
+	double-checking the tool's output, by automatically dropping
+	you into a merge program when it has done its job, so that you
+	can verify its work and finish off any remaining
+	merges.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:mq:perf">
+    <title>Getting the best performance out of MQ</title>
+
+    <para id="x_403">MQ is very efficient at handling a large number of patches.
+      I ran some performance experiments in mid-2006 for a talk that I
+      gave at the 2006 EuroPython conference
+      <citation>web:europython</citation>.  I used as my data set the
+      Linux 2.6.17-mm1 patch series, which consists of 1,738 patches.
+      I applied these on top of a Linux kernel repository containing
+      all 27,472 revisions between Linux 2.6.12-rc2 and Linux
+      2.6.17.</para>
+
+    <para id="x_404">On my old, slow laptop, I was able to <command
+	role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
+      1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
+	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
+      them all in 30 seconds.  (On a newer laptop, the time to push
+      all patches dropped to two minutes.)  I could <command
+	role="hg-ext-mq">qrefresh</command> one of the biggest patches
+      (which made 22,779 lines of changes to 287 files) in 6.6
+      seconds.</para>
+
+    <para id="x_405">Clearly, MQ is well suited to working in large trees, but
+      there are a few tricks you can use to get the best performance
+      of it.</para>
+
+    <para id="x_406">First of all, try to <quote>batch</quote> operations
+      together.  Every time you run <command
+	role="hg-ext-mq">qpush</command> or <command
+	role="hg-ext-mq">qpop</command>, these commands scan the
+      working directory once to make sure you haven't made some
+      changes and then forgotten to run <command
+	role="hg-ext-mq">qrefresh</command>.  On a small tree, the
+      time that this scan takes is unnoticeable.  However, on a
+      medium-sized tree (containing tens of thousands of files), it
+      can take a second or more.</para>
+
+    <para id="x_407">The <command role="hg-ext-mq">qpush</command> and <command
+	role="hg-ext-mq">qpop</command> commands allow you to push and
+      pop multiple patches at a time.  You can identify the
+      <quote>destination patch</quote> that you want to end up at.
+      When you <command role="hg-ext-mq">qpush</command> with a
+      destination specified, it will push patches until that patch is
+      at the top of the applied stack.  When you <command
+	role="hg-ext-mq">qpop</command> to a destination, MQ will pop
+      patches until the destination patch is at the top.</para>
+
+    <para id="x_408">You can identify a destination patch using either the name
+      of the patch, or by number.  If you use numeric addressing,
+      patches are counted from zero; this means that the first patch
+      is zero, the second is one, and so on.</para>
+
+  </sect1>
+  <sect1 id="sec:mq:merge">
+    <title>Updating your patches when the underlying code
+      changes</title>
+
+    <para id="x_409">It's common to have a stack of patches on top of an
+      underlying repository that you don't modify directly.  If you're
+      working on changes to third-party code, or on a feature that is
+      taking longer to develop than the rate of change of the code
+      beneath, you will often need to sync up with the underlying
+      code, and fix up any hunks in your patches that no longer apply.
+      This is called <emphasis>rebasing</emphasis> your patch
+      series.</para>
+
+    <para id="x_40a">The simplest way to do this is to <command role="hg-cmd">hg
+	qpop <option role="hg-ext-mq-cmd-qpop-opt">hg
+	  -a</option></command> your patches, then <command
+	role="hg-cmd">hg pull</command> changes into the underlying
+      repository, and finally <command role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
+      patches again.  MQ will stop pushing any time it runs across a
+      patch that fails to apply during conflicts, allowing you to fix
+      your conflicts, <command role="hg-ext-mq">qrefresh</command> the
+      affected patch, and continue pushing until you have fixed your
+      entire stack.</para>
+
+    <para id="x_40b">This approach is easy to use and works well if you don't
+      expect changes to the underlying code to affect how well your
+      patches apply. If your patch stack touches code that is modified
+      frequently or invasively in the underlying repository, however,
+      fixing up rejected hunks by hand quickly becomes
+      tiresome.</para>
+
+    <para id="x_40c">It's possible to partially automate the rebasing process.
+      If your patches apply cleanly against some revision of the
+      underlying repo, MQ can use this information to help you to
+      resolve conflicts between your patches and a different
+      revision.</para>
+
+    <para id="x_40d">The process is a little involved.</para>
+    <orderedlist>
+      <listitem><para id="x_40e">To begin, <command role="hg-cmd">hg qpush
+	    -a</command> all of your patches on top of the revision
+	  where you know that they apply cleanly.</para>
+      </listitem>
+      <listitem><para id="x_40f">Save a backup copy of your patch directory using
+	  <command role="hg-cmd">hg qsave <option
+	      role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option
+	      role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>.
+	  This prints the name of the directory that it has saved the
+	  patches in.  It will save the patches to a directory called
+	  <filename role="special"
+	    class="directory">.hg/patches.N</filename>, where
+	  <literal>N</literal> is a small integer.  It also commits a
+	  <quote>save changeset</quote> on top of your applied
+	  patches; this is for internal book-keeping, and records the
+	  states of the <filename role="special">series</filename> and
+	  <filename role="special">status</filename> files.</para>
+      </listitem>
+      <listitem><para id="x_410">Use <command role="hg-cmd">hg pull</command> to
+	  bring new changes into the underlying repository.  (Don't
+	  run <command role="hg-cmd">hg pull -u</command>; see below
+	  for why.)</para>
+      </listitem>
+      <listitem><para id="x_411">Update to the new tip revision, using <command
+	    role="hg-cmd">hg update <option
+	      role="hg-opt-update">-C</option></command> to override
+	  the patches you have pushed.</para>
+      </listitem>
+      <listitem><para id="x_412">Merge all patches using <command>hg qpush -m
+	    -a</command>.  The <option
+	    role="hg-ext-mq-cmd-qpush-opt">-m</option> option to
+	  <command role="hg-ext-mq">qpush</command> tells MQ to
+	  perform a three-way merge if the patch fails to
+	  apply.</para>
+      </listitem></orderedlist>
+
+    <para id="x_413">During the <command role="hg-cmd">hg qpush <option
+	  role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>,
+      each patch in the <filename role="special">series</filename>
+      file is applied normally.  If a patch applies with fuzz or
+      rejects, MQ looks at the queue you <command
+	role="hg-ext-mq">qsave</command>d, and performs a three-way
+      merge with the corresponding changeset.  This merge uses
+      Mercurial's normal merge machinery, so it may pop up a GUI merge
+      tool to help you to resolve problems.</para>
+
+    <para id="x_414">When you finish resolving the effects of a patch, MQ
+      refreshes your patch based on the result of the merge.</para>
+
+    <para id="x_415">At the end of this process, your repository will have one
+      extra head from the old patch queue, and a copy of the old patch
+      queue will be in <filename role="special"
+	class="directory">.hg/patches.N</filename>. You can remove the
+      extra head using <command role="hg-cmd">hg qpop -a -n
+	patches.N</command> or <command role="hg-cmd">hg
+	strip</command>.  You can delete <filename role="special"
+	class="directory">.hg/patches.N</filename> once you are sure
+      that you no longer need it as a backup.</para>
+
+  </sect1>
+  <sect1>
+    <title>Identifying patches</title>
+
+    <para id="x_416">MQ commands that work with patches let you refer to a patch
+      either by using its name or by a number.  By name is obvious
+      enough; pass the name <filename>foo.patch</filename> to <command
+	role="hg-ext-mq">qpush</command>, for example, and it will
+      push patches until <filename>foo.patch</filename> is
+      applied.</para>
+
+    <para id="x_417">As a shortcut, you can refer to a patch using both a name
+      and a numeric offset; <literal>foo.patch-2</literal> means
+      <quote>two patches before <literal>foo.patch</literal></quote>,
+      while <literal>bar.patch+4</literal> means <quote>four patches
+	after <literal>bar.patch</literal></quote>.</para>
+
+    <para id="x_418">Referring to a patch by index isn't much different.  The
+      first patch printed in the output of <command
+	role="hg-ext-mq">qseries</command> is patch zero (yes, it's
+      one of those start-at-zero counting systems); the second is
+      patch one; and so on.</para>
+
+    <para id="x_419">MQ also makes it easy to work with patches when you are
+      using normal Mercurial commands.  Every command that accepts a
+      changeset ID will also accept the name of an applied patch.  MQ
+      augments the tags normally in the repository with an eponymous
+      one for each applied patch.  In addition, the special tags
+      <literal role="tag">qbase</literal> and
+      <literal role="tag">qtip</literal> identify
+      the <quote>bottom-most</quote> and topmost applied patches,
+      respectively.</para>
+
+    <para id="x_41a">These additions to Mercurial's normal tagging capabilities
+      make dealing with patches even more of a breeze.</para>
+    <itemizedlist>
+      <listitem><para id="x_41b">Want to patchbomb a mailing list with your
+	  latest series of changes?</para>
+	<programlisting>hg email qbase:qtip</programlisting>
+	<para id="x_41c">  (Don't know what <quote>patchbombing</quote> is?  See
+	  <xref linkend="sec:hgext:patchbomb"/>.)</para>
+      </listitem>
+      <listitem><para id="x_41d">Need to see all of the patches since
+	  <literal>foo.patch</literal> that have touched files in a
+	  subdirectory of your tree?</para>
+	<programlisting>hg log -r foo.patch:qtip subdir</programlisting>
+      </listitem>
+    </itemizedlist>
+
+    <para id="x_41e">Because MQ makes the names of patches available to the rest
+      of Mercurial through its normal internal tag machinery, you
+      don't need to type in the entire name of a patch when you want
+      to identify it by name.</para>
+
+    <para id="x_41f">Another nice consequence of representing patch names as tags
+      is that when you run the <command role="hg-cmd">hg log</command>
+      command, it will display a patch's name as a tag, simply as part
+      of its normal output.  This makes it easy to visually
+      distinguish applied patches from underlying
+      <quote>normal</quote> revisions.  The following example shows a
+      few normal Mercurial commands in use with applied
+      patches.</para>
+
+&interaction.mq.id.output;
+
+  </sect1>
+  <sect1>
+    <title>Useful things to know about</title>
+
+    <para id="x_420">There are a number of aspects of MQ usage that don't fit
+      tidily into sections of their own, but that are good to know.
+      Here they are, in one place.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_421">Normally, when you <command
+	    role="hg-ext-mq">qpop</command> a patch and <command
+	    role="hg-ext-mq">qpush</command> it again, the changeset
+	  that represents the patch after the pop/push will have a
+	  <emphasis>different identity</emphasis> than the changeset
+	  that represented the hash beforehand.  See <xref
+	    linkend="sec:mqref:cmd:qpush"/> for
+	  information as to why this is.</para>
+      </listitem>
+      <listitem><para id="x_422">It's not a good idea to <command
+	    role="hg-cmd">hg merge</command> changes from another
+	  branch with a patch changeset, at least if you want to
+	  maintain the <quote>patchiness</quote> of that changeset and
+	  changesets below it on the patch stack.  If you try to do
+	  this, it will appear to succeed, but MQ will become
+	  confused.</para>
+      </listitem></itemizedlist>
+
+  </sect1>
+  <sect1 id="sec:mq:repo">
+    <title>Managing patches in a repository</title>
+
+    <para id="x_423">Because MQ's <filename role="special"
+	class="directory">.hg/patches</filename> directory resides
+      outside a Mercurial repository's working directory, the
+      <quote>underlying</quote> Mercurial repository knows nothing
+      about the management or presence of patches.</para>
+
+    <para id="x_424">This presents the interesting possibility of managing the
+      contents of the patch directory as a Mercurial repository in its
+      own right.  This can be a useful way to work.  For example, you
+      can work on a patch for a while, <command
+	role="hg-ext-mq">qrefresh</command> it, then <command
+	role="hg-cmd">hg commit</command> the current state of the
+      patch.  This lets you <quote>roll back</quote> to that version
+      of the patch later on.</para>
+
+    <para id="x_425">You can then share different versions of the same patch
+      stack among multiple underlying repositories.  I use this when I
+      am developing a Linux kernel feature.  I have a pristine copy of
+      my kernel sources for each of several CPU architectures, and a
+      cloned repository under each that contains the patches I am
+      working on.  When I want to test a change on a different
+      architecture, I push my current patches to the patch repository
+      associated with that kernel tree, pop and push all of my
+      patches, and build and test that kernel.</para>
+
+    <para id="x_426">Managing patches in a repository makes it possible for
+      multiple developers to work on the same patch series without
+      colliding with each other, all on top of an underlying source
+      base that they may or may not control.</para>
+
+    <sect2>
+      <title>MQ support for patch repositories</title>
+
+      <para id="x_427">MQ helps you to work with the <filename role="special"
+	  class="directory">.hg/patches</filename> directory as a
+	repository; when you prepare a repository for working with
+	patches using <command role="hg-ext-mq">qinit</command>, you
+	can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg
+	  -c</option> option to create the <filename role="special"
+	  class="directory">.hg/patches</filename> directory as a
+	Mercurial repository.</para>
+
+      <note>
+	<para id="x_428">  If you forget to use the <option
+	    role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you
+	  can simply go into the <filename role="special"
+	    class="directory">.hg/patches</filename> directory at any
+	  time and run <command role="hg-cmd">hg init</command>.
+	  Don't forget to add an entry for the <filename
+	    role="special">status</filename> file to the <filename
+	    role="special">.hgignore</filename> file, though</para>
+
+	<para id="x_429">  (<command role="hg-cmd">hg qinit <option
+	      role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command>
+	  does this for you automatically); you
+	  <emphasis>really</emphasis> don't want to manage the
+	  <filename role="special">status</filename> file.</para>
+      </note>
+
+      <para id="x_42a">As a convenience, if MQ notices that the <filename
+	  class="directory">.hg/patches</filename> directory is a
+	repository, it will automatically <command role="hg-cmd">hg
+	  add</command> every patch that you create and import.</para>
+
+      <para id="x_42b">MQ provides a shortcut command, <command
+	  role="hg-ext-mq">qcommit</command>, that runs <command
+	  role="hg-cmd">hg commit</command> in the <filename
+	  role="special" class="directory">.hg/patches</filename>
+	directory.  This saves some bothersome typing.</para>
+
+      <para id="x_42c">Finally, as a convenience to manage the patch directory,
+	you can define the alias <command>mq</command> on Unix
+	systems. For example, on Linux systems using the
+	<command>bash</command> shell, you can include the following
+	snippet in your <filename
+	  role="home">~/.bashrc</filename>.</para>
+
+      <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting>
+
+      <para id="x_42d">You can then issue commands of the form <command>mq
+	  pull</command> from the main repository.</para>
+
+    </sect2>
+    <sect2>
+      <title>A few things to watch out for</title>
+
+      <para id="x_42e">MQ's support for working with a repository full of patches
+	is limited in a few small respects.</para>
+
+      <para id="x_42f">MQ cannot automatically detect changes that you make to
+	the patch directory.  If you <command role="hg-cmd">hg
+	  pull</command>, manually edit, or <command role="hg-cmd">hg
+	  update</command> changes to patches or the <filename
+	  role="special">series</filename> file, you will have to
+	<command role="hg-cmd">hg qpop <option
+	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
+	then <command role="hg-cmd">hg qpush <option
+	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
+	the underlying repository to see those changes show up there.
+	If you forget to do this, you can confuse MQ's idea of which
+	patches are applied.</para>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:mq:tools">
+    <title>Third party tools for working with patches</title>
+
+    <para id="x_430">Once you've been working with patches for a while, you'll
+      find yourself hungry for tools that will help you to understand
+      and manipulate the patches you're dealing with.</para>
+
+    <para id="x_431">The <command>diffstat</command> command
+      <citation>web:diffstat</citation> generates a histogram of the
+      modifications made to each file in a patch.  It provides a good
+      way to <quote>get a sense of</quote> a patch&emdash;which files
+      it affects, and how much change it introduces to each file and
+      as a whole.  (I find that it's a good idea to use
+      <command>diffstat</command>'s <option
+	role="cmd-opt-diffstat">-p</option> option as a matter of
+      course, as otherwise it will try to do clever things with
+      prefixes of file names that inevitably confuse at least
+      me.)</para>
+
+&interaction.mq.tools.tools;
+
+    <para id="x_432">The <literal role="package">patchutils</literal> package
+      <citation>web:patchutils</citation> is invaluable. It provides a
+      set of small utilities that follow the <quote>Unix
+	philosophy;</quote> each does one useful thing with a patch.
+      The <literal role="package">patchutils</literal> command I use
+      most is <command>filterdiff</command>, which extracts subsets
+      from a patch file.  For example, given a patch that modifies
+      hundreds of files across dozens of directories, a single
+      invocation of <command>filterdiff</command> can generate a
+      smaller patch that only touches files whose names match a
+      particular glob pattern.  See <xref
+	linkend="mq-collab:tips:interdiff"/> for another
+      example.</para>
+
+  </sect1>
+  <sect1>
+    <title>Good ways to work with patches</title>
+
+    <para id="x_433">Whether you are working on a patch series to submit to a
+      free software or open source project, or a series that you
+      intend to treat as a sequence of regular changesets when you're
+      done, you can use some simple techniques to keep your work well
+      organized.</para>
+
+    <para id="x_434">Give your patches descriptive names.  A good name for a
+      patch might be <filename>rework-device-alloc.patch</filename>,
+      because it will immediately give you a hint what the purpose of
+      the patch is.  Long names shouldn't be a problem; you won't be
+      typing the names often, but you <emphasis>will</emphasis> be
+      running commands like <command
+	role="hg-ext-mq">qapplied</command> and <command
+	role="hg-ext-mq">qtop</command> over and over. Good naming
+      becomes especially important when you have a number of patches
+      to work with, or if you are juggling a number of different tasks
+      and your patches only get a fraction of your attention.</para>
+
+    <para id="x_435">Be aware of what patch you're working on.  Use the <command
+	role="hg-ext-mq">qtop</command> command and skim over the text
+      of your patches frequently&emdash;for example, using <command
+	role="hg-cmd">hg tip <option
+	  role="hg-opt-tip">-p</option></command>)&emdash;to be sure
+      of where you stand.  I have several times worked on and <command
+	role="hg-ext-mq">qrefresh</command>ed a patch other than the
+      one I intended, and it's often tricky to migrate changes into
+      the right patch after making them in the wrong one.</para>
+
+    <para id="x_436">For this reason, it is very much worth investing a little
+      time to learn how to use some of the third-party tools I
+      described in <xref linkend="sec:mq:tools"/>,
+      particularly
+      <command>diffstat</command> and <command>filterdiff</command>.
+      The former will give you a quick idea of what changes your patch
+      is making, while the latter makes it easy to splice hunks
+      selectively out of one patch and into another.</para>
+
+  </sect1>
+  <sect1>
+    <title>MQ cookbook</title>
+
+    <sect2>
+      <title>Manage <quote>trivial</quote> patches</title>
+
+      <para id="x_437">Because the overhead of dropping files into a new
+	Mercurial repository is so low, it makes a lot of sense to
+	manage patches this way even if you simply want to make a few
+	changes to a source tarball that you downloaded.</para>
+
+      <para id="x_438">Begin by downloading and unpacking the source tarball, and
+	turning it into a Mercurial repository.</para>
+
+      &interaction.mq.tarball.download;
+
+      <para id="x_439">Continue by creating a patch stack and making your
+	changes.</para>
+
+      &interaction.mq.tarball.qinit;
+
+      <para id="x_43a">Let's say a few weeks or months pass, and your package
+	author releases a new version.  First, bring their changes
+	into the repository.</para>
+
+      &interaction.mq.tarball.newsource;
+
+      <para id="x_43b">The pipeline starting with <command role="hg-cmd">hg
+	  locate</command> above deletes all files in the working
+	directory, so that <command role="hg-cmd">hg
+	  commit</command>'s <option
+	  role="hg-opt-commit">--addremove</option> option can
+	actually tell which files have really been removed in the
+	newer version of the source.</para>
+
+      <para id="x_43c">Finally, you can apply your patches on top of the new
+	tree.</para>
+
+      &interaction.mq.tarball.repush;
+
+    </sect2>
+    <sect2 id="sec:mq:combine">
+      <title>Combining entire patches</title>
+
+      <para id="x_43d">MQ provides a command, <command
+	  role="hg-ext-mq">qfold</command> that lets you combine
+	entire patches.  This <quote>folds</quote> the patches you
+	name, in the order you name them, into the topmost applied
+	patch, and concatenates their descriptions onto the end of its
+	description.  The patches that you fold must be unapplied
+	before you fold them.</para>
+
+      <para id="x_43e">The order in which you fold patches matters.  If your
+	topmost applied patch is <literal>foo</literal>, and you
+	<command role="hg-ext-mq">qfold</command>
+	<literal>bar</literal> and <literal>quux</literal> into it,
+	you will end up with a patch that has the same effect as if
+	you applied first <literal>foo</literal>, then
+	<literal>bar</literal>, followed by
+	<literal>quux</literal>.</para>
+
+    </sect2>
+    <sect2>
+      <title>Merging part of one patch into another</title>
+
+      <para id="x_43f">Merging <emphasis>part</emphasis> of one patch into
+	another is more difficult than combining entire
+	patches.</para>
+
+      <para id="x_440">If you want to move changes to entire files, you can use
+	<command>filterdiff</command>'s <option
+	  role="cmd-opt-filterdiff">-i</option> and <option
+	  role="cmd-opt-filterdiff">-x</option> options to choose the
+	modifications to snip out of one patch, concatenating its
+	output onto the end of the patch you want to merge into.  You
+	usually won't need to modify the patch you've merged the
+	changes from.  Instead, MQ will report some rejected hunks
+	when you <command role="hg-ext-mq">qpush</command> it (from
+	the hunks you moved into the other patch), and you can simply
+	<command role="hg-ext-mq">qrefresh</command> the patch to drop
+	the duplicate hunks.</para>
+
+      <para id="x_441">If you have a patch that has multiple hunks modifying a
+	file, and you only want to move a few of those hunks, the job
+	becomes more messy, but you can still partly automate it.  Use
+	<command>lsdiff -nvv</command> to print some metadata about
+	the patch.</para>
+
+      &interaction.mq.tools.lsdiff;
+
+      <para id="x_442">This command prints three different kinds of
+	number:</para>
+      <itemizedlist>
+	<listitem><para id="x_443">(in the first column) a <emphasis>file
+	      number</emphasis> to identify each file modified in the
+	    patch;</para>
+	</listitem>
+	<listitem><para id="x_444">(on the next line, indented) the line number
+	    within a modified file where a hunk starts; and</para>
+	</listitem>
+	<listitem><para id="x_445">(on the same line) a <emphasis>hunk
+	      number</emphasis> to identify that hunk.</para>
+	</listitem></itemizedlist>
+
+      <para id="x_446">You'll have to use some visual inspection, and reading of
+	the patch, to identify the file and hunk numbers you'll want,
+	but you can then pass them to to
+	<command>filterdiff</command>'s <option
+	  role="cmd-opt-filterdiff">--files</option> and <option
+	  role="cmd-opt-filterdiff">--hunks</option> options, to
+	select exactly the file and hunk you want to extract.</para>
+
+      <para id="x_447">Once you have this hunk, you can concatenate it onto the
+	end of your destination patch and continue with the remainder
+	of <xref linkend="sec:mq:combine"/>.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Differences between quilt and MQ</title>
+
+    <para id="x_448">If you are already familiar with quilt, MQ provides a
+      similar command set.  There are a few differences in the way
+      that it works.</para>
+
+    <para id="x_449">You will already have noticed that most quilt commands have
+      MQ counterparts that simply begin with a
+      <quote><literal>q</literal></quote>.  The exceptions are quilt's
+      <literal>add</literal> and <literal>remove</literal> commands,
+      the counterparts for which are the normal Mercurial <command
+	role="hg-cmd">hg add</command> and <command role="hg-cmd">hg
+	remove</command> commands.  There is no MQ equivalent of the
+      quilt <literal>edit</literal> command.</para>
+
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch12-mq-collab.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,518 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:mq-collab">
+  <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?>
+  <title>Advanced uses of Mercurial Queues</title>
+
+  <para id="x_15d">While it's easy to pick up straightforward uses of Mercurial
+    Queues, use of a little discipline and some of MQ's less
+    frequently used capabilities makes it possible to work in
+    complicated development environments.</para>
+
+  <para id="x_15e">In this chapter, I will use as an example a technique I have
+    used to manage the development of an Infiniband device driver for
+    the Linux kernel.  The driver in question is large (at least as
+    drivers go), with 25,000 lines of code spread across 35 source
+    files.  It is maintained by a small team of developers.</para>
+
+  <para id="x_15f">While much of the material in this chapter is specific to
+    Linux, the same principles apply to any code base for which you're
+    not the primary owner, and upon which you need to do a lot of
+    development.</para>
+
+  <sect1>
+    <title>The problem of many targets</title>
+
+    <para id="x_160">The Linux kernel changes rapidly, and has never been
+      internally stable; developers frequently make drastic changes
+      between releases. This means that a version of the driver that
+      works well with a particular released version of the kernel will
+      not even <emphasis>compile</emphasis> correctly against,
+      typically, any other version.</para>
+
+    <para id="x_161">To maintain a driver, we have to keep a number of distinct
+      versions of Linux in mind.</para>
+    <itemizedlist>
+      <listitem><para id="x_162">One target is the main Linux kernel development
+	  tree. Maintenance of the code is in this case partly shared
+	  by other developers in the kernel community, who make
+	  <quote>drive-by</quote> modifications to the driver as they
+	  develop and refine kernel subsystems.</para>
+      </listitem>
+      <listitem><para id="x_163">We also maintain a number of
+	  <quote>backports</quote> to older versions of the Linux
+	  kernel, to support the needs of customers who are running
+	  older Linux distributions that do not incorporate our
+	  drivers.  (To <emphasis>backport</emphasis> a piece of code
+	  is to modify it to work in an older version of its target
+	  environment than the version it was developed for.)</para>
+      </listitem>
+      <listitem><para id="x_164">Finally, we make software releases on a schedule
+	  that is necessarily not aligned with those used by Linux
+	  distributors and kernel developers, so that we can deliver
+	  new features to customers without forcing them to upgrade
+	  their entire kernels or distributions.</para>
+      </listitem></itemizedlist>
+
+    <sect2>
+      <title>Tempting approaches that don't work well</title>
+
+      <para id="x_165">There are two <quote>standard</quote> ways to maintain a
+	piece of software that has to target many different
+	environments.</para>
+
+      <para id="x_166">The first is to maintain a number of branches, each
+	intended for a single target.  The trouble with this approach
+	is that you must maintain iron discipline in the flow of
+	changes between repositories. A new feature or bug fix must
+	start life in a <quote>pristine</quote> repository, then
+	percolate out to every backport repository.  Backport changes
+	are more limited in the branches they should propagate to; a
+	backport change that is applied to a branch where it doesn't
+	belong will probably stop the driver from compiling.</para>
+
+      <para id="x_167">The second is to maintain a single source tree filled with
+	conditional statements that turn chunks of code on or off
+	depending on the intended target.  Because these
+	<quote>ifdefs</quote> are not allowed in the Linux kernel
+	tree, a manual or automatic process must be followed to strip
+	them out and yield a clean tree.  A code base maintained in
+	this fashion rapidly becomes a rat's nest of conditional
+	blocks that are difficult to understand and maintain.</para>
+
+      <para id="x_168">Neither of these approaches is well suited to a situation
+	where you don't <quote>own</quote> the canonical copy of a
+	source tree.  In the case of a Linux driver that is
+	distributed with the standard kernel, Linus's tree contains
+	the copy of the code that will be treated by the world as
+	canonical.  The upstream version of <quote>my</quote> driver
+	can be modified by people I don't know, without me even
+	finding out about it until after the changes show up in
+	Linus's tree.</para>
+
+      <para id="x_169">These approaches have the added weakness of making it
+	difficult to generate well-formed patches to submit
+	upstream.</para>
+
+      <para id="x_16a">In principle, Mercurial Queues seems like a good candidate
+	to manage a development scenario such as the above.  While
+	this is indeed the case, MQ contains a few added features that
+	make the job more pleasant.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Conditionally applying patches with guards</title>
+
+    <para id="x_16b">Perhaps the best way to maintain sanity with so many targets
+      is to be able to choose specific patches to apply for a given
+      situation.  MQ provides a feature called <quote>guards</quote>
+      (which originates with quilt's <literal>guards</literal>
+      command) that does just this.  To start off, let's create a
+      simple repository for experimenting in.</para>
+
+    &interaction.mq.guards.init;
+
+    <para id="x_16c">This gives us a tiny repository that contains two patches
+      that don't have any dependencies on each other, because they
+      touch different files.</para>
+
+    <para id="x_16d">The idea behind conditional application is that you can
+      <quote>tag</quote> a patch with a <emphasis>guard</emphasis>,
+      which is simply a text string of your choosing, then tell MQ to
+      select specific guards to use when applying patches.  MQ will
+      then either apply, or skip over, a guarded patch, depending on
+      the guards that you have selected.</para>
+
+    <para id="x_16e">A patch can have an arbitrary number of guards; each one is
+      <emphasis>positive</emphasis> (<quote>apply this patch if this
+	guard is selected</quote>) or <emphasis>negative</emphasis>
+      (<quote>skip this patch if this guard is selected</quote>).  A
+      patch with no guards is always applied.</para>
+
+  </sect1>
+  <sect1>
+    <title>Controlling the guards on a patch</title>
+
+    <para id="x_16f">The <command role="hg-ext-mq">qguard</command> command lets
+      you determine which guards should apply to a patch, or display
+      the guards that are already in effect. Without any arguments, it
+      displays the guards on the current topmost patch.</para>
+
+      &interaction.mq.guards.qguard;
+
+    <para id="x_170">To set a positive guard on a patch, prefix the name of the
+      guard with a <quote><literal>+</literal></quote>.</para>
+
+      &interaction.mq.guards.qguard.pos;
+
+    <para id="x_171">To set a negative guard
+      on a patch, prefix the name of the guard with a
+      <quote><literal>-</literal></quote>.</para>
+
+    &interaction.mq.guards.qguard.neg;
+
+    <note>
+      <para id="x_172">  The <command role="hg-ext-mq">qguard</command> command
+	<emphasis>sets</emphasis> the guards on a patch; it doesn't
+	<emphasis>modify</emphasis> them.  What this means is that if
+	you run <command role="hg-cmd">hg qguard +a +b</command> on a
+	patch, then <command role="hg-cmd">hg qguard +c</command> on
+	the same patch, the <emphasis>only</emphasis> guard that will
+	be set on it afterwards is <literal>+c</literal>.</para>
+    </note>
+
+    <para id="x_173">Mercurial stores guards in the <filename
+	role="special">series</filename> file; the form in which they
+      are stored is easy both to understand and to edit by hand. (In
+      other words, you don't have to use the <command
+	role="hg-ext-mq">qguard</command> command if you don't want
+      to; it's okay to simply edit the <filename
+	role="special">series</filename> file.)</para>
+
+    &interaction.mq.guards.series;
+
+  </sect1>
+  <sect1>
+    <title>Selecting the guards to use</title>
+
+    <para id="x_174">The <command role="hg-ext-mq">qselect</command> command
+      determines which guards are active at a given time.  The effect
+      of this is to determine which patches MQ will apply the next
+      time you run <command role="hg-ext-mq">qpush</command>.  It has
+      no other effect; in particular, it doesn't do anything to
+      patches that are already applied.</para>
+
+    <para id="x_175">With no arguments, the <command
+	role="hg-ext-mq">qselect</command> command lists the guards
+      currently in effect, one per line of output.  Each argument is
+      treated as the name of a guard to apply.</para>
+
+      &interaction.mq.guards.qselect.foo;
+
+    <para id="x_176">In case you're interested, the currently selected guards are
+      stored in the <filename role="special">guards</filename> file.</para>
+
+    &interaction.mq.guards.qselect.cat;
+
+    <para id="x_177">We can see the effect the selected guards have when we run
+      <command role="hg-ext-mq">qpush</command>.</para>
+
+    &interaction.mq.guards.qselect.qpush;
+
+    <para id="x_178">A guard cannot start with a
+      <quote><literal>+</literal></quote> or
+      <quote><literal>-</literal></quote> character.  The name of a
+      guard must not contain white space, but most other characters
+      are acceptable.  If you try to use a guard with an invalid name,
+      MQ will complain:</para>
+
+    &interaction.mq.guards.qselect.error;
+      
+    <para id="x_179">Changing the selected guards changes the patches that are
+      applied.</para>
+
+    &interaction.mq.guards.qselect.quux;
+
+    <para id="x_17a">You can see in the example below that negative guards take
+      precedence over positive guards.</para>
+
+    &interaction.mq.guards.qselect.foobar;
+
+  </sect1>
+  <sect1>
+    <title>MQ's rules for applying patches</title>
+
+    <para id="x_17b">The rules that MQ uses when deciding whether to apply a
+      patch are as follows.</para>
+    <itemizedlist>
+      <listitem><para id="x_17c">A patch that has no guards is always
+	  applied.</para>
+      </listitem>
+      <listitem><para id="x_17d">If the patch has any negative guard that matches
+	  any currently selected guard, the patch is skipped.</para>
+      </listitem>
+      <listitem><para id="x_17e">If the patch has any positive guard that matches
+	  any currently selected guard, the patch is applied.</para>
+      </listitem>
+      <listitem><para id="x_17f">If the patch has positive or negative guards,
+	  but none matches any currently selected guard, the patch is
+	  skipped.</para>
+      </listitem></itemizedlist>
+
+  </sect1>
+  <sect1>
+    <title>Trimming the work environment</title>
+
+    <para id="x_180">In working on the device driver I mentioned earlier, I don't
+      apply the patches to a normal Linux kernel tree.  Instead, I use
+      a repository that contains only a snapshot of the source files
+      and headers that are relevant to Infiniband development.  This
+      repository is 1% the size of a kernel repository, so it's easier
+      to work with.</para>
+
+    <para id="x_181">I then choose a <quote>base</quote> version on top of which
+      the patches are applied.  This is a snapshot of the Linux kernel
+      tree as of a revision of my choosing.  When I take the snapshot,
+      I record the changeset ID from the kernel repository in the
+      commit message.  Since the snapshot preserves the
+      <quote>shape</quote> and content of the relevant parts of the
+      kernel tree, I can apply my patches on top of either my tiny
+      repository or a normal kernel tree.</para>
+
+    <para id="x_182">Normally, the base tree atop which the patches apply should
+      be a snapshot of a very recent upstream tree.  This best
+      facilitates the development of patches that can easily be
+      submitted upstream with few or no modifications.</para>
+
+  </sect1>
+  <sect1>
+    <title>Dividing up the <filename role="special">series</filename>
+      file</title>
+
+    <para id="x_183">I categorise the patches in the <filename
+	role="special">series</filename> file into a number of logical
+      groups.  Each section of like patches begins with a block of
+      comments that describes the purpose of the patches that
+      follow.</para>
+
+    <para id="x_184">The sequence of patch groups that I maintain follows.  The
+      ordering of these groups is important; I'll describe why after I
+      introduce the groups.</para>
+    <itemizedlist>
+      <listitem><para id="x_185">The <quote>accepted</quote> group.  Patches that
+	  the development team has submitted to the maintainer of the
+	  Infiniband subsystem, and which he has accepted, but which
+	  are not present in the snapshot that the tiny repository is
+	  based on.  These are <quote>read only</quote> patches,
+	  present only to transform the tree into a similar state as
+	  it is in the upstream maintainer's repository.</para>
+      </listitem>
+      <listitem><para id="x_186">The <quote>rework</quote> group.  Patches that I
+	  have submitted, but that the upstream maintainer has
+	  requested modifications to before he will accept
+	  them.</para>
+      </listitem>
+      <listitem><para id="x_187">The <quote>pending</quote> group.  Patches that
+	  I have not yet submitted to the upstream maintainer, but
+	  which we have finished working on. These will be <quote>read
+	    only</quote> for a while.  If the upstream maintainer
+	  accepts them upon submission, I'll move them to the end of
+	  the <quote>accepted</quote> group.  If he requests that I
+	  modify any, I'll move them to the beginning of the
+	  <quote>rework</quote> group.</para>
+      </listitem>
+      <listitem><para id="x_188">The <quote>in progress</quote> group.  Patches
+	  that are actively being developed, and should not be
+	  submitted anywhere yet.</para>
+      </listitem>
+      <listitem><para id="x_189">The <quote>backport</quote> group.  Patches that
+	  adapt the source tree to older versions of the kernel
+	  tree.</para>
+      </listitem>
+      <listitem><para id="x_18a">The <quote>do not ship</quote> group.  Patches
+	  that for some reason should never be submitted upstream.
+	  For example, one such patch might change embedded driver
+	  identification strings to make it easier to distinguish, in
+	  the field, between an out-of-tree version of the driver and
+	  a version shipped by a distribution vendor.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_18b">Now to return to the reasons for ordering groups of patches
+      in this way.  We would like the lowest patches in the stack to
+      be as stable as possible, so that we will not need to rework
+      higher patches due to changes in context.  Putting patches that
+      will never be changed first in the <filename
+	role="special">series</filename> file serves this
+      purpose.</para>
+
+    <para id="x_18c">We would also like the patches that we know we'll need to
+      modify to be applied on top of a source tree that resembles the
+      upstream tree as closely as possible.  This is why we keep
+      accepted patches around for a while.</para>
+
+    <para id="x_18d">The <quote>backport</quote> and <quote>do not ship</quote>
+      patches float at the end of the <filename
+	role="special">series</filename> file.  The backport patches
+      must be applied on top of all other patches, and the <quote>do
+	not ship</quote> patches might as well stay out of harm's
+      way.</para>
+
+  </sect1>
+  <sect1>
+    <title>Maintaining the patch series</title>
+
+    <para id="x_18e">In my work, I use a number of guards to control which
+      patches are to be applied.</para>
+
+    <itemizedlist>
+      <listitem><para id="x_18f"><quote>Accepted</quote> patches are guarded with
+	  <literal>accepted</literal>.  I enable this guard most of
+	  the time.  When I'm applying the patches on top of a tree
+	  where the patches are already present, I can turn this patch
+	  off, and the patches that follow it will apply
+	  cleanly.</para>
+      </listitem>
+      <listitem><para id="x_190">Patches that are <quote>finished</quote>, but
+	  not yet submitted, have no guards.  If I'm applying the
+	  patch stack to a copy of the upstream tree, I don't need to
+	  enable any guards in order to get a reasonably safe source
+	  tree.</para>
+      </listitem>
+      <listitem><para id="x_191">Those patches that need reworking before being
+	  resubmitted are guarded with
+	  <literal>rework</literal>.</para>
+      </listitem>
+      <listitem><para id="x_192">For those patches that are still under
+	  development, I use <literal>devel</literal>.</para>
+      </listitem>
+      <listitem><para id="x_193">A backport patch may have several guards, one
+	  for each version of the kernel to which it applies.  For
+	  example, a patch that backports a piece of code to 2.6.9
+	  will have a <literal>2.6.9</literal> guard.</para>
+      </listitem></itemizedlist>
+    <para id="x_194">This variety of guards gives me considerable flexibility in
+      determining what kind of source tree I want to end up with.  For
+      most situations, the selection of appropriate guards is
+      automated during the build process, but I can manually tune the
+      guards to use for less common circumstances.</para>
+
+    <sect2>
+      <title>The art of writing backport patches</title>
+
+      <para id="x_195">Using MQ, writing a backport patch is a simple process.
+	All such a patch has to do is modify a piece of code that uses
+	a kernel feature not present in the older version of the
+	kernel, so that the driver continues to work correctly under
+	that older version.</para>
+
+      <para id="x_196">A useful goal when writing a good backport patch is to
+	make your code look as if it was written for the older version
+	of the kernel you're targeting.  The less obtrusive the patch,
+	the easier it will be to understand and maintain.  If you're
+	writing a collection of backport patches to avoid the
+	<quote>rat's nest</quote> effect of lots of
+	<literal>#ifdef</literal>s (hunks of source code that are only
+	used conditionally) in your code, don't introduce
+	version-dependent <literal>#ifdef</literal>s into the patches.
+	Instead, write several patches, each of which makes
+	unconditional changes, and control their application using
+	guards.</para>
+
+      <para id="x_197">There are two reasons to divide backport patches into a
+	distinct group, away from the <quote>regular</quote> patches
+	whose effects they modify. The first is that intermingling the
+	two makes it more difficult to use a tool like the <literal
+	  role="hg-ext">patchbomb</literal> extension to automate the
+	process of submitting the patches to an upstream maintainer.
+	The second is that a backport patch could perturb the context
+	in which a subsequent regular patch is applied, making it
+	impossible to apply the regular patch cleanly
+	<emphasis>without</emphasis> the earlier backport patch
+	already being applied.</para>
+
+    </sect2>
+  </sect1>
+  <sect1>
+    <title>Useful tips for developing with MQ</title>
+
+    <sect2>
+      <title>Organising patches in directories</title>
+
+      <para id="x_198">If you're working on a substantial project with MQ, it's
+	not difficult to accumulate a large number of patches.  For
+	example, I have one patch repository that contains over 250
+	patches.</para>
+
+      <para id="x_199">If you can group these patches into separate logical
+	categories, you can if you like store them in different
+	directories; MQ has no problems with patch names that contain
+	path separators.</para>
+
+    </sect2>
+    <sect2 id="mq-collab:tips:interdiff">
+      <title>Viewing the history of a patch</title>
+
+      <para id="x_19a">If you're developing a set of patches over a long time,
+	it's a good idea to maintain them in a repository, as
+	discussed in <xref linkend="sec:mq:repo"/>.  If you do
+	so, you'll quickly
+	discover that using the <command role="hg-cmd">hg
+	  diff</command> command to look at the history of changes to
+	a patch is unworkable.  This is in part because you're looking
+	at the second derivative of the real code (a diff of a diff),
+	but also because MQ adds noise to the process by modifying
+	time stamps and directory names when it updates a
+	patch.</para>
+
+      <para id="x_19b">However, you can use the <literal
+	  role="hg-ext">extdiff</literal> extension, which is bundled
+	with Mercurial, to turn a diff of two versions of a patch into
+	something readable.  To do this, you will need a third-party
+	package called <literal role="package">patchutils</literal>
+	<citation>web:patchutils</citation>.  This provides a command
+	named <command>interdiff</command>, which shows the
+	differences between two diffs as a diff.  Used on two versions
+	of the same diff, it generates a diff that represents the diff
+	from the first to the second version.</para>
+
+      <para id="x_19c">You can enable the <literal
+	  role="hg-ext">extdiff</literal> extension in the usual way,
+	by adding a line to the <literal
+	  role="rc-extensions">extensions</literal> section of your
+	<filename role="special">~/.hgrc</filename>.</para>
+      <programlisting>[extensions]
+extdiff =</programlisting>
+      <para id="x_19d">The <command>interdiff</command> command expects to be
+	passed the names of two files, but the <literal
+	  role="hg-ext">extdiff</literal> extension passes the program
+	it runs a pair of directories, each of which can contain an
+	arbitrary number of files.  We thus need a small program that
+	will run <command>interdiff</command> on each pair of files in
+	these two directories.  This program is available as <filename
+	  role="special">hg-interdiff</filename> in the <filename
+	  class="directory">examples</filename> directory of the
+	source code repository that accompanies this book. <!--
+	&example.hg-interdiff; --></para>
+
+      <para id="x_19e">With the <filename role="special">hg-interdiff</filename>
+	program in your shell's search path, you can run it as
+	follows, from inside an MQ patch directory:</para>
+      <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting>
+      <para id="x_19f">Since you'll probably want to use this long-winded command
+	a lot, you can get <literal role="hg-ext">hgext</literal> to
+	make it available as a normal Mercurial command, again by
+	editing your <filename
+	  role="special">~/.hgrc</filename>.</para>
+      <programlisting>[extdiff]
+cmd.interdiff = hg-interdiff</programlisting>
+      <para id="x_1a0">This directs <literal role="hg-ext">hgext</literal> to
+	make an <literal>interdiff</literal> command available, so you
+	can now shorten the previous invocation of <command
+	  role="hg-ext-extdiff">extdiff</command> to something a
+	little more wieldy.</para>
+      <programlisting>hg interdiff -r A:B my-change.patch</programlisting>
+
+      <note>
+	<para id="x_1a1">  The <command>interdiff</command> command works well
+	  only if the underlying files against which versions of a
+	  patch are generated remain the same.  If you create a patch,
+	  modify the underlying files, and then regenerate the patch,
+	  <command>interdiff</command> may not produce useful
+	  output.</para>
+      </note>
+
+      <para id="x_1a2">The <literal role="hg-ext">extdiff</literal> extension is
+	useful for more than merely improving the presentation of MQ
+	patches.  To read more about it, go to <xref
+	  linkend="sec:hgext:extdiff"/>.</para>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/ch13-hgext.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,554 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+
+<chapter id="chap:hgext">
+  <?dbhtml filename="adding-functionality-with-extensions.html"?>
+  <title>Adding functionality with extensions</title>
+
+  <para id="x_4fe">While the core of Mercurial is quite complete from a
+    functionality standpoint, it's deliberately shorn of fancy
+    features.  This approach of preserving simplicity keeps the
+    software easy to deal with for both maintainers and users.</para>
+
+  <para id="x_4ff">However, Mercurial doesn't box you in with an inflexible
+    command set: you can add features to it as
+    <emphasis>extensions</emphasis> (sometimes known as
+    <emphasis>plugins</emphasis>).  We've already discussed a few of
+    these extensions in earlier chapters.</para>
+  <itemizedlist>
+    <listitem><para id="x_500"><xref linkend="sec:tour-merge:fetch"/>
+	covers the <literal role="hg-ext">fetch</literal> extension;
+	this combines pulling new changes and merging them with local
+	changes into a single command, <command
+	  role="hg-ext-fetch">fetch</command>.</para>
+    </listitem>
+    <listitem><para id="x_501">In <xref linkend="chap:hook"/>, we covered
+	several extensions that are useful for hook-related
+	functionality: <literal role="hg-ext">acl</literal> adds
+	access control lists; <literal
+	  role="hg-ext">bugzilla</literal> adds integration with the
+	Bugzilla bug tracking system; and <literal
+	  role="hg-ext">notify</literal> sends notification emails on
+	new changes.</para>
+    </listitem>
+    <listitem><para id="x_502">The Mercurial Queues patch management extension is
+	so invaluable that it merits two chapters and an appendix all
+	to itself. <xref linkend="chap:mq"/> covers the
+	basics; <xref
+	  linkend="chap:mq-collab"/> discusses advanced topics;
+	and <xref linkend="chap:mqref"/> goes into detail on
+	each
+	command.</para>
+    </listitem></itemizedlist>
+
+  <para id="x_503">In this chapter, we'll cover some of the other extensions that
+    are available for Mercurial, and briefly touch on some of the
+    machinery you'll need to know about if you want to write an
+    extension of your own.</para>
+  <itemizedlist>
+    <listitem><para id="x_504">In <xref linkend="sec:hgext:inotify"/>,
+	we'll discuss the possibility of <emphasis>huge</emphasis>
+	performance improvements using the <literal
+	  role="hg-ext">inotify</literal> extension.</para>
+    </listitem></itemizedlist>
+
+  <sect1 id="sec:hgext:inotify">
+    <title>Improve performance with the <literal
+	role="hg-ext">inotify</literal> extension</title>
+
+    <para id="x_505">Are you interested in having some of the most common
+      Mercurial operations run as much as a hundred times faster?
+      Read on!</para>
+
+    <para id="x_506">Mercurial has great performance under normal circumstances.
+      For example, when you run the <command role="hg-cmd">hg
+	status</command> command, Mercurial has to scan almost every
+      directory and file in your repository so that it can display
+      file status.  Many other Mercurial commands need to do the same
+      work behind the scenes; for example, the <command
+	role="hg-cmd">hg diff</command> command uses the status
+      machinery to avoid doing an expensive comparison operation on
+      files that obviously haven't changed.</para>
+
+    <para id="x_507">Because obtaining file status is crucial to good
+      performance, the authors of Mercurial have optimised this code
+      to within an inch of its life.  However, there's no avoiding the
+      fact that when you run <command role="hg-cmd">hg
+	status</command>, Mercurial is going to have to perform at
+      least one expensive system call for each managed file to
+      determine whether it's changed since the last time Mercurial
+      checked.  For a sufficiently large repository, this can take a
+      long time.</para>
+
+    <para id="x_508">To put a number on the magnitude of this effect, I created a
+      repository containing 150,000 managed files.  I timed <command
+	role="hg-cmd">hg status</command> as taking ten seconds to
+      run, even when <emphasis>none</emphasis> of those files had been
+      modified.</para>
+
+    <para id="x_509">Many modern operating systems contain a file notification
+      facility. If a program signs up to an appropriate service, the
+      operating system will notify it every time a file of interest is
+      created, modified, or deleted.  On Linux systems, the kernel
+      component that does this is called
+      <literal>inotify</literal>.</para>
+
+    <para id="x_50a">Mercurial's <literal role="hg-ext">inotify</literal>
+      extension talks to the kernel's <literal>inotify</literal>
+      component to optimise <command role="hg-cmd">hg status</command>
+      commands.  The extension has two components.  A daemon sits in
+      the background and receives notifications from the
+      <literal>inotify</literal> subsystem.  It also listens for
+      connections from a regular Mercurial command.  The extension
+      modifies Mercurial's behavior so that instead of scanning the
+      filesystem, it queries the daemon.  Since the daemon has perfect
+      information about the state of the repository, it can respond
+      with a result instantaneously, avoiding the need to scan every
+      directory and file in the repository.</para>
+
+    <para id="x_50b">Recall the ten seconds that I measured plain Mercurial as
+      taking to run <command role="hg-cmd">hg status</command> on a
+      150,000 file repository.  With the <literal
+	role="hg-ext">inotify</literal> extension enabled, the time
+      dropped to 0.1 seconds, a factor of <emphasis>one
+	hundred</emphasis> faster.</para>
+
+    <para id="x_50c">Before we continue, please pay attention to some
+      caveats.</para>
+    <itemizedlist>
+      <listitem><para id="x_50d">The <literal role="hg-ext">inotify</literal>
+	  extension is Linux-specific.  Because it interfaces directly
+	  to the Linux kernel's <literal>inotify</literal> subsystem,
+	  it does not work on other operating systems.</para>
+      </listitem>
+      <listitem><para id="x_50e">It should work on any Linux distribution that
+	  was released after early 2005.  Older distributions are
+	  likely to have a kernel that lacks
+	  <literal>inotify</literal>, or a version of
+	  <literal>glibc</literal> that does not have the necessary
+	  interfacing support.</para>
+      </listitem>
+      <listitem><para id="x_50f">Not all filesystems are suitable for use with
+	  the <literal role="hg-ext">inotify</literal> extension.
+	  Network filesystems such as NFS are a non-starter, for
+	  example, particularly if you're running Mercurial on several
+	  systems, all mounting the same network filesystem.  The
+	  kernel's <literal>inotify</literal> system has no way of
+	  knowing about changes made on another system.  Most local
+	  filesystems (e.g. ext3, XFS, ReiserFS) should work
+	  fine.</para>
+      </listitem></itemizedlist>
+
+    <para id="x_510">The <literal role="hg-ext">inotify</literal> extension is
+      not yet shipped with Mercurial as of May 2007, so it's a little
+      more involved to set up than other extensions.  But the
+      performance improvement is worth it!</para>
+
+    <para id="x_511">The extension currently comes in two parts: a set of patches
+      to the Mercurial source code, and a library of Python bindings
+      to the <literal>inotify</literal> subsystem.</para>
+    <note>
+      <para id="x_512">  There are <emphasis>two</emphasis> Python
+	<literal>inotify</literal> binding libraries.  One of them is
+	called <literal>pyinotify</literal>, and is packaged by some
+	Linux distributions as <literal>python-inotify</literal>.
+	This is <emphasis>not</emphasis> the one you'll need, as it is
+	too buggy and inefficient to be practical.</para>
+    </note>
+    <para id="x_513">To get going, it's best to already have a functioning copy
+      of Mercurial installed.</para>
+    <note>
+      <para id="x_514">  If you follow the instructions below, you'll be
+	<emphasis>replacing</emphasis> and overwriting any existing
+	installation of Mercurial that you might already have, using
+	the latest <quote>bleeding edge</quote> Mercurial code. Don't
+	say you weren't warned!</para>
+    </note>
+    <orderedlist>
+      <listitem><para id="x_515">Clone the Python <literal>inotify</literal>
+	  binding repository.  Build and install it.</para>
+	<programlisting>hg clone http://hg.kublai.com/python/inotify
+cd inotify
+python setup.py build --force
+sudo python setup.py install --skip-build</programlisting>
+      </listitem>
+      <listitem><para id="x_516">Clone the <filename
+	    class="directory">crew</filename> Mercurial repository.
+	  Clone the <literal role="hg-ext">inotify</literal> patch
+	  repository so that Mercurial Queues will be able to apply
+	  patches to your cope of the <filename
+	    class="directory">crew</filename> repository.</para>
+	<programlisting>hg clone http://hg.intevation.org/mercurial/crew
+hg clone crew inotify
+hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting>
+      </listitem>
+      <listitem><para id="x_517">Make sure that you have the Mercurial Queues
+	  extension, <literal role="hg-ext">mq</literal>, enabled.  If
+	  you've never used MQ, read <xref
+	    linkend="sec:mq:start"/> to get started
+	  quickly.</para>
+      </listitem>
+      <listitem><para id="x_518">Go into the <filename
+	    class="directory">inotify</filename> repo, and apply all
+	  of the <literal role="hg-ext">inotify</literal> patches
+	  using the <option role="hg-ext-mq-cmd-qpush-opt">hg
+	    -a</option> option to the <command
+	    role="hg-ext-mq">qpush</command> command.</para>
+	<programlisting>cd inotify
+hg qpush -a</programlisting>
+      </listitem>
+      <listitem><para id="x_519">  If you get an error message from <command
+	    role="hg-ext-mq">qpush</command>, you should not continue.
+	  Instead, ask for help.</para>
+      </listitem>
+      <listitem><para id="x_51a">Build and install the patched version of
+	  Mercurial.</para>
+	<programlisting>python setup.py build --force
+sudo python setup.py install --skip-build</programlisting>
+      </listitem>
+    </orderedlist>
+    <para id="x_51b">Once you've build a suitably patched version of Mercurial,
+      all you need to do to enable the <literal
+	role="hg-ext">inotify</literal> extension is add an entry to
+      your <filename role="special">~/.hgrc</filename>.</para>
+    <programlisting>[extensions] inotify =</programlisting>
+    <para id="x_51c">When the <literal role="hg-ext">inotify</literal> extension
+      is enabled, Mercurial will automatically and transparently start
+      the status daemon the first time you run a command that needs
+      status in a repository.  It runs one status daemon per
+      repository.</para>
+
+    <para id="x_51d">The status daemon is started silently, and runs in the
+      background.  If you look at a list of running processes after
+      you've enabled the <literal role="hg-ext">inotify</literal>
+      extension and run a few commands in different repositories,
+      you'll thus see a few <literal>hg</literal> processes sitting
+      around, waiting for updates from the kernel and queries from
+      Mercurial.</para>
+
+    <para id="x_51e">The first time you run a Mercurial command in a repository
+      when you have the <literal role="hg-ext">inotify</literal>
+      extension enabled, it will run with about the same performance
+      as a normal Mercurial command.  This is because the status
+      daemon needs to perform a normal status scan so that it has a
+      baseline against which to apply later updates from the kernel.
+      However, <emphasis>every</emphasis> subsequent command that does
+      any kind of status check should be noticeably faster on
+      repositories of even fairly modest size.  Better yet, the bigger
+      your repository is, the greater a performance advantage you'll
+      see.  The <literal role="hg-ext">inotify</literal> daemon makes
+      status operations almost instantaneous on repositories of all
+      sizes!</para>
+
+    <para id="x_51f">If you like, you can manually start a status daemon using
+      the <command role="hg-ext-inotify">inserve</command> command.
+      This gives you slightly finer control over how the daemon ought
+      to run.  This command will of course only be available when the
+      <literal role="hg-ext">inotify</literal> extension is
+      enabled.</para>
+
+    <para id="x_520">When you're using the <literal
+	role="hg-ext">inotify</literal> extension, you should notice
+      <emphasis>no difference at all</emphasis> in Mercurial's
+      behavior, with the sole exception of status-related commands
+      running a whole lot faster than they used to.  You should
+      specifically expect that commands will not print different
+      output; neither should they give different results. If either of
+      these situations occurs, please report a bug.</para>
+
+  </sect1>
+  <sect1 id="sec:hgext:extdiff">
+    <title>Flexible diff support with the <literal
+	role="hg-ext">extdiff</literal> extension</title>
+
+    <para id="x_521">Mercurial's built-in <command role="hg-cmd">hg
+	diff</command> command outputs plaintext unified diffs.</para>
+
+    &interaction.extdiff.diff;
+
+    <para id="x_522">If you would like to use an external tool to display
+      modifications, you'll want to use the <literal
+	role="hg-ext">extdiff</literal> extension.  This will let you
+      use, for example, a graphical diff tool.</para>
+
+    <para id="x_523">The <literal role="hg-ext">extdiff</literal> extension is
+      bundled with Mercurial, so it's easy to set up.  In the <literal
+	role="rc-extensions">extensions</literal> section of your
+      <filename role="special">~/.hgrc</filename>, simply add a
+      one-line entry to enable the extension.</para>
+    <programlisting>[extensions]
+extdiff =</programlisting>
+    <para id="x_524">This introduces a command named <command
+	role="hg-ext-extdiff">extdiff</command>, which by default uses
+      your system's <command>diff</command> command to generate a
+      unified diff in the same form as the built-in <command
+	role="hg-cmd">hg diff</command> command.</para>
+    
+    &interaction.extdiff.extdiff;
+
+    <para id="x_525">The result won't be exactly the same as with the built-in
+      <command role="hg-cmd">hg diff</command> variations, because the
+      output of <command>diff</command> varies from one system to
+      another, even when passed the same options.</para>
+
+    <para id="x_526">As the <quote><literal>making snapshot</literal></quote>
+      lines of output above imply, the <command
+	role="hg-ext-extdiff">extdiff</command> command works by
+      creating two snapshots of your source tree.  The first snapshot
+      is of the source revision; the second, of the target revision or
+      working directory.  The <command
+	role="hg-ext-extdiff">extdiff</command> command generates
+      these snapshots in a temporary directory, passes the name of
+      each directory to an external diff viewer, then deletes the
+      temporary directory.  For efficiency, it only snapshots the
+      directories and files that have changed between the two
+      revisions.</para>
+
+    <para id="x_527">Snapshot directory names have the same base name as your
+      repository. If your repository path is <filename
+	class="directory">/quux/bar/foo</filename>, then <filename
+	class="directory">foo</filename> will be the name of each
+      snapshot directory.  Each snapshot directory name has its
+      changeset ID appended, if appropriate.  If a snapshot is of
+      revision <literal>a631aca1083f</literal>, the directory will be
+      named <filename class="directory">foo.a631aca1083f</filename>.
+      A snapshot of the working directory won't have a changeset ID
+      appended, so it would just be <filename
+	class="directory">foo</filename> in this example.  To see what
+      this looks like in practice, look again at the <command
+	role="hg-ext-extdiff">extdiff</command> example above.  Notice
+      that the diff has the snapshot directory names embedded in its
+      header.</para>
+
+    <para id="x_528">The <command role="hg-ext-extdiff">extdiff</command> command
+      accepts two important options. The <option
+	role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option
+      lets you choose a program to view differences with, instead of
+      <command>diff</command>.  With the <option
+	role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option,
+      you can change the options that <command
+	role="hg-ext-extdiff">extdiff</command> passes to the program
+      (by default, these options are
+      <quote><literal>-Npru</literal></quote>, which only make sense
+      if you're running <command>diff</command>).  In other respects,
+      the <command role="hg-ext-extdiff">extdiff</command> command
+      acts similarly to the built-in <command role="hg-cmd">hg
+	diff</command> command: you use the same option names, syntax,
+      and arguments to specify the revisions you want, the files you
+      want, and so on.</para>
+
+    <para id="x_529">As an example, here's how to run the normal system
+      <command>diff</command> command, getting it to generate context
+      diffs (using the <option role="cmd-opt-diff">-c</option> option)
+      instead of unified diffs, and five lines of context instead of
+      the default three (passing <literal>5</literal> as the argument
+      to the <option role="cmd-opt-diff">-C</option> option).</para>
+
+      &interaction.extdiff.extdiff-ctx;
+
+    <para id="x_52a">Launching a visual diff tool is just as easy.  Here's how to
+      launch the <command>kdiff3</command> viewer.</para>
+    <programlisting>hg extdiff -p kdiff3 -o</programlisting>
+
+    <para id="x_52b">If your diff viewing command can't deal with directories,
+      you can easily work around this with a little scripting.  For an
+      example of such scripting in action with the <literal
+	role="hg-ext">mq</literal> extension and the
+      <command>interdiff</command> command, see <xref
+	linkend="mq-collab:tips:interdiff"/>.</para>
+
+    <sect2>
+      <title>Defining command aliases</title>
+
+      <para id="x_52c">It can be cumbersome to remember the options to both the
+	<command role="hg-ext-extdiff">extdiff</command> command and
+	the diff viewer you want to use, so the <literal
+	  role="hg-ext">extdiff</literal> extension lets you define
+	<emphasis>new</emphasis> commands that will invoke your diff
+	viewer with exactly the right options.</para>
+
+      <para id="x_52d">All you need to do is edit your <filename
+	  role="special">~/.hgrc</filename>, and add a section named
+	<literal role="rc-extdiff">extdiff</literal>.  Inside this
+	section, you can define multiple commands.  Here's how to add
+	a <literal>kdiff3</literal> command.  Once you've defined
+	this, you can type <quote><literal>hg kdiff3</literal></quote>
+	and the <literal role="hg-ext">extdiff</literal> extension
+	will run <command>kdiff3</command> for you.</para>
+      <programlisting>[extdiff]
+cmd.kdiff3 =</programlisting>
+      <para id="x_52e">If you leave the right hand side of the definition empty,
+	as above, the <literal role="hg-ext">extdiff</literal>
+	extension uses the name of the command you defined as the name
+	of the external program to run.  But these names don't have to
+	be the same.  Here, we define a command named
+	<quote><literal>hg wibble</literal></quote>, which runs
+	<command>kdiff3</command>.</para>
+      <programlisting>[extdiff]
+ cmd.wibble = kdiff3</programlisting>
+
+      <para id="x_52f">You can also specify the default options that you want to
+	invoke your diff viewing program with.  The prefix to use is
+	<quote><literal>opts.</literal></quote>, followed by the name
+	of the command to which the options apply.  This example
+	defines a <quote><literal>hg vimdiff</literal></quote> command
+	that runs the <command>vim</command> editor's
+	<literal>DirDiff</literal> extension.</para>
+      <programlisting>[extdiff]
+ cmd.vimdiff = vim
+opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting>
+
+    </sect2>
+  </sect1>
+  <sect1 id="sec:hgext:transplant">
+    <title>Cherrypicking changes with the <literal
+	role="hg-ext">transplant</literal> extension</title>
+
+    <para id="x_530">Need to have a long chat with Brendan about this.</para>
+
+  </sect1>
+  <sect1 id="sec:hgext:patchbomb">
+    <title>Send changes via email with the <literal
+	role="hg-ext">patchbomb</literal> extension</title>
+
+    <para id="x_531">Many projects have a culture of <quote>change
+	review</quote>, in which people send their modifications to a
+      mailing list for others to read and comment on before they
+      commit the final version to a shared repository.  Some projects
+      have people who act as gatekeepers; they apply changes from
+      other people to a repository to which those others don't have
+      access.</para>
+
+    <para id="x_532">Mercurial makes it easy to send changes over email for
+      review or application, via its <literal
+	role="hg-ext">patchbomb</literal> extension.  The extension is
+      so named because changes are formatted as patches, and it's usual
+      to send one changeset per email message.  Sending a long series
+      of changes by email is thus much like <quote>bombing</quote> the
+      recipient's inbox, hence <quote>patchbomb</quote>.</para>
+
+    <para id="x_533">As usual, the basic configuration of the <literal
+	role="hg-ext">patchbomb</literal> extension takes just one or
+      two lines in your <filename role="special">
+	/.hgrc</filename>.</para>
+    <programlisting>[extensions]
+patchbomb =</programlisting>
+    <para id="x_534">Once you've enabled the extension, you will have a new
+      command available, named <command
+	role="hg-ext-patchbomb">email</command>.</para>
+
+    <para id="x_535">The safest and best way to invoke the <command
+	role="hg-ext-patchbomb">email</command> command is to
+      <emphasis>always</emphasis> run it first with the <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option.
+      This will show you what the command <emphasis>would</emphasis>
+      send, without actually sending anything.  Once you've had a
+      quick glance over the changes and verified that you are sending
+      the right ones, you can rerun the same command, with the <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option
+      removed.</para>
+
+    <para id="x_536">The <command role="hg-ext-patchbomb">email</command> command
+      accepts the same kind of revision syntax as every other
+      Mercurial command.  For example, this command will send every
+      revision between 7 and <literal>tip</literal>, inclusive.</para>
+    <programlisting>hg email -n 7:tip</programlisting>
+    <para id="x_537">You can also specify a <emphasis>repository</emphasis> to
+      compare with.  If you provide a repository but no revisions, the
+      <command role="hg-ext-patchbomb">email</command> command will
+      send all revisions in the local repository that are not present
+      in the remote repository.  If you additionally specify revisions
+      or a branch name (the latter using the <option
+	role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option),
+      this will constrain the revisions sent.</para>
+
+    <para id="x_538">It's perfectly safe to run the <command
+	role="hg-ext-patchbomb">email</command> command without the
+      names of the people you want to send to: if you do this, it will
+      just prompt you for those values interactively.  (If you're
+      using a Linux or Unix-like system, you should have enhanced
+      <literal>readline</literal>-style editing capabilities when
+      entering those headers, too, which is useful.)</para>
+
+    <para id="x_539">When you are sending just one revision, the <command
+	role="hg-ext-patchbomb">email</command> command will by
+      default use the first line of the changeset description as the
+      subject of the single email message it sends.</para>
+
+    <para id="x_53a">If you send multiple revisions, the <command
+	role="hg-ext-patchbomb">email</command> command will usually
+      send one message per changeset.  It will preface the series with
+      an introductory message, in which you should describe the
+      purpose of the series of changes you're sending.</para>
+
+    <sect2>
+      <title>Changing the behavior of patchbombs</title>
+
+      <para id="x_53b">Not every project has exactly the same conventions for
+	sending changes in email; the <literal
+	  role="hg-ext">patchbomb</literal> extension tries to
+	accommodate a number of variations through command line
+	options.</para>
+      <itemizedlist>
+	<listitem><para id="x_53c">You can write a subject for the introductory
+	    message on the command line using the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -s</option>
+	    option.  This takes one argument, the text of the subject
+	    to use.</para>
+	</listitem>
+	<listitem><para id="x_53d">To change the email address from which the
+	    messages originate, use the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -f</option>
+	    option.  This takes one argument, the email address to
+	    use.</para>
+	</listitem>
+	<listitem><para id="x_53e">The default behavior is to send unified diffs
+	    (see <xref linkend="sec:mq:patch"/> for a
+	    description of the
+	    format), one per message.  You can send a binary bundle
+	    instead with the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -b</option>
+	    option.</para>
+	</listitem>
+	<listitem><para id="x_53f">Unified diffs are normally prefaced with a
+	    metadata header.  You can omit this, and send unadorned
+	    diffs, with the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg
+	      --plain</option> option.</para>
+	</listitem>
+	<listitem><para id="x_540">Diffs are normally sent <quote>inline</quote>,
+	    in the same body part as the description of a patch.  This
+	    makes it easiest for the largest number of readers to
+	    quote and respond to parts of a diff, as some mail clients
+	    will only quote the first MIME body part in a message. If
+	    you'd prefer to send the description and the diff in
+	    separate body parts, use the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -a</option>
+	    option.</para>
+	</listitem>
+	<listitem><para id="x_541">Instead of sending mail messages, you can
+	    write them to an <literal>mbox</literal>-format mail
+	    folder using the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -m</option>
+	    option.  That option takes one argument, the name of the
+	    file to write to.</para>
+	</listitem>
+	<listitem><para id="x_542">If you would like to add a
+	    <command>diffstat</command>-format summary to each patch,
+	    and one to the introductory message, use the <option
+	      role="hg-ext-patchbomb-cmd-email-opt">hg -d</option>
+	    option.  The <command>diffstat</command> command displays
+	    a table containing the name of each file patched, the
+	    number of lines affected, and a histogram showing how much
+	    each file is modified.  This gives readers a qualitative
+	    glance at how complex a patch is.</para>
+	</listitem></itemizedlist>
+
+    </sect2>
+  </sect1>
+</chapter>
+
+<!--
+local variables: 
+sgml-parent-document: ("00book.xml" "book" "chapter")
+end:
+-->
--- a/en/cmdref.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,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: 
--- a/en/collab.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1118 +0,0 @@
-\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 choose 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 id 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}.
-
-If we replace \dirname{/my/root} on the left hand side of this example
-with \dirname{/my}, then \sfilename{hgwebdir.cgi} will only strip off
-\dirname{/my} from the repository name, and will give us a virtual
-path of \dirname{root/this/repo} instead of \dirname{this/repo}.
-
-The \sfilename{hgwebdir.cgi} script will recursively search each
-directory listed in the \texttt{collections} section of its
-configuration file, but it will \texttt{not} recurse into the
-repositories it finds.
-
-The \texttt{collections} mechanism makes it easy to publish many
-repositories in a ``fire and forget'' manner.  You only need to set up
-the CGI script and configuration file one time.  Afterwards, you can
-publish or unpublish a repository at any time by simply moving it
-into, or out of, the directory hierarchy in which you've configured
-\sfilename{hgwebdir.cgi} to look.
-
-\subsubsection{Explicitly specifying which repositories to publish}
-
-In addition to the \texttt{collections} mechanism, the
-\sfilename{hgwebdir.cgi} script allows you to publish a specific list
-of repositories.  To do so, create a \texttt{paths} section, with
-contents of the following form.
-\begin{codesample2}
-  [paths]
-  repo1 = /my/path/to/some/repo
-  repo2 = /some/path/to/another
-\end{codesample2}
-In this case, the virtual path (the component that will appear in a
-URL) is on the left hand side of each definition, while the path to
-the repository is on the right.  Notice that there does not need to be
-any relationship between the virtual path you choose and the location
-of a repository in your filesystem.
-
-If you wish, you can use both the \texttt{collections} and
-\texttt{paths} mechanisms simultaneously in a single configuration
-file.
-
-\begin{note}
-  If multiple repositories have the same virtual path,
-  \sfilename{hgwebdir.cgi} will not report an error.  Instead, it will
-  behave unpredictably.
-\end{note}
-
-\subsection{Downloading source archives}
-
-Mercurial's web interface lets users download an archive of any
-revision.  This archive will contain a snapshot of the working
-directory as of that revision, but it will not contain a copy of the
-repository data.
-
-By default, this feature is not enabled.  To enable it, you'll need to
-add an \rcitem{web}{allow\_archive} item to the \rcsection{web}
-section of your \hgrc.
-
-\subsection{Web configuration options}
-
-Mercurial's web interfaces (the \hgcmd{serve} command, and the
-\sfilename{hgweb.cgi} and \sfilename{hgwebdir.cgi} scripts) have a
-number of configuration options that you can set.  These belong in a
-section named \rcsection{web}.
-\begin{itemize}
-\item[\rcitem{web}{allow\_archive}] Determines which (if any) archive
-  download mechanisms Mercurial supports.  If you enable this
-  feature, users of the web interface will be able to download an
-  archive of whatever revision of a repository they are viewing.
-  To enable the archive feature, this item must take the form of a
-  sequence of words drawn from the list below.
-  \begin{itemize}
-  \item[\texttt{bz2}] A \command{tar} archive, compressed using
-    \texttt{bzip2} compression.  This has the best compression ratio,
-    but uses the most CPU time on the server.
-  \item[\texttt{gz}] A \command{tar} archive, compressed using
-    \texttt{gzip} compression.
-  \item[\texttt{zip}] A \command{zip} archive, compressed using LZW
-    compression.  This format has the worst compression ratio, but is
-    widely used in the Windows world.
-  \end{itemize}
-  If you provide an empty list, or don't have an
-  \rcitem{web}{allow\_archive} entry at all, this feature will be
-  disabled.  Here is an example of how to enable all three supported
-  formats.
-  \begin{codesample4}
-    [web]
-    allow_archive = bz2 gz zip
-  \end{codesample4}
-\item[\rcitem{web}{allowpull}] Boolean.  Determines whether the web
-  interface allows remote users to \hgcmd{pull} and \hgcmd{clone} this
-  repository over~HTTP.  If set to \texttt{no} or \texttt{false}, only
-  the ``human-oriented'' portion of the web interface is available.
-\item[\rcitem{web}{contact}] String.  A free-form (but preferably
-  brief) string identifying the person or group in charge of the
-  repository.  This often contains the name and email address of a
-  person or mailing list.  It often makes sense to place this entry in
-  a repository's own \sfilename{.hg/hgrc} file, but it can make sense
-  to use in a global \hgrc\ if every repository has a single
-  maintainer.
-\item[\rcitem{web}{maxchanges}] Integer.  The default maximum number
-  of changesets to display in a single page of output.
-\item[\rcitem{web}{maxfiles}] Integer.  The default maximum number
-  of modified files to display in a single page of output.
-\item[\rcitem{web}{stripes}] Integer.  If the web interface displays
-  alternating ``stripes'' to make it easier to visually align rows
-  when you are looking at a table, this number controls the number of
-  rows in each stripe.
-\item[\rcitem{web}{style}] Controls the template Mercurial uses to
-  display the web interface.  Mercurial ships with two web templates,
-  named \texttt{default} and \texttt{gitweb} (the latter is much more
-  visually attractive).  You can also specify a custom template of
-  your own; see chapter~\ref{chap:template} for details.  Here, you
-  can see how to enable the \texttt{gitweb} style.
-  \begin{codesample4}
-    [web]
-    style = gitweb
-  \end{codesample4}
-\item[\rcitem{web}{templates}] Path.  The directory in which to search
-  for template files.  By default, Mercurial searches in the directory
-  in which it was installed.
-\end{itemize}
-If you are using \sfilename{hgwebdir.cgi}, you can place a few
-configuration items in a \rcsection{web} section of the
-\sfilename{hgweb.config} file instead of a \hgrc\ file, for
-convenience.  These items are \rcitem{web}{motd} and
-\rcitem{web}{style}.
-
-\subsubsection{Options specific to an individual repository}
-
-A few \rcsection{web} configuration items ought to be placed in a
-repository's local \sfilename{.hg/hgrc}, rather than a user's or
-global \hgrc.
-\begin{itemize}
-\item[\rcitem{web}{description}] String.  A free-form (but preferably
-  brief) string that describes the contents or purpose of the
-  repository.
-\item[\rcitem{web}{name}] String.  The name to use for the repository
-  in the web interface.  This overrides the default name, which is the
-  last component of the repository's path.
-\end{itemize}
-
-\subsubsection{Options specific to the \hgcmd{serve} command}
-
-Some of the items in the \rcsection{web} section of a \hgrc\ file are
-only for use with the \hgcmd{serve} command.
-\begin{itemize}
-\item[\rcitem{web}{accesslog}] Path.  The name of a file into which to
-  write an access log.  By default, the \hgcmd{serve} command writes
-  this information to standard output, not to a file.  Log entries are
-  written in the standard ``combined'' file format used by almost all
-  web servers.
-\item[\rcitem{web}{address}] String.  The local address on which the
-  server should listen for incoming connections.  By default, the
-  server listens on all addresses.
-\item[\rcitem{web}{errorlog}] Path.  The name of a file into which to
-  write an error log.  By default, the \hgcmd{serve} command writes this
-  information to standard error, not to a file.
-\item[\rcitem{web}{ipv6}] Boolean.  Whether to use the IPv6 protocol.
-  By default, IPv6 is not used. 
-\item[\rcitem{web}{port}] Integer.  The TCP~port number on which the
-  server should listen.  The default port number used is~8000.
-\end{itemize}
-
-\subsubsection{Choosing the right \hgrc\ file to add \rcsection{web}
-  items to}
-
-It is important to remember that a web server like Apache or
-\texttt{lighttpd} will run under a user~ID that is different to yours.
-CGI scripts run by your server, such as \sfilename{hgweb.cgi}, will
-usually also run under that user~ID.
-
-If you add \rcsection{web} items to your own personal \hgrc\ file, CGI
-scripts won't read that \hgrc\ file.  Those settings will thus only
-affect the behaviour of the \hgcmd{serve} command when you run it.  To
-cause CGI scripts to see your settings, either create a \hgrc\ file in
-the home directory of the user ID that runs your web server, or add
-those settings to a system-wide \hgrc\ file.
-
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/concepts.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,577 +0,0 @@
-\chapter{Behind the scenes}
-\label{chap:concepts}
-
-Unlike many revision control systems, the concepts upon which
-Mercurial is built are simple enough that it's easy to understand how
-the software really works.  Knowing this certainly isn't necessary,
-but I find it useful to have a ``mental model'' of what's going on.
-
-This understanding gives me confidence that Mercurial has been
-carefully designed to be both \emph{safe} and \emph{efficient}.  And
-just as importantly, if it's easy for me to retain a good idea of what
-the software is doing when I perform a revision control task, I'm less
-likely to be surprised by its behaviour.
-
-In this chapter, we'll initially cover the core concepts behind
-Mercurial's design, then continue to discuss some of the interesting
-details of its implementation.
-
-\section{Mercurial's historical record}
-
-\subsection{Tracking the history of a single file}
-
-When Mercurial tracks modifications to a file, it stores the history
-of that file in a metadata object called a \emph{filelog}.  Each entry
-in the filelog contains enough information to reconstruct one revision
-of the file that is being tracked.  Filelogs are stored as files in
-the \sdirname{.hg/store/data} directory.  A filelog contains two kinds
-of information: revision data, and an index to help Mercurial to find
-a revision efficiently.
-
-A file that is large, or has a lot of history, has its filelog stored
-in separate data (``\texttt{.d}'' suffix) and index (``\texttt{.i}''
-suffix) files.  For small files without much history, the revision
-data and index are combined in a single ``\texttt{.i}'' file.  The
-correspondence between a file in the working directory and the filelog
-that tracks its history in the repository is illustrated in
-figure~\ref{fig:concepts:filelog}.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{filelog}
-  \caption{Relationships between files in working directory and
-    filelogs in repository}
-  \label{fig:concepts:filelog}
-\end{figure}
-
-\subsection{Managing tracked files}
-
-Mercurial uses a structure called a \emph{manifest} to collect
-together information about the files that it tracks.  Each entry in
-the manifest contains information about the files present in a single
-changeset.  An entry records which files are present in the changeset,
-the revision of each file, and a few other pieces of file metadata.
-
-\subsection{Recording changeset information}
-
-The \emph{changelog} contains information about each changeset.  Each
-revision records who committed a change, the changeset comment, other
-pieces of changeset-related information, and the revision of the
-manifest to use.
-
-\subsection{Relationships between revisions}
-
-Within a changelog, a manifest, or a filelog, each revision stores a
-pointer to its immediate parent (or to its two parents, if it's a
-merge revision).  As I mentioned above, there are also relationships
-between revisions \emph{across} these structures, and they are
-hierarchical in nature.
-
-For every changeset in a repository, there is exactly one revision
-stored in the changelog.  Each revision of the changelog contains a
-pointer to a single revision of the manifest.  A revision of the
-manifest stores a pointer to a single revision of each filelog tracked
-when that changeset was created.  These relationships are illustrated
-in figure~\ref{fig:concepts:metadata}.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{metadata}
-  \caption{Metadata relationships}
-  \label{fig:concepts:metadata}
-\end{figure}
-
-As the illustration shows, there is \emph{not} a ``one to one''
-relationship between revisions in the changelog, manifest, or filelog.
-If the manifest hasn't changed between two changesets, the changelog
-entries for those changesets will point to the same revision of the
-manifest.  If a file that Mercurial tracks hasn't changed between two
-changesets, the entry for that file in the two revisions of the
-manifest will point to the same revision of its filelog.
-
-\section{Safe, efficient storage}
-
-The underpinnings of changelogs, manifests, and filelogs are provided
-by a single structure called the \emph{revlog}.
-
-\subsection{Efficient storage}
-
-The revlog provides efficient storage of revisions using a
-\emph{delta} mechanism.  Instead of storing a complete copy of a file
-for each revision, it stores the changes needed to transform an older
-revision into the new revision.  For many kinds of file data, these
-deltas are typically a fraction of a percent of the size of a full
-copy of a file.
-
-Some obsolete revision control systems can only work with deltas of
-text files.  They must either store binary files as complete snapshots
-or encoded into a text representation, both of which are wasteful
-approaches.  Mercurial can efficiently handle deltas of files with
-arbitrary binary contents; it doesn't need to treat text as special.
-
-\subsection{Safe operation}
-\label{sec:concepts:txn}
-
-Mercurial only ever \emph{appends} data to the end of a revlog file.
-It never modifies a section of a file after it has written it.  This
-is both more robust and efficient than schemes that need to modify or
-rewrite data.
-
-In addition, Mercurial treats every write as part of a
-\emph{transaction} that can span a number of files.  A transaction is
-\emph{atomic}: either the entire transaction succeeds and its effects
-are all visible to readers in one go, or the whole thing is undone.
-This guarantee of atomicity means that if you're running two copies of
-Mercurial, where one is reading data and one is writing it, the reader
-will never see a partially written result that might confuse it.
-
-The fact that Mercurial only appends to files makes it easier to
-provide this transactional guarantee.  The easier it is to do stuff
-like this, the more confident you should be that it's done correctly.
-
-\subsection{Fast retrieval}
-
-Mercurial cleverly avoids a pitfall common to all earlier
-revision control systems: the problem of \emph{inefficient retrieval}.
-Most revision control systems store the contents of a revision as an
-incremental series of modifications against a ``snapshot''.  To
-reconstruct a specific revision, you must first read the snapshot, and
-then every one of the revisions between the snapshot and your target
-revision.  The more history that a file accumulates, the more
-revisions you must read, hence the longer it takes to reconstruct a
-particular revision.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{snapshot}
-  \caption{Snapshot of a revlog, with incremental deltas}
-  \label{fig:concepts:snapshot}
-\end{figure}
-
-The innovation that Mercurial applies to this problem is simple but
-effective.  Once the cumulative amount of delta information stored
-since the last snapshot exceeds a fixed threshold, it stores a new
-snapshot (compressed, of course), instead of another delta.  This
-makes it possible to reconstruct \emph{any} revision of a file
-quickly.  This approach works so well that it has since been copied by
-several other revision control systems.
-
-Figure~\ref{fig:concepts:snapshot} illustrates the idea.  In an entry
-in a revlog's index file, Mercurial stores the range of entries from
-the data file that it must read to reconstruct a particular revision.
-
-\subsubsection{Aside: the influence of video compression}
-
-If you're familiar with video compression or have ever watched a TV
-feed through a digital cable or satellite service, you may know that
-most video compression schemes store each frame of video as a delta
-against its predecessor frame.  In addition, these schemes use
-``lossy'' compression techniques to increase the compression ratio, so
-visual errors accumulate over the course of a number of inter-frame
-deltas.
-
-Because it's possible for a video stream to ``drop out'' occasionally
-due to signal glitches, and to limit the accumulation of artefacts
-introduced by the lossy compression process, video encoders
-periodically insert a complete frame (called a ``key frame'') into the
-video stream; the next delta is generated against that frame.  This
-means that if the video signal gets interrupted, it will resume once
-the next key frame is received.  Also, the accumulation of encoding
-errors restarts anew with each key frame.
-
-\subsection{Identification and strong integrity}
-
-Along with delta or snapshot information, a revlog entry contains a
-cryptographic hash of the data that it represents.  This makes it
-difficult to forge the contents of a revision, and easy to detect
-accidental corruption.  
-
-Hashes provide more than a mere check against corruption; they are
-used as the identifiers for revisions.  The changeset identification
-hashes that you see as an end user are from revisions of the
-changelog.  Although filelogs and the manifest also use hashes,
-Mercurial only uses these behind the scenes.
-
-Mercurial verifies that hashes are correct when it retrieves file
-revisions and when it pulls changes from another repository.  If it
-encounters an integrity problem, it will complain and stop whatever
-it's doing.
-
-In addition to the effect it has on retrieval efficiency, Mercurial's
-use of periodic snapshots makes it more robust against partial data
-corruption.  If a revlog becomes partly corrupted due to a hardware
-error or system bug, it's often possible to reconstruct some or most
-revisions from the uncorrupted sections of the revlog, both before and
-after the corrupted section.  This would not be possible with a
-delta-only storage model.
-
-\section{Revision history, branching,
-  and merging}
-
-Every entry in a Mercurial revlog knows the identity of its immediate
-ancestor revision, usually referred to as its \emph{parent}.  In fact,
-a revision contains room for not one parent, but two.  Mercurial uses
-a special hash, called the ``null ID'', to represent the idea ``there
-is no parent here''.  This hash is simply a string of zeroes.
-
-In figure~\ref{fig:concepts:revlog}, you can see an example of the
-conceptual structure of a revlog.  Filelogs, manifests, and changelogs
-all have this same structure; they differ only in the kind of data
-stored in each delta or snapshot.
-
-The first revision in a revlog (at the bottom of the image) has the
-null ID in both of its parent slots.  For a ``normal'' revision, its
-first parent slot contains the ID of its parent revision, and its
-second contains the null ID, indicating that the revision has only one
-real parent.  Any two revisions that have the same parent ID are
-branches.  A revision that represents a merge between branches has two
-normal revision IDs in its parent slots.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{revlog}
-  \caption{}
-  \label{fig:concepts:revlog}
-\end{figure}
-
-\section{The working directory}
-
-In the working directory, Mercurial stores a snapshot of the files
-from the repository as of a particular changeset.
-
-The working directory ``knows'' which changeset it contains.  When you
-update the working directory to contain a particular changeset,
-Mercurial looks up the appropriate revision of the manifest to find
-out which files it was tracking at the time that changeset was
-committed, and which revision of each file was then current.  It then
-recreates a copy of each of those files, with the same contents it had
-when the changeset was committed.
-
-The \emph{dirstate} contains Mercurial's knowledge of the working
-directory.  This details which changeset the working directory is
-updated to, and all of the files that Mercurial is tracking in the
-working directory.
-
-Just as a revision of a revlog has room for two parents, so that it
-can represent either a normal revision (with one parent) or a merge of
-two earlier revisions, the dirstate has slots for two parents.  When
-you use the \hgcmd{update} command, the changeset that you update to
-is stored in the ``first parent'' slot, and the null ID in the second.
-When you \hgcmd{merge} with another changeset, the first parent
-remains unchanged, and the second parent is filled in with the
-changeset you're merging with.  The \hgcmd{parents} command tells you
-what the parents of the dirstate are.
-
-\subsection{What happens when you commit}
-
-The dirstate stores parent information for more than just book-keeping
-purposes.  Mercurial uses the parents of the dirstate as \emph{the
-  parents of a new changeset} when you perform a commit.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{wdir}
-  \caption{The working directory can have two parents}
-  \label{fig:concepts:wdir}
-\end{figure}
-
-Figure~\ref{fig:concepts:wdir} shows the normal state of the working
-directory, where it has a single changeset as parent.  That changeset
-is the \emph{tip}, the newest changeset in the repository that has no
-children.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{wdir-after-commit}
-  \caption{The working directory gains new parents after a commit}
-  \label{fig:concepts:wdir-after-commit}
-\end{figure}
-
-It's useful to think of the working directory as ``the changeset I'm
-about to commit''.  Any files that you tell Mercurial that you've
-added, removed, renamed, or copied will be reflected in that
-changeset, as will modifications to any files that Mercurial is
-already tracking; the new changeset will have the parents of the
-working directory as its parents.
-
-After a commit, Mercurial will update the parents of the working
-directory, so that the first parent is the ID of the new changeset,
-and the second is the null ID.  This is shown in
-figure~\ref{fig:concepts:wdir-after-commit}.  Mercurial doesn't touch
-any of the files in the working directory when you commit; it just
-modifies the dirstate to note its new parents.
-
-\subsection{Creating a new head}
-
-It's perfectly normal to update the working directory to a changeset
-other than the current tip.  For example, you might want to know what
-your project looked like last Tuesday, or you could be looking through
-changesets to see which one introduced a bug.  In cases like this, the
-natural thing to do is update the working directory to the changeset
-you're interested in, and then examine the files in the working
-directory directly to see their contents as they werea when you
-committed that changeset.  The effect of this is shown in
-figure~\ref{fig:concepts:wdir-pre-branch}.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{wdir-pre-branch}
-  \caption{The working directory, updated to an older changeset}
-  \label{fig:concepts:wdir-pre-branch}
-\end{figure}
-
-Having updated the working directory to an older changeset, what
-happens if you make some changes, and then commit?  Mercurial behaves
-in the same way as I outlined above.  The parents of the working
-directory become the parents of the new changeset.  This new changeset
-has no children, so it becomes the new tip.  And the repository now
-contains two changesets that have no children; we call these
-\emph{heads}.  You can see the structure that this creates in
-figure~\ref{fig:concepts:wdir-branch}.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{wdir-branch}
-  \caption{After a commit made while synced to an older changeset}
-  \label{fig:concepts:wdir-branch}
-\end{figure}
-
-\begin{note}
-  If you're new to Mercurial, you should keep in mind a common
-  ``error'', which is to use the \hgcmd{pull} command without any
-  options.  By default, the \hgcmd{pull} command \emph{does not}
-  update the working directory, so you'll bring new changesets into
-  your repository, but the working directory will stay synced at the
-  same changeset as before the pull.  If you make some changes and
-  commit afterwards, you'll thus create a new head, because your
-  working directory isn't synced to whatever the current tip is.
-
-  I put the word ``error'' in quotes because all that you need to do
-  to rectify this situation is \hgcmd{merge}, then \hgcmd{commit}.  In
-  other words, this almost never has negative consequences; it just
-  surprises people.  I'll discuss other ways to avoid this behaviour,
-  and why Mercurial behaves in this initially surprising way, later
-  on.
-\end{note}
-
-\subsection{Merging heads}
-
-When you run the \hgcmd{merge} command, Mercurial leaves the first
-parent of the working directory unchanged, and sets the second parent
-to the changeset you're merging with, as shown in
-figure~\ref{fig:concepts:wdir-merge}.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{wdir-merge}
-  \caption{Merging two heads}
-  \label{fig:concepts:wdir-merge}
-\end{figure}
-
-Mercurial also has to modify the working directory, to merge the files
-managed in the two changesets.  Simplified a little, the merging
-process goes like this, for every file in the manifests of both
-changesets.
-\begin{itemize}
-\item If neither changeset has modified a file, do nothing with that
-  file.
-\item If one changeset has modified a file, and the other hasn't,
-  create the modified copy of the file in the working directory.
-\item If one changeset has removed a file, and the other hasn't (or
-  has also deleted it), delete the file from the working directory.
-\item If one changeset has removed a file, but the other has modified
-  the file, ask the user what to do: keep the modified file, or remove
-  it?
-\item If both changesets have modified a file, invoke an external
-  merge program to choose the new contents for the merged file.  This
-  may require input from the user.
-\item If one changeset has modified a file, and the other has renamed
-  or copied the file, make sure that the changes follow the new name
-  of the file.
-\end{itemize}
-There are more details---merging has plenty of corner cases---but
-these are the most common choices that are involved in a merge.  As
-you can see, most cases are completely automatic, and indeed most
-merges finish automatically, without requiring your input to resolve
-any conflicts.
-
-When you're thinking about what happens when you commit after a merge,
-once again the working directory is ``the changeset I'm about to
-commit''.  After the \hgcmd{merge} command completes, the working
-directory has two parents; these will become the parents of the new
-changeset.
-
-Mercurial lets you perform multiple merges, but you must commit the
-results of each individual merge as you go.  This is necessary because
-Mercurial only tracks two parents for both revisions and the working
-directory.  While it would be technically possible to merge multiple
-changesets at once, the prospect of user confusion and making a
-terrible mess of a merge immediately becomes overwhelming.
-
-\section{Other interesting design features}
-
-In the sections above, I've tried to highlight some of the most
-important aspects of Mercurial's design, to illustrate that it pays
-careful attention to reliability and performance.  However, the
-attention to detail doesn't stop there.  There are a number of other
-aspects of Mercurial's construction that I personally find
-interesting.  I'll detail a few of them here, separate from the ``big
-ticket'' items above, so that if you're interested, you can gain a
-better idea of the amount of thinking that goes into a well-designed
-system.
-
-\subsection{Clever compression}
-
-When appropriate, Mercurial will store both snapshots and deltas in
-compressed form.  It does this by always \emph{trying to} compress a
-snapshot or delta, but only storing the compressed version if it's
-smaller than the uncompressed version.
-
-This means that Mercurial does ``the right thing'' when storing a file
-whose native form is compressed, such as a \texttt{zip} archive or a
-JPEG image.  When these types of files are compressed a second time,
-the resulting file is usually bigger than the once-compressed form,
-and so Mercurial will store the plain \texttt{zip} or JPEG.
-
-Deltas between revisions of a compressed file are usually larger than
-snapshots of the file, and Mercurial again does ``the right thing'' in
-these cases.  It finds that such a delta exceeds the threshold at
-which it should store a complete snapshot of the file, so it stores
-the snapshot, again saving space compared to a naive delta-only
-approach.
-
-\subsubsection{Network recompression}
-
-When storing revisions on disk, Mercurial uses the ``deflate''
-compression algorithm (the same one used by the popular \texttt{zip}
-archive format), which balances good speed with a respectable
-compression ratio.  However, when transmitting revision data over a
-network connection, Mercurial uncompresses the compressed revision
-data.
-
-If the connection is over HTTP, Mercurial recompresses the entire
-stream of data using a compression algorithm that gives a better
-compression ratio (the Burrows-Wheeler algorithm from the widely used
-\texttt{bzip2} compression package).  This combination of algorithm
-and compression of the entire stream (instead of a revision at a time)
-substantially reduces the number of bytes to be transferred, yielding
-better network performance over almost all kinds of network.
-
-(If the connection is over \command{ssh}, Mercurial \emph{doesn't}
-recompress the stream, because \command{ssh} can already do this
-itself.)
-
-\subsection{Read/write ordering and atomicity}
-
-Appending to files isn't the whole story when it comes to guaranteeing
-that a reader won't see a partial write.  If you recall
-figure~\ref{fig:concepts:metadata}, revisions in the changelog point to
-revisions in the manifest, and revisions in the manifest point to
-revisions in filelogs.  This hierarchy is deliberate.
-
-A writer starts a transaction by writing filelog and manifest data,
-and doesn't write any changelog data until those are finished.  A
-reader starts by reading changelog data, then manifest data, followed
-by filelog data.
-
-Since the writer has always finished writing filelog and manifest data
-before it writes to the changelog, a reader will never read a pointer
-to a partially written manifest revision from the changelog, and it will
-never read a pointer to a partially written filelog revision from the
-manifest.
-
-\subsection{Concurrent access}
-
-The read/write ordering and atomicity guarantees mean that Mercurial
-never needs to \emph{lock} a repository when it's reading data, even
-if the repository is being written to while the read is occurring.
-This has a big effect on scalability; you can have an arbitrary number
-of Mercurial processes safely reading data from a repository safely
-all at once, no matter whether it's being written to or not.
-
-The lockless nature of reading means that if you're sharing a
-repository on a multi-user system, you don't need to grant other local
-users permission to \emph{write} to your repository in order for them
-to be able to clone it or pull changes from it; they only need
-\emph{read} permission.  (This is \emph{not} a common feature among
-revision control systems, so don't take it for granted!  Most require
-readers to be able to lock a repository to access it safely, and this
-requires write permission on at least one directory, which of course
-makes for all kinds of nasty and annoying security and administrative
-problems.)
-
-Mercurial uses locks to ensure that only one process can write to a
-repository at a time (the locking mechanism is safe even over
-filesystems that are notoriously hostile to locking, such as NFS).  If
-a repository is locked, a writer will wait for a while to retry if the
-repository becomes unlocked, but if the repository remains locked for
-too long, the process attempting to write will time out after a while.
-This means that your daily automated scripts won't get stuck forever
-and pile up if a system crashes unnoticed, for example.  (Yes, the
-timeout is configurable, from zero to infinity.)
-
-\subsubsection{Safe dirstate access}
-
-As with revision data, Mercurial doesn't take a lock to read the
-dirstate file; it does acquire a lock to write it.  To avoid the
-possibility of reading a partially written copy of the dirstate file,
-Mercurial writes to a file with a unique name in the same directory as
-the dirstate file, then renames the temporary file atomically to
-\filename{dirstate}.  The file named \filename{dirstate} is thus
-guaranteed to be complete, not partially written.
-
-\subsection{Avoiding seeks}
-
-Critical to Mercurial's performance is the avoidance of seeks of the
-disk head, since any seek is far more expensive than even a
-comparatively large read operation.
-
-This is why, for example, the dirstate is stored in a single file.  If
-there were a dirstate file per directory that Mercurial tracked, the
-disk would seek once per directory.  Instead, Mercurial reads the
-entire single dirstate file in one step.
-
-Mercurial also uses a ``copy on write'' scheme when cloning a
-repository on local storage.  Instead of copying every revlog file
-from the old repository into the new repository, it makes a ``hard
-link'', which is a shorthand way to say ``these two names point to the
-same file''.  When Mercurial is about to write to one of a revlog's
-files, it checks to see if the number of names pointing at the file is
-greater than one.  If it is, more than one repository is using the
-file, so Mercurial makes a new copy of the file that is private to
-this repository.
-
-A few revision control developers have pointed out that this idea of
-making a complete private copy of a file is not very efficient in its
-use of storage.  While this is true, storage is cheap, and this method
-gives the highest performance while deferring most book-keeping to the
-operating system.  An alternative scheme would most likely reduce
-performance and increase the complexity of the software, each of which
-is much more important to the ``feel'' of day-to-day use.
-
-\subsection{Other contents of the dirstate}
-
-Because Mercurial doesn't force you to tell it when you're modifying a
-file, it uses the dirstate to store some extra information so it can
-determine efficiently whether you have modified a file.  For each file
-in the working directory, it stores the time that it last modified the
-file itself, and the size of the file at that time.  
-
-When you explicitly \hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} or
-\hgcmd{copy} files, Mercurial updates the dirstate so that it knows
-what to do with those files when you commit.
-
-When Mercurial is checking the states of files in the working
-directory, it first checks a file's modification time.  If that has
-not changed, the file must not have been modified.  If the file's size
-has changed, the file must have been modified.  If the modification
-time has changed, but the size has not, only then does Mercurial need
-to read the actual contents of the file to see if they've changed.
-Storing these few extra pieces of information dramatically reduces the
-amount of data that Mercurial needs to read, which yields large
-performance improvements compared to other revision control systems.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End:
--- a/en/daily.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-\chapter{Mercurial in daily use}
-\label{chap:daily}
-
-\section{Telling Mercurial which files to track}
-
-Mercurial does not work with files in your repository unless you tell
-it to manage them.  The \hgcmd{status} command will tell you which
-files Mercurial doesn't know about; it uses a ``\texttt{?}'' to
-display such files.
-
-To tell Mercurial to track a file, use the \hgcmd{add} command.  Once
-you have added a file, the entry in the output of \hgcmd{status} for
-that file changes from ``\texttt{?}'' to ``\texttt{A}''.
-\interaction{daily.files.add}
-
-After you run a \hgcmd{commit}, the files that you added before the
-commit will no longer be listed in the output of \hgcmd{status}.  The
-reason for this is that \hgcmd{status} only tells you about
-``interesting'' files---those that you have modified or told Mercurial
-to do something with---by default.  If you have a repository that
-contains thousands of files, you will rarely want to know about files
-that Mercurial is tracking, but that have not changed.  (You can still
-get this information; we'll return to this later.)
-
-Once you add a file, Mercurial doesn't do anything with it
-immediately.  Instead, it will take a snapshot of the file's state the
-next time you perform a commit.  It will then continue to track the
-changes you make to the file every time you commit, until you remove
-the file.
-
-\subsection{Explicit versus implicit file naming}
-
-A useful behaviour that Mercurial has is that if you pass the name of
-a directory to a command, every Mercurial command will treat this as
-``I want to operate on every file in this directory and its
-subdirectories''.
-\interaction{daily.files.add-dir}
-Notice in this example that Mercurial printed the names of the files
-it added, whereas it didn't do so when we added the file named
-\filename{a} in the earlier example.
-
-What's going on is that in the former case, we explicitly named the
-file to add on the command line, so the assumption that Mercurial
-makes in such cases is that you know what you were doing, and it
-doesn't print any output.
-
-However, when we \emph{imply} the names of files by giving the name of
-a directory, Mercurial takes the extra step of printing the name of
-each file that it does something with.  This makes it more clear what
-is happening, and reduces the likelihood of a silent and nasty
-surprise.  This behaviour is common to most Mercurial commands.
-
-\subsection{Aside: Mercurial tracks files, not directories}
-
-Mercurial does not track directory information.  Instead, it tracks
-the path to a file.  Before creating a file, it first creates any
-missing directory components of the path.  After it deletes a file, it
-then deletes any empty directories that were in the deleted file's
-path.  This sounds like a trivial distinction, but it has one minor
-practical consequence: it is not possible to represent a completely
-empty directory in Mercurial.
-
-Empty directories are rarely useful, and there are unintrusive
-workarounds that you can use to achieve an appropriate effect.  The
-developers of Mercurial thus felt that the complexity that would be
-required to manage empty directories was not worth the limited benefit
-this feature would bring.
-
-If you need an empty directory in your repository, there are a few
-ways to achieve this. One is to create a directory, then \hgcmd{add} a
-``hidden'' file to that directory.  On Unix-like systems, any file
-name that begins with a period (``\texttt{.}'') is treated as hidden
-by most commands and GUI tools.  This approach is illustrated in
-figure~\ref{ex:daily:hidden}.
-
-\begin{figure}[ht]
-  \interaction{daily.files.hidden}
-  \caption{Simulating an empty directory using a hidden file}
-  \label{ex:daily:hidden}
-\end{figure}
-
-Another way to tackle a need for an empty directory is to simply
-create one in your automated build scripts before they will need it.
-
-\section{How to stop tracking a file}
-
-Once you decide that a file no longer belongs in your repository, use
-the \hgcmd{remove} command; this deletes the file, and tells Mercurial
-to stop tracking it.  A removed file is represented in the output of
-\hgcmd{status} with a ``\texttt{R}''.
-\interaction{daily.files.remove}
-
-After you \hgcmd{remove} a file, Mercurial will no longer track
-changes to that file, even if you recreate a file with the same name
-in your working directory.  If you do recreate a file with the same
-name and want Mercurial to track the new file, simply \hgcmd{add} it.
-Mercurial will know that the newly added file is not related to the
-old file of the same name.
-
-\subsection{Removing a file does not affect its history}
-
-It is important to understand that removing a file has only two
-effects.
-\begin{itemize}
-\item It removes the current version of the file from the working
-  directory.
-\item It stops Mercurial from tracking changes to the file, from the
-  time of the next commit.
-\end{itemize}
-Removing a file \emph{does not} in any way alter the \emph{history} of
-the file.
-
-If you update the working directory to a changeset in which a file
-that you have removed was still tracked, it will reappear in the
-working directory, with the contents it had when you committed that
-changeset.  If you then update the working directory to a later
-changeset, in which the file had been removed, Mercurial will once
-again remove the file from the working directory.
-
-\subsection{Missing files}
-
-Mercurial considers a file that you have deleted, but not used
-\hgcmd{remove} to delete, to be \emph{missing}.  A missing file is
-represented with ``\texttt{!}'' in the output of \hgcmd{status}.
-Mercurial commands will not generally do anything with missing files.
-\interaction{daily.files.missing}
-
-If your repository contains a file that \hgcmd{status} reports as
-missing, and you want the file to stay gone, you can run
-\hgcmdargs{remove}{\hgopt{remove}{--after}} at any time later on, to
-tell Mercurial that you really did mean to remove the file.
-\interaction{daily.files.remove-after}
-
-On the other hand, if you deleted the missing file by accident, use
-\hgcmdargs{revert}{\emph{filename}} to recover the file.  It will
-reappear, in unmodified form.
-\interaction{daily.files.recover-missing}
-
-\subsection{Aside: why tell Mercurial explicitly to 
-  remove a file?}
-
-You might wonder why Mercurial requires you to explicitly tell it that
-you are deleting a file.  Early during the development of Mercurial,
-it let you delete a file however you pleased; Mercurial would notice
-the absence of the file automatically when you next ran a
-\hgcmd{commit}, and stop tracking the file.  In practice, this made it
-too easy to accidentally remove a file without noticing.
-
-\subsection{Useful shorthand---adding and removing files
-  in one step}
-
-Mercurial offers a combination command, \hgcmd{addremove}, that adds
-untracked files and marks missing files as removed.  
-\interaction{daily.files.addremove}
-The \hgcmd{commit} command also provides a \hgopt{commit}{-A} option
-that performs this same add-and-remove, immediately followed by a
-commit.
-\interaction{daily.files.commit-addremove}
-
-\section{Copying files}
-
-Mercurial provides a \hgcmd{copy} command that lets you make a new
-copy of a file.  When you copy a file using this command, Mercurial
-makes a record of the fact that the new file is a copy of the original
-file.  It treats these copied files specially when you merge your work
-with someone else's.
-
-\subsection{The results of copying during a merge}
-
-What happens during a merge is that changes ``follow'' a copy.  To
-best illustrate what this means, let's create an example.  We'll start
-with the usual tiny repository that contains a single file.
-\interaction{daily.copy.init}
-We need to do some work in parallel, so that we'll have something to
-merge.  So let's clone our repository.
-\interaction{daily.copy.clone}
-Back in our initial repository, let's use the \hgcmd{copy} command to
-make a copy of the first file we created.
-\interaction{daily.copy.copy}
-
-If we look at the output of the \hgcmd{status} command afterwards, the
-copied file looks just like a normal added file.
-\interaction{daily.copy.status}
-But if we pass the \hgopt{status}{-C} option to \hgcmd{status}, it
-prints another line of output: this is the file that our newly-added
-file was copied \emph{from}.
-\interaction{daily.copy.status-copy}
-
-Now, back in the repository we cloned, let's make a change in
-parallel.  We'll add a line of content to the original file that we
-created.
-\interaction{daily.copy.other}
-Now we have a modified \filename{file} in this repository.  When we
-pull the changes from the first repository, and merge the two heads,
-Mercurial will propagate the changes that we made locally to
-\filename{file} into its copy, \filename{new-file}.
-\interaction{daily.copy.merge}
-
-\subsection{Why should changes follow copies?}
-\label{sec:daily:why-copy}
-
-This behaviour, of changes to a file propagating out to copies of the
-file, might seem esoteric, but in most cases it's highly desirable.
-
-First of all, remember that this propagation \emph{only} happens when
-you merge.  So if you \hgcmd{copy} a file, and subsequently modify the
-original file during the normal course of your work, nothing will
-happen.
-
-The second thing to know is that modifications will only propagate
-across a copy as long as the repository that you're pulling changes
-from \emph{doesn't know} about the copy.
-
-The reason that Mercurial does this is as follows.  Let's say I make
-an important bug fix in a source file, and commit my changes.
-Meanwhile, you've decided to \hgcmd{copy} the file in your repository,
-without knowing about the bug or having seen the fix, and you have
-started hacking on your copy of the file.
-
-If you pulled and merged my changes, and Mercurial \emph{didn't}
-propagate changes across copies, your source file would now contain
-the bug, and unless you remembered to propagate the bug fix by hand,
-the bug would \emph{remain} in your copy of the file.
-
-By automatically propagating the change that fixed the bug from the
-original file to the copy, Mercurial prevents this class of problem.
-To my knowledge, Mercurial is the \emph{only} revision control system
-that propagates changes across copies like this.
-
-Once your change history has a record that the copy and subsequent
-merge occurred, there's usually no further need to propagate changes
-from the original file to the copied file, and that's why Mercurial
-only propagates changes across copies until this point, and no
-further.
-
-\subsection{How to make changes \emph{not} follow a copy}
-
-If, for some reason, you decide that this business of automatically
-propagating changes across copies is not for you, simply use your
-system's normal file copy command (on Unix-like systems, that's
-\command{cp}) to make a copy of a file, then \hgcmd{add} the new copy
-by hand.  Before you do so, though, please do reread
-section~\ref{sec:daily:why-copy}, and make an informed decision that
-this behaviour is not appropriate to your specific case.
-
-\subsection{Behaviour of the \hgcmd{copy} command}
-
-When you use the \hgcmd{copy} command, Mercurial makes a copy of each
-source file as it currently stands in the working directory.  This
-means that if you make some modifications to a file, then \hgcmd{copy}
-it without first having committed those changes, the new copy will
-also contain the modifications you have made up until that point.  (I
-find this behaviour a little counterintuitive, which is why I mention
-it here.)
-
-The \hgcmd{copy} command acts similarly to the Unix \command{cp}
-command (you can use the \hgcmd{cp} alias if you prefer).  The last
-argument is the \emph{destination}, and all prior arguments are
-\emph{sources}.  If you pass it a single file as the source, and the
-destination does not exist, it creates a new file with that name.
-\interaction{daily.copy.simple}
-If the destination is a directory, Mercurial copies its sources into
-that directory.
-\interaction{daily.copy.dir-dest}
-Copying a directory is recursive, and preserves the directory
-structure of the source.
-\interaction{daily.copy.dir-src}
-If the source and destination are both directories, the source tree is
-recreated in the destination directory.
-\interaction{daily.copy.dir-src-dest}
-
-As with the \hgcmd{rename} command, if you copy a file manually and
-then want Mercurial to know that you've copied the file, simply use
-the \hgopt{copy}{--after} option to \hgcmd{copy}.
-\interaction{daily.copy.after}
-
-\section{Renaming files}
-
-It's rather more common to need to rename a file than to make a copy
-of it.  The reason I discussed the \hgcmd{copy} command before talking
-about renaming files is that Mercurial treats a rename in essentially
-the same way as a copy.  Therefore, knowing what Mercurial does when
-you copy a file tells you what to expect when you rename a file.
-
-When you use the \hgcmd{rename} command, Mercurial makes a copy of
-each source file, then deletes it and marks the file as removed.
-\interaction{daily.rename.rename}
-The \hgcmd{status} command shows the newly copied file as added, and
-the copied-from file as removed.
-\interaction{daily.rename.status}
-As with the results of a \hgcmd{copy}, we must use the
-\hgopt{status}{-C} option to \hgcmd{status} to see that the added file
-is really being tracked by Mercurial as a copy of the original, now
-removed, file.
-\interaction{daily.rename.status-copy}
-
-As with \hgcmd{remove} and \hgcmd{copy}, you can tell Mercurial about
-a rename after the fact using the \hgopt{rename}{--after} option.  In
-most other respects, the behaviour of the \hgcmd{rename} command, and
-the options it accepts, are similar to the \hgcmd{copy} command.
-
-\subsection{Renaming files and merging changes}
-
-Since Mercurial's rename is implemented as copy-and-remove, the same
-propagation of changes happens when you merge after a rename as after
-a copy.
-
-If I modify a file, and you rename it to a new name, and then we merge
-our respective changes, my modifications to the file under its
-original name will be propagated into the file under its new name.
-(This is something you might expect to ``simply work,'' but not all
-revision control systems actually do this.)
-
-Whereas having changes follow a copy is a feature where you can
-perhaps nod and say ``yes, that might be useful,'' it should be clear
-that having them follow a rename is definitely important.  Without
-this facility, it would simply be too easy for changes to become
-orphaned when files are renamed.
-
-\subsection{Divergent renames and merging}
-
-The case of diverging names occurs when two developers start with a
-file---let's call it \filename{foo}---in their respective
-repositories.
-
-\interaction{rename.divergent.clone}
-Anne renames the file to \filename{bar}.
-\interaction{rename.divergent.rename.anne}
-Meanwhile, Bob renames it to \filename{quux}.
-\interaction{rename.divergent.rename.bob}
-
-I like to think of this as a conflict because each developer has
-expressed different intentions about what the file ought to be named.
-
-What do you think should happen when they merge their work?
-Mercurial's actual behaviour is that it always preserves \emph{both}
-names when it merges changesets that contain divergent renames.
-\interaction{rename.divergent.merge}
-
-Notice that Mercurial does warn about the divergent renames, but it
-leaves it up to you to do something about the divergence after the merge.
-
-\subsection{Convergent renames and merging}
-
-Another kind of rename conflict occurs when two people choose to
-rename different \emph{source} files to the same \emph{destination}.
-In this case, Mercurial runs its normal merge machinery, and lets you
-guide it to a suitable resolution.
-
-\subsection{Other name-related corner cases}
-
-Mercurial has a longstanding bug in which it fails to handle a merge
-where one side has a file with a given name, while another has a
-directory with the same name.  This is documented as~\bug{29}.
-\interaction{issue29.go}
-
-\section{Recovering from mistakes}
-
-Mercurial has some useful commands that will help you to recover from
-some common mistakes.
-
-The \hgcmd{revert} command lets you undo changes that you have made to
-your working directory.  For example, if you \hgcmd{add} a file by
-accident, just run \hgcmd{revert} with the name of the file you added,
-and while the file won't be touched in any way, it won't be tracked
-for adding by Mercurial any longer, either.  You can also use
-\hgcmd{revert} to get rid of erroneous changes to a file.
-
-It's useful to remember that the \hgcmd{revert} command is useful for
-changes that you have not yet committed.  Once you've committed a
-change, if you decide it was a mistake, you can still do something
-about it, though your options may be more limited.
-
-For more information about the \hgcmd{revert} command, and details
-about how to deal with changes you have already committed, see
-chapter~\ref{chap:undo}.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/auto-snippets.xml	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,236 @@
+<!ENTITY ch06-apache-config.lst SYSTEM "results/ch06-apache-config.lst.lxo">
+<!ENTITY ch10-bugzilla-config.lst SYSTEM "results/ch10-bugzilla-config.lst.lxo">
+<!ENTITY ch10-notify-config-mail.lst SYSTEM "results/ch10-notify-config-mail.lst.lxo">
+<!ENTITY ch10-notify-config.lst SYSTEM "results/ch10-notify-config.lst.lxo">
+<!ENTITY interaction.backout.init SYSTEM "results/backout.init.lxo">
+<!ENTITY interaction.backout.manual.backout SYSTEM "results/backout.manual.backout.lxo">
+<!ENTITY interaction.backout.manual.cat SYSTEM "results/backout.manual.cat.lxo">
+<!ENTITY interaction.backout.manual.clone SYSTEM "results/backout.manual.clone.lxo">
+<!ENTITY interaction.backout.manual.heads SYSTEM "results/backout.manual.heads.lxo">
+<!ENTITY interaction.backout.manual.log SYSTEM "results/backout.manual.log.lxo">
+<!ENTITY interaction.backout.manual.merge SYSTEM "results/backout.manual.merge.lxo">
+<!ENTITY interaction.backout.manual.parents SYSTEM "results/backout.manual.parents.lxo">
+<!ENTITY interaction.backout.non-tip.backout SYSTEM "results/backout.non-tip.backout.lxo">
+<!ENTITY interaction.backout.non-tip.cat SYSTEM "results/backout.non-tip.cat.lxo">
+<!ENTITY interaction.backout.non-tip.clone SYSTEM "results/backout.non-tip.clone.lxo">
+<!ENTITY interaction.backout.simple SYSTEM "results/backout.simple.lxo">
+<!ENTITY interaction.backout.simple.log SYSTEM "results/backout.simple.log.lxo">
+<!ENTITY interaction.bisect.commits SYSTEM "results/bisect.commits.lxo">
+<!ENTITY interaction.bisect.help SYSTEM "results/bisect.help.lxo">
+<!ENTITY interaction.bisect.init SYSTEM "results/bisect.init.lxo">
+<!ENTITY interaction.bisect.search.bad-init SYSTEM "results/bisect.search.bad-init.lxo">
+<!ENTITY interaction.bisect.search.good-init SYSTEM "results/bisect.search.good-init.lxo">
+<!ENTITY interaction.bisect.search.init SYSTEM "results/bisect.search.init.lxo">
+<!ENTITY interaction.bisect.search.mytest SYSTEM "results/bisect.search.mytest.lxo">
+<!ENTITY interaction.bisect.search.reset SYSTEM "results/bisect.search.reset.lxo">
+<!ENTITY interaction.bisect.search.rest SYSTEM "results/bisect.search.rest.lxo">
+<!ENTITY interaction.bisect.search.step1 SYSTEM "results/bisect.search.step1.lxo">
+<!ENTITY interaction.bisect.search.step2 SYSTEM "results/bisect.search.step2.lxo">
+<!ENTITY interaction.branch-named.branch SYSTEM "results/branch-named.branch.lxo">
+<!ENTITY interaction.branch-named.branches SYSTEM "results/branch-named.branches.lxo">
+<!ENTITY interaction.branch-named.commit SYSTEM "results/branch-named.commit.lxo">
+<!ENTITY interaction.branch-named.create SYSTEM "results/branch-named.create.lxo">
+<!ENTITY interaction.branch-named.foo-commit SYSTEM "results/branch-named.foo-commit.lxo">
+<!ENTITY interaction.branch-named.merge SYSTEM "results/branch-named.merge.lxo">
+<!ENTITY interaction.branch-named.parents SYSTEM "results/branch-named.parents.lxo">
+<!ENTITY interaction.branch-named.rebranch SYSTEM "results/branch-named.rebranch.lxo">
+<!ENTITY interaction.branch-named.status SYSTEM "results/branch-named.status.lxo">
+<!ENTITY interaction.branch-named.update-bar SYSTEM "results/branch-named.update-bar.lxo">
+<!ENTITY interaction.branch-named.update-nothing SYSTEM "results/branch-named.update-nothing.lxo">
+<!ENTITY interaction.branch-named.update-switchy SYSTEM "results/branch-named.update-switchy.lxo">
+<!ENTITY interaction.branch-repo.bugfix SYSTEM "results/branch-repo.bugfix.lxo">
+<!ENTITY interaction.branch-repo.clone SYSTEM "results/branch-repo.clone.lxo">
+<!ENTITY interaction.branch-repo.merge SYSTEM "results/branch-repo.merge.lxo">
+<!ENTITY interaction.branch-repo.new SYSTEM "results/branch-repo.new.lxo">
+<!ENTITY interaction.branch-repo.pull SYSTEM "results/branch-repo.pull.lxo">
+<!ENTITY interaction.branch-repo.tag SYSTEM "results/branch-repo.tag.lxo">
+<!ENTITY interaction.branching.clone SYSTEM "results/branching.clone.lxo">
+<!ENTITY interaction.branching.init SYSTEM "results/branching.init.lxo">
+<!ENTITY interaction.branching.main SYSTEM "results/branching.main.lxo">
+<!ENTITY interaction.branching.merge SYSTEM "results/branching.merge.lxo">
+<!ENTITY interaction.branching.stable SYSTEM "results/branching.stable.lxo">
+<!ENTITY interaction.branching.tag SYSTEM "results/branching.tag.lxo">
+<!ENTITY interaction.branching.update SYSTEM "results/branching.update.lxo">
+<!ENTITY interaction.ch04-resolve.cifail SYSTEM "results/ch04-resolve.cifail.lxo">
+<!ENTITY interaction.ch04-resolve.export SYSTEM "results/ch04-resolve.export.lxo">
+<!ENTITY interaction.ch04-resolve.heads SYSTEM "results/ch04-resolve.heads.lxo">
+<!ENTITY interaction.ch04-resolve.init SYSTEM "results/ch04-resolve.init.lxo">
+<!ENTITY interaction.ch04-resolve.left SYSTEM "results/ch04-resolve.left.lxo">
+<!ENTITY interaction.ch04-resolve.list SYSTEM "results/ch04-resolve.list.lxo">
+<!ENTITY interaction.ch04-resolve.merge SYSTEM "results/ch04-resolve.merge.lxo">
+<!ENTITY interaction.ch04-resolve.pull SYSTEM "results/ch04-resolve.pull.lxo">
+<!ENTITY interaction.ch04-resolve.right SYSTEM "results/ch04-resolve.right.lxo">
+<!ENTITY interaction.cmdref.diff-p SYSTEM "results/cmdref.diff-p.lxo">
+<!ENTITY interaction.daily.copy.after SYSTEM "results/daily.copy.after.lxo">
+<!ENTITY interaction.daily.copy.cat SYSTEM "results/daily.copy.cat.lxo">
+<!ENTITY interaction.daily.copy.clone SYSTEM "results/daily.copy.clone.lxo">
+<!ENTITY interaction.daily.copy.copy SYSTEM "results/daily.copy.copy.lxo">
+<!ENTITY interaction.daily.copy.dir-dest SYSTEM "results/daily.copy.dir-dest.lxo">
+<!ENTITY interaction.daily.copy.dir-src SYSTEM "results/daily.copy.dir-src.lxo">
+<!ENTITY interaction.daily.copy.dir-src-dest SYSTEM "results/daily.copy.dir-src-dest.lxo">
+<!ENTITY interaction.daily.copy.init SYSTEM "results/daily.copy.init.lxo">
+<!ENTITY interaction.daily.copy.merge SYSTEM "results/daily.copy.merge.lxo">
+<!ENTITY interaction.daily.copy.other SYSTEM "results/daily.copy.other.lxo">
+<!ENTITY interaction.daily.copy.simple SYSTEM "results/daily.copy.simple.lxo">
+<!ENTITY interaction.daily.copy.status SYSTEM "results/daily.copy.status.lxo">
+<!ENTITY interaction.daily.copy.status-copy SYSTEM "results/daily.copy.status-copy.lxo">
+<!ENTITY interaction.daily.files.add SYSTEM "results/daily.files.add.lxo">
+<!ENTITY interaction.daily.files.add-dir SYSTEM "results/daily.files.add-dir.lxo">
+<!ENTITY interaction.daily.files.addremove SYSTEM "results/daily.files.addremove.lxo">
+<!ENTITY interaction.daily.files.commit-addremove SYSTEM "results/daily.files.commit-addremove.lxo">
+<!ENTITY interaction.daily.files.hidden SYSTEM "results/daily.files.hidden.lxo">
+<!ENTITY interaction.daily.files.missing SYSTEM "results/daily.files.missing.lxo">
+<!ENTITY interaction.daily.files.recover-missing SYSTEM "results/daily.files.recover-missing.lxo">
+<!ENTITY interaction.daily.files.remove SYSTEM "results/daily.files.remove.lxo">
+<!ENTITY interaction.daily.files.remove-after SYSTEM "results/daily.files.remove-after.lxo">
+<!ENTITY interaction.daily.rename.rename SYSTEM "results/daily.rename.rename.lxo">
+<!ENTITY interaction.daily.rename.status SYSTEM "results/daily.rename.status.lxo">
+<!ENTITY interaction.daily.rename.status-copy SYSTEM "results/daily.rename.status-copy.lxo">
+<!ENTITY interaction.daily.revert.add SYSTEM "results/daily.revert.add.lxo">
+<!ENTITY interaction.daily.revert.copy SYSTEM "results/daily.revert.copy.lxo">
+<!ENTITY interaction.daily.revert.missing SYSTEM "results/daily.revert.missing.lxo">
+<!ENTITY interaction.daily.revert.modify SYSTEM "results/daily.revert.modify.lxo">
+<!ENTITY interaction.daily.revert.remove SYSTEM "results/daily.revert.remove.lxo">
+<!ENTITY interaction.daily.revert.rename SYSTEM "results/daily.revert.rename.lxo">
+<!ENTITY interaction.daily.revert.rename-orig SYSTEM "results/daily.revert.rename-orig.lxo">
+<!ENTITY interaction.daily.revert.status SYSTEM "results/daily.revert.status.lxo">
+<!ENTITY interaction.daily.revert.unmodify SYSTEM "results/daily.revert.unmodify.lxo">
+<!ENTITY interaction.extdiff.diff SYSTEM "results/extdiff.diff.lxo">
+<!ENTITY interaction.extdiff.extdiff SYSTEM "results/extdiff.extdiff.lxo">
+<!ENTITY interaction.extdiff.extdiff-ctx SYSTEM "results/extdiff.extdiff-ctx.lxo">
+<!ENTITY interaction.filenames.dirs SYSTEM "results/filenames.dirs.lxo">
+<!ENTITY interaction.filenames.files SYSTEM "results/filenames.files.lxo">
+<!ENTITY interaction.filenames.filter.exclude SYSTEM "results/filenames.filter.exclude.lxo">
+<!ENTITY interaction.filenames.filter.include SYSTEM "results/filenames.filter.include.lxo">
+<!ENTITY interaction.filenames.glob.group SYSTEM "results/filenames.glob.group.lxo">
+<!ENTITY interaction.filenames.glob.question SYSTEM "results/filenames.glob.question.lxo">
+<!ENTITY interaction.filenames.glob.range SYSTEM "results/filenames.glob.range.lxo">
+<!ENTITY interaction.filenames.glob.star SYSTEM "results/filenames.glob.star.lxo">
+<!ENTITY interaction.filenames.glob.star-starstar SYSTEM "results/filenames.glob.star-starstar.lxo">
+<!ENTITY interaction.filenames.glob.starstar SYSTEM "results/filenames.glob.starstar.lxo">
+<!ENTITY interaction.filenames.wdir-relname SYSTEM "results/filenames.wdir-relname.lxo">
+<!ENTITY interaction.filenames.wdir-subdir SYSTEM "results/filenames.wdir-subdir.lxo">
+<!ENTITY interaction.hook.msglen.go SYSTEM "results/hook.msglen.go.lxo">
+<!ENTITY interaction.hook.simple.ext SYSTEM "results/hook.simple.ext.lxo">
+<!ENTITY interaction.hook.simple.init SYSTEM "results/hook.simple.init.lxo">
+<!ENTITY interaction.hook.simple.pretxncommit SYSTEM "results/hook.simple.pretxncommit.lxo">
+<!ENTITY interaction.hook.ws.better SYSTEM "results/hook.ws.better.lxo">
+<!ENTITY interaction.hook.ws.simple SYSTEM "results/hook.ws.simple.lxo">
+<!ENTITY interaction.issue29.go SYSTEM "results/issue29.go.lxo">
+<!ENTITY interaction.mq.dodiff.diff SYSTEM "results/mq.dodiff.diff.lxo">
+<!ENTITY interaction.mq.guards.init SYSTEM "results/mq.guards.init.lxo">
+<!ENTITY interaction.mq.guards.qguard SYSTEM "results/mq.guards.qguard.lxo">
+<!ENTITY interaction.mq.guards.qguard.neg SYSTEM "results/mq.guards.qguard.neg.lxo">
+<!ENTITY interaction.mq.guards.qguard.pos SYSTEM "results/mq.guards.qguard.pos.lxo">
+<!ENTITY interaction.mq.guards.qselect.cat SYSTEM "results/mq.guards.qselect.cat.lxo">
+<!ENTITY interaction.mq.guards.qselect.error SYSTEM "results/mq.guards.qselect.error.lxo">
+<!ENTITY interaction.mq.guards.qselect.foo SYSTEM "results/mq.guards.qselect.foo.lxo">
+<!ENTITY interaction.mq.guards.qselect.foobar SYSTEM "results/mq.guards.qselect.foobar.lxo">
+<!ENTITY interaction.mq.guards.qselect.qpush SYSTEM "results/mq.guards.qselect.qpush.lxo">
+<!ENTITY interaction.mq.guards.qselect.quux SYSTEM "results/mq.guards.qselect.quux.lxo">
+<!ENTITY interaction.mq.guards.series SYSTEM "results/mq.guards.series.lxo">
+<!ENTITY interaction.mq.id.lxoput SYSTEM "results/mq.id.lxoput.lxo">
+<!ENTITY interaction.mq.id.output SYSTEM "results/mq.id.output.lxo">
+<!ENTITY interaction.mq.qinit-help.help SYSTEM "results/mq.qinit-help.help.lxo">
+<!ENTITY interaction.mq.tarball.download SYSTEM "results/mq.tarball.download.lxo">
+<!ENTITY interaction.mq.tarball.newsource SYSTEM "results/mq.tarball.newsource.lxo">
+<!ENTITY interaction.mq.tarball.qinit SYSTEM "results/mq.tarball.qinit.lxo">
+<!ENTITY interaction.mq.tarball.repush SYSTEM "results/mq.tarball.repush.lxo">
+<!ENTITY interaction.mq.tools.lsdiff SYSTEM "results/mq.tools.lsdiff.lxo">
+<!ENTITY interaction.mq.tools.tools SYSTEM "results/mq.tools.tools.lxo">
+<!ENTITY interaction.mq.tutorial.add SYSTEM "results/mq.tutorial.add.lxo">
+<!ENTITY interaction.mq.tutorial.qinit SYSTEM "results/mq.tutorial.qinit.lxo">
+<!ENTITY interaction.mq.tutorial.qnew SYSTEM "results/mq.tutorial.qnew.lxo">
+<!ENTITY interaction.mq.tutorial.qnew2 SYSTEM "results/mq.tutorial.qnew2.lxo">
+<!ENTITY interaction.mq.tutorial.qpop SYSTEM "results/mq.tutorial.qpop.lxo">
+<!ENTITY interaction.mq.tutorial.qpush-a SYSTEM "results/mq.tutorial.qpush-a.lxo">
+<!ENTITY interaction.mq.tutorial.qrefresh SYSTEM "results/mq.tutorial.qrefresh.lxo">
+<!ENTITY interaction.mq.tutorial.qrefresh2 SYSTEM "results/mq.tutorial.qrefresh2.lxo">
+<!ENTITY interaction.mq.tutorial.qseries SYSTEM "results/mq.tutorial.qseries.lxo">
+<!ENTITY interaction.rename.divergent.clone SYSTEM "results/rename.divergent.clone.lxo">
+<!ENTITY interaction.rename.divergent.merge SYSTEM "results/rename.divergent.merge.lxo">
+<!ENTITY interaction.rename.divergent.rename.anne SYSTEM "results/rename.divergent.rename.anne.lxo">
+<!ENTITY interaction.rename.divergent.rename.bob SYSTEM "results/rename.divergent.rename.bob.lxo">
+<!ENTITY interaction.rollback.add SYSTEM "results/rollback.add.lxo">
+<!ENTITY interaction.rollback.commit SYSTEM "results/rollback.commit.lxo">
+<!ENTITY interaction.rollback.rollback SYSTEM "results/rollback.rollback.lxo">
+<!ENTITY interaction.rollback.status SYSTEM "results/rollback.status.lxo">
+<!ENTITY interaction.rollback.tip SYSTEM "results/rollback.tip.lxo">
+<!ENTITY interaction.rollback.twice SYSTEM "results/rollback.twice.lxo">
+<!ENTITY interaction.tag.init SYSTEM "results/tag.init.lxo">
+<!ENTITY interaction.tag.log SYSTEM "results/tag.log.lxo">
+<!ENTITY interaction.tag.log.v1.0 SYSTEM "results/tag.log.v1.0.lxo">
+<!ENTITY interaction.tag.remove SYSTEM "results/tag.remove.lxo">
+<!ENTITY interaction.tag.replace SYSTEM "results/tag.replace.lxo">
+<!ENTITY interaction.tag.tag SYSTEM "results/tag.tag.lxo">
+<!ENTITY interaction.tag.tags SYSTEM "results/tag.tags.lxo">
+<!ENTITY interaction.tag.tip SYSTEM "results/tag.tip.lxo">
+<!ENTITY interaction.template.simple.changelog SYSTEM "results/template.simple.changelog.lxo">
+<!ENTITY interaction.template.simple.combine SYSTEM "results/template.simple.combine.lxo">
+<!ENTITY interaction.template.simple.compact SYSTEM "results/template.simple.compact.lxo">
+<!ENTITY interaction.template.simple.datekeyword SYSTEM "results/template.simple.datekeyword.lxo">
+<!ENTITY interaction.template.simple.keywords SYSTEM "results/template.simple.keywords.lxo">
+<!ENTITY interaction.template.simple.manyfilters SYSTEM "results/template.simple.manyfilters.lxo">
+<!ENTITY interaction.template.simple.normal SYSTEM "results/template.simple.normal.lxo">
+<!ENTITY interaction.template.simple.rev SYSTEM "results/template.simple.rev.lxo">
+<!ENTITY interaction.template.simple.simplest SYSTEM "results/template.simple.simplest.lxo">
+<!ENTITY interaction.template.simple.simplesub SYSTEM "results/template.simple.simplesub.lxo">
+<!ENTITY interaction.template.svnstyle.id SYSTEM "results/template.svnstyle.id.lxo">
+<!ENTITY interaction.template.svnstyle.result SYSTEM "results/template.svnstyle.result.lxo">
+<!ENTITY interaction.template.svnstyle.short SYSTEM "results/template.svnstyle.short.lxo">
+<!ENTITY interaction.template.svnstyle.simplest SYSTEM "results/template.svnstyle.simplest.lxo">
+<!ENTITY interaction.template.svnstyle.style SYSTEM "results/template.svnstyle.style.lxo">
+<!ENTITY interaction.template.svnstyle.syntax.error SYSTEM "results/template.svnstyle.syntax.error.lxo">
+<!ENTITY interaction.template.svnstyle.syntax.input SYSTEM "results/template.svnstyle.syntax.input.lxo">
+<!ENTITY interaction.template.svnstyle.template SYSTEM "results/template.svnstyle.template.lxo">
+<!ENTITY interaction.tour-merge-conflict.commit SYSTEM "results/tour-merge-conflict.commit.lxo">
+<!ENTITY interaction.tour-merge-conflict.cousin SYSTEM "results/tour-merge-conflict.cousin.lxo">
+<!ENTITY interaction.tour-merge-conflict.merge SYSTEM "results/tour-merge-conflict.merge.lxo">
+<!ENTITY interaction.tour-merge-conflict.pull SYSTEM "results/tour-merge-conflict.pull.lxo">
+<!ENTITY interaction.tour-merge-conflict.son SYSTEM "results/tour-merge-conflict.son.lxo">
+<!ENTITY interaction.tour-merge-conflict.wife SYSTEM "results/tour-merge-conflict.wife.lxo">
+<!ENTITY interaction.tour.cat1 SYSTEM "results/tour.cat1.lxo">
+<!ENTITY interaction.tour.cat2 SYSTEM "results/tour.cat2.lxo">
+<!ENTITY interaction.tour.clone SYSTEM "results/tour.clone.lxo">
+<!ENTITY interaction.tour.clone-pull SYSTEM "results/tour.clone-pull.lxo">
+<!ENTITY interaction.tour.clone-push SYSTEM "results/tour.clone-push.lxo">
+<!ENTITY interaction.tour.commit SYSTEM "results/tour.commit.lxo">
+<!ENTITY interaction.tour.diff SYSTEM "results/tour.diff.lxo">
+<!ENTITY interaction.tour.help SYSTEM "results/tour.help.lxo">
+<!ENTITY interaction.tour.incoming SYSTEM "results/tour.incoming.lxo">
+<!ENTITY interaction.tour.log SYSTEM "results/tour.log.lxo">
+<!ENTITY interaction.tour.log-r SYSTEM "results/tour.log-r.lxo">
+<!ENTITY interaction.tour.log-v SYSTEM "results/tour.log-v.lxo">
+<!ENTITY interaction.tour.log-vp SYSTEM "results/tour.log-vp.lxo">
+<!ENTITY interaction.tour.log.range SYSTEM "results/tour.log.range.lxo">
+<!ENTITY interaction.tour.ls SYSTEM "results/tour.ls.lxo">
+<!ENTITY interaction.tour.ls-a SYSTEM "results/tour.ls-a.lxo">
+<!ENTITY interaction.tour.lxogoing SYSTEM "results/tour.lxogoing.lxo">
+<!ENTITY interaction.tour.lxogoing.net SYSTEM "results/tour.lxogoing.net.lxo">
+<!ENTITY interaction.tour.merge.cat SYSTEM "results/tour.merge.cat.lxo">
+<!ENTITY interaction.tour.merge.clone SYSTEM "results/tour.merge.clone.lxo">
+<!ENTITY interaction.tour.merge.commit SYSTEM "results/tour.merge.commit.lxo">
+<!ENTITY interaction.tour.merge.dummy1 SYSTEM "results/tour.merge.dummy1.lxo">
+<!ENTITY interaction.tour.merge.dummy2 SYSTEM "results/tour.merge.dummy2.lxo">
+<!ENTITY interaction.tour.merge.dummy3 SYSTEM "results/tour.merge.dummy3.lxo">
+<!ENTITY interaction.tour.merge.dummy4 SYSTEM "results/tour.merge.dummy4.lxo">
+<!ENTITY interaction.tour.merge.heads SYSTEM "results/tour.merge.heads.lxo">
+<!ENTITY interaction.tour.merge.merge SYSTEM "results/tour.merge.merge.lxo">
+<!ENTITY interaction.tour.merge.parents SYSTEM "results/tour.merge.parents.lxo">
+<!ENTITY interaction.tour.merge.pull SYSTEM "results/tour.merge.pull.lxo">
+<!ENTITY interaction.tour.merge.tip SYSTEM "results/tour.merge.tip.lxo">
+<!ENTITY interaction.tour.merge.update SYSTEM "results/tour.merge.update.lxo">
+<!ENTITY interaction.tour.older SYSTEM "results/tour.older.lxo">
+<!ENTITY interaction.tour.outgoing SYSTEM "results/tour.outgoing.lxo">
+<!ENTITY interaction.tour.outgoing.net SYSTEM "results/tour.outgoing.net.lxo">
+<!ENTITY interaction.tour.parents SYSTEM "results/tour.parents.lxo">
+<!ENTITY interaction.tour.pull SYSTEM "results/tour.pull.lxo">
+<!ENTITY interaction.tour.push SYSTEM "results/tour.push.lxo">
+<!ENTITY interaction.tour.push.net SYSTEM "results/tour.push.net.lxo">
+<!ENTITY interaction.tour.push.nothing SYSTEM "results/tour.push.nothing.lxo">
+<!ENTITY interaction.tour.reclone SYSTEM "results/tour.reclone.lxo">
+<!ENTITY interaction.tour.sed SYSTEM "results/tour.sed.lxo">
+<!ENTITY interaction.tour.status SYSTEM "results/tour.status.lxo">
+<!ENTITY interaction.tour.tip SYSTEM "results/tour.tip.lxo">
+<!ENTITY interaction.tour.update SYSTEM "results/tour.update.lxo">
+<!ENTITY interaction.tour.version SYSTEM "results/tour.version.lxo">
--- a/en/examples/backout.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg init myrepo}
-$ \textbf{cd myrepo}
-$ \textbf{echo first change >> myfile}
-$ \textbf{hg add myfile}
-$ \textbf{hg commit -m 'first change'}
-$ \textbf{echo second change >> myfile}
-$ \textbf{hg commit -m 'second change'}
--- a/en/examples/backout.manual.backout.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{echo third change >> myfile}
-$ \textbf{hg commit -m 'third change'}
-$ \textbf{hg backout -m 'back out second change' 1}
-reverting myfile
-changeset  backs out changeset 
-the backout changeset is a new head - do not forget to merge
-(use "backout --merge" if you want to auto-merge)
--- a/en/examples/backout.manual.cat.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cat myfile}
-first change
--- a/en/examples/backout.manual.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone -r1 myrepo newrepo}
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 2 changes to 1 files
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd newrepo}
--- a/en/examples/backout.manual.heads.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg heads}
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     back out second change
-
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     third change
-
--- a/en/examples/backout.manual.log.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg log --style compact}
-3[tip]:1   
-  back out second change
-
-2   
-  third change
-
-1   
-  second change
-
-0   
-  first change
-
--- a/en/examples/backout.manual.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg merge}
-merging myfile
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{hg commit -m 'merged backout with previous tip'}
-$ \textbf{cat myfile}
-first change
-third change
--- a/en/examples/backout.manual.parents.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg parents}
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     back out second change
-
--- a/en/examples/backout.non-tip.backout.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{echo third change >> myfile}
-$ \textbf{hg commit -m 'third change'}
-$ \textbf{hg backout --merge -m 'back out second change' 1}
-reverting myfile
-changeset  backs out changeset 
-merging with changeset 
-merging myfile
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
--- a/en/examples/backout.non-tip.cat.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cat myfile}
-first change
-third change
--- a/en/examples/backout.non-tip.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone -r1 myrepo non-tip-repo}
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 2 changes to 1 files
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd non-tip-repo}
--- a/en/examples/backout.simple.log.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{hg log --style compact}
-2[tip]   
-  back out second change
-
-1   
-  second change
-
-0   
-  first change
-
--- a/en/examples/backout.simple.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg backout -m 'back out second change' tip}
-reverting myfile
-changeset  backs out changeset 
-$ \textbf{cat myfile}
-first change
--- a/en/examples/bisect	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/bisect	Tue Apr 21 00:36:40 2009 +0900
@@ -1,7 +1,11 @@
 #!/bin/bash
 
+if  hg -v | head -1 | grep -e "version 0.*"
+then
+#On mercurial 1.0 and later bisect is a builtin
 echo '[extensions]' >> $HGRC
 echo 'hbisect =' >> $HGRC
+fi
 
 # XXX There's some kind of horrible nondeterminism in the execution of
 # bisect at the moment.  Ugh.
@@ -33,15 +37,15 @@
 
 #$ name: search.init
 
-hg bisect --init
+hg bisect init
 
 #$ name: search.bad-init
 
-hg bisect --bad
+hg bisect bad
 
 #$ name: search.good-init
 
-hg bisect --good 10
+hg bisect good 10
 
 #$ name: search.step1
 
@@ -66,7 +70,7 @@
   fi
 
   echo this revision is $result
-  hg bisect --$result
+  hg bisect $result
 }
   
 #$ name: search.step2
@@ -81,7 +85,7 @@
 
 #$ name: search.reset
 
-hg bisect --reset
+hg bisect reset
 
 #$ name:
 
--- a/en/examples/bisect.commits.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.help.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/bisect.search.bad-init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
--- a/en/examples/bisect.search.good-init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-
-
-
--- a/en/examples/bisect.search.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.search.mytest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.search.reset.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
--- a/en/examples/bisect.search.rest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.search.step1.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/bisect.search.step2.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
--- a/en/examples/branch-named	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/branch-named	Tue Apr 21 00:36:40 2009 +0900
@@ -64,11 +64,10 @@
 #$ name: update-bar
 
 hg update bar
-hg update -C bar
 
 #$ name: merge
 
 hg branch
-hg merge
+hg merge foo
 hg commit -m 'Merge'
 hg tip
--- a/en/examples/branch-named.branch.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg branch}
-default
--- a/en/examples/branch-named.branches.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Initial commit
-
-$ \textbf{hg branches}
-default                        
--- a/en/examples/branch-named.commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{echo 'hello again' >> myfile}
-$ \textbf{hg commit -m 'Second commit'}
-$ \textbf{hg tip}
-changeset:   
-branch:      foo
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Second commit
-
--- a/en/examples/branch-named.create.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg branch foo}
-marked working directory as branch foo
-$ \textbf{hg branch}
-foo
--- a/en/examples/branch-named.foo-commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-$ \textbf{echo something > somefile}
-$ \textbf{hg commit -A -m 'New file'}
-adding somefile
-$ \textbf{hg heads}
-changeset:   
-branch:      foo
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     New file
-
-changeset:   
-branch:      bar
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Third commit
-
--- a/en/examples/branch-named.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$ \textbf{hg branch}
-bar
-$ \textbf{hg merge}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{hg commit -m 'Merge'}
-$ \textbf{hg tip}
-changeset:   
-branch:      bar
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Merge
-
--- a/en/examples/branch-named.parents.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{hg parents}
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Third commit
-
-$ \textbf{hg branches}
-bar                            
-foo                             (inactive)
-default                         (inactive)
--- a/en/examples/branch-named.rebranch.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-$ \textbf{hg branch}
-foo
-$ \textbf{hg branch bar}
-marked working directory as branch bar
-$ \textbf{echo new file > newfile}
-$ \textbf{hg commit -A -m 'Third commit'}
-adding newfile
-$ \textbf{hg tip}
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Third commit
-
--- a/en/examples/branch-named.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg status}
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Initial commit
-
--- a/en/examples/branch-named.update-bar.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg update bar}
-abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
-$ \textbf{hg update -C bar}
-1 files updated, 0 files merged, 1 files removed, 0 files unresolved
--- a/en/examples/branch-named.update-foo.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg update foo}
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{hg update}
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{hg parents}
-changeset:   
-branch:      foo
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Second commit
-
-$ \textbf{hg update bar}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/branch-named.update-nothing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg update foo}
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{hg update}
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/branch-named.update-switchy.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-$ \textbf{hg update foo}
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{hg parents}
-changeset:   
-branch:      foo
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Second commit
-
-$ \textbf{hg update bar}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{hg parents}
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Third commit
-
--- a/en/examples/branch-named.update.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg update foo}
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{hg update}
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{hg parent}
-changeset:   
-branch:      foo
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Second commit
-
-$ \textbf{hg update bar}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/branch-repo.bugfix.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{hg clone myproject-1.0.1 my-1.0.1-bugfix}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd my-1.0.1-bugfix}
-$ \textbf{echo 'I fixed a bug using only echo!' >> myfile}
-$ \textbf{hg commit -m 'Important fix for 1.0.1'}
-$ \textbf{hg push}
-pushing to /tmp/branch-repo4rF-PL/myproject-1.0.1
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
--- a/en/examples/branch-repo.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone myproject myproject-1.0.1}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/branch-repo.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{hg merge}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{hg commit -m 'Merge bugfix from 1.0.1 branch'}
-$ \textbf{hg push}
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 1 changes to 1 files
--- a/en/examples/branch-repo.new.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone myproject my-feature}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd my-feature}
-$ \textbf{echo 'This sure is an exciting new feature!' > mynewfile}
-$ \textbf{hg commit -A -m 'New feature'}
-adding mynewfile
-$ \textbf{hg push}
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
--- a/en/examples/branch-repo.pull.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone myproject myproject-merge}
-3 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd myproject-merge}
-$ \textbf{hg pull ../myproject-1.0.1}
-pulling from ../myproject-1.0.1
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-(run 'hg heads' to see heads, 'hg merge' to merge)
--- a/en/examples/branch-repo.tag.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cd myproject}
-$ \textbf{hg tag v1.0}
--- a/en/examples/branching.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone -rv1.0 main stable}
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/branching.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg init main}
-$ \textbf{cd main}
-$ \textbf{echo 'This is a boring feature.' > myfile}
-$ \textbf{hg commit -A -m 'We have reached an important milestone!'}
-adding myfile
--- a/en/examples/branching.main.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{cd ../main}
-$ \textbf{echo 'This is exciting and new!' >> myfile}
-$ \textbf{hg commit -m 'Add a new feature'}
-$ \textbf{cat myfile}
-This is a boring feature.
-This is exciting and new!
--- a/en/examples/branching.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-$ \textbf{cd ../main}
-$ \textbf{hg pull ../stable}
-pulling from ../stable
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-(run 'hg heads' to see heads, 'hg merge' to merge)
-$ \textbf{hg merge}
-merging myfile
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{hg commit -m 'Bring in bugfix from stable branch'}
-$ \textbf{cat myfile}
-This is a fix to a boring feature.
-This is exciting and new!
--- a/en/examples/branching.stable.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{hg clone stable stable-fix}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd stable-fix}
-$ \textbf{echo 'This is a fix to a boring feature.' > myfile}
-$ \textbf{hg commit -m 'Fix a bug'}
-$ \textbf{hg push}
-pushing to /tmp/branchingfJgZac/stable
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
--- a/en/examples/branching.tag.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{hg tag v1.0}
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added tag v1.0 for changeset 
-
-$ \textbf{hg tags}
-tip                                
-v1.0                               
--- a/en/examples/branching.update.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone -U main main-old}
-$ \textbf{cd main-old}
-$ \textbf{hg update v1.0}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cat myfile}
-This is a boring feature.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch04/resolve	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,38 @@
+#$ name: init
+hg init conflict
+cd conflict
+echo first > myfile.txt
+hg ci -A -m first
+cd ..
+hg clone conflict left
+hg clone conflict right
+
+#$ name: left
+cd left
+echo left >> myfile.txt
+hg ci -m left
+
+#$ name: right
+cd ../right
+echo right >> myfile.txt
+hg ci -m right
+
+#$ name: pull
+cd ../conflict
+hg pull -u ../left
+hg pull -u ../right
+
+#$ name: heads
+hg heads
+
+#$ name: export
+export HGMERGE=merge
+
+#$ name: merge
+hg merge
+
+#$ name: cifail
+hg commit -m 'Attempt to commit a failed merge'
+
+#$ name: list
+hg resolve -l
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch06/apache-config.lst	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,11 @@
+<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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch10/bugzilla-config.lst	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,14 @@
+[bugzilla]
+host = bugzilla.example.com
+password = mypassword version = 2.16
+# server-side repos live in /home/hg/repos, so strip 4 leading
+# separators
+strip = 4
+hgweb = http://hg.example.com/
+usermap = /home/hg/repos/notify/bugzilla.conf
+template = Changeset {node|short}, made by {author} in the {webroot}
+  repo, refers to this bug.\n
+  For complete details, see
+  {hgweb}{webroot}?cmd=changeset;node={node|short}\n
+  Changeset description:\n
+  \t{desc|tabindent}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch10/notify-config-mail.lst	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,18 @@
+X-Hg-Repo: tests/slave
+Subject: tests/slave: Handle error case when slave has no buffers
+Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
+
+changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
+
+details:
+http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 
+
+description: Handle error case when slave has no buffers
+
+diffs (54 lines):
+diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
+--- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
++++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
+@@ -212,6 +212,15 @@ static __inline__
+void test_headers(void *h)
+[...snip...]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/ch10/notify-config.lst	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,19 @@
+[notify]
+# really send email
+test = false
+# subscriber data lives in the notify repo
+config = /home/hg/repos/notify/notify.conf
+# repos live in /home/hg/repos on server, so strip 4 "/" chars
+strip = 4
+template = X-Hg-Repo: {webroot}\n
+  Subject: {webroot}: {desc|firstline|strip}\n
+  From: {author}
+  \n\n
+  changeset {node|short} in {root}
+  \n\ndetails:
+  {baseurl}{webroot}?cmd=changeset;node={node|short}
+  description: {desc|tabindent|strip}
+
+[web]
+baseurl =
+http://hg.example.com/
--- a/en/examples/cmdref.diff-p.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-$ \textbf{echo '[diff]' >> $HGRC}
-$ \textbf{echo 'showfunc = False' >> $HGRC}
-$ \textbf{hg diff}
-diff -r  myfile.c
-
-
-@@ -1,4 +1,4 @@
- int myfunc()
- \{
--    return 1;
-+    return 10;
- \}
-$ \textbf{hg diff -p}
-diff -r  myfile.c
-
-
-@@ -1,4 +1,4 @@ int myfunc()
- int myfunc()
- \{
--    return 1;
-+    return 10;
- \}
--- a/en/examples/daily.copy.after.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cp a z}
-$ \textbf{hg copy --after a z}
--- a/en/examples/daily.copy.cat.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{cat file}
-line
-new contents
-$ \textbf{cat ../my-copy/new-file}
-line
--- a/en/examples/daily.copy.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone my-copy your-copy}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/daily.copy.copy.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cd my-copy}
-$ \textbf{hg copy file new-file}
--- a/en/examples/daily.copy.dir-dest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{mkdir d}
-$ \textbf{hg copy a b d}
-$ \textbf{ls d}
-a  b
--- a/en/examples/daily.copy.dir-src-dest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg copy c d}
-copying c/a/c to d/c/a/c
--- a/en/examples/daily.copy.dir-src.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg copy c e}
-copying c/a/c to e/a/c
--- a/en/examples/daily.copy.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg init my-copy}
-$ \textbf{cd my-copy}
-$ \textbf{echo line > file}
-$ \textbf{hg add file}
-$ \textbf{hg commit -m 'Added a file'}
--- a/en/examples/daily.copy.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-$ \textbf{hg pull ../my-copy}
-pulling from ../my-copy
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-(run 'hg heads' to see heads, 'hg merge' to merge)
-$ \textbf{hg merge}
-merging file and new-file
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{cat new-file}
-line
-new contents
--- a/en/examples/daily.copy.other.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ../your-copy}
-$ \textbf{echo 'new contents' >> file}
-$ \textbf{hg commit -m 'Changed file'}
--- a/en/examples/daily.copy.simple.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{mkdir k}
-$ \textbf{hg copy a k}
-$ \textbf{ls k}
-a
--- a/en/examples/daily.copy.status-copy.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg status -C}
-A new-file
-  file
-$ \textbf{hg commit -m 'Copied file'}
--- a/en/examples/daily.copy.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg status}
-A new-file
--- a/en/examples/daily.files	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/daily.files	Tue Apr 21 00:36:40 2009 +0900
@@ -4,9 +4,9 @@
 
 hg init add-example
 cd add-example
-echo a > a
+echo a > myfile.txt
 hg status
-hg add a
+hg add myfile.txt
 hg status
 hg commit -m 'Added one file'
 hg status
@@ -14,10 +14,10 @@
 #$ name: add-dir
 
 mkdir b
-echo b > b/b
-echo c > b/c
+echo b > b/somefile.txt
+echo c > b/source.cpp
 mkdir b/d
-echo d > b/d/d
+echo d > b/d/test.h
 hg add b
 hg commit -m 'Added all files in subdirectory'
 
--- a/en/examples/daily.files.add-dir.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{mkdir b}
-$ \textbf{echo b > b/b}
-$ \textbf{echo c > b/c}
-$ \textbf{mkdir b/d}
-$ \textbf{echo d > b/d/d}
-$ \textbf{hg add b}
-adding b/b
-adding b/c
-adding b/d/d
-$ \textbf{hg commit -m 'Added all files in subdirectory'}
--- a/en/examples/daily.files.add.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{hg init add-example}
-$ \textbf{cd add-example}
-$ \textbf{echo a > a}
-$ \textbf{hg status}
-? a
-$ \textbf{hg add a}
-$ \textbf{hg status}
-A a
-$ \textbf{hg commit -m 'Added one file'}
-$ \textbf{hg status}
--- a/en/examples/daily.files.addremove.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg init addremove-example}
-$ \textbf{cd addremove-example}
-$ \textbf{echo a > a}
-$ \textbf{echo b > b}
-$ \textbf{hg addremove}
-adding a
-adding b
--- a/en/examples/daily.files.commit-addremove.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{echo c > c}
-$ \textbf{hg commit -A -m 'Commit with addremove'}
-adding c
--- a/en/examples/daily.files.hidden.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg init hidden-example}
-$ \textbf{cd hidden-example}
-$ \textbf{mkdir empty}
-$ \textbf{touch empty/.hidden}
-$ \textbf{hg add empty/.hidden}
-$ \textbf{hg commit -m 'Manage an empty-looking directory'}
-$ \textbf{ls empty}
-$ \textbf{cd ..}
-$ \textbf{hg clone hidden-example tmp}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{ls tmp}
-empty
-$ \textbf{ls tmp/empty}
--- a/en/examples/daily.files.missing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg init missing-example}
-$ \textbf{cd missing-example}
-$ \textbf{echo a > a}
-$ \textbf{hg add a}
-$ \textbf{hg commit -m 'File about to be missing'}
-$ \textbf{rm a}
-$ \textbf{hg status}
-! a
--- a/en/examples/daily.files.recover-missing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg revert a}
-$ \textbf{cat a}
-a
-$ \textbf{hg status}
--- a/en/examples/daily.files.remove-after.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg remove --after a}
-$ \textbf{hg status}
-R a
--- a/en/examples/daily.files.remove.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg init remove-example}
-$ \textbf{cd remove-example}
-$ \textbf{echo a > a}
-$ \textbf{mkdir b}
-$ \textbf{echo b > b/b}
-$ \textbf{hg add a b}
-adding b/b
-$ \textbf{hg commit -m 'Small example for file removal'}
-$ \textbf{hg remove a}
-$ \textbf{hg status}
-R a
-$ \textbf{hg remove b}
-removing b/b
--- a/en/examples/daily.rename.rename.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg rename a b}
--- a/en/examples/daily.rename.status-copy.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg status -C}
-A b
-  a
-R a
--- a/en/examples/daily.rename.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg status}
-A b
-R a
--- a/en/examples/daily.revert.add.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{echo oops > oops}
-$ \textbf{hg add oops}
-$ \textbf{hg status oops}
-A oops
-$ \textbf{hg revert oops}
-$ \textbf{hg status}
-? oops
--- a/en/examples/daily.revert.copy.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg copy file new-file}
-$ \textbf{hg revert new-file}
-$ \textbf{hg status}
-? new-file
--- a/en/examples/daily.revert.missing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{rm file}
-$ \textbf{hg status}
-! file
-$ \textbf{hg revert file}
-$ \textbf{ls file}
-file
--- a/en/examples/daily.revert.modify.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cat file}
-original content
-$ \textbf{echo unwanted change >> file}
-$ \textbf{hg diff file}
-diff -r  file
-
-
-@@ -1,1 +1,2 @@ original content
- original content
-+unwanted change
--- a/en/examples/daily.revert.remove.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg remove file}
-$ \textbf{hg status}
-R file
-$ \textbf{hg revert file}
-$ \textbf{hg status}
-$ \textbf{ls file}
-file
--- a/en/examples/daily.revert.rename-orig.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg revert file}
-no changes needed to file
-$ \textbf{hg status}
-? new-file
--- a/en/examples/daily.revert.rename.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg rename file new-file}
-$ \textbf{hg revert new-file}
-$ \textbf{hg status}
-? new-file
--- a/en/examples/daily.revert.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg status}
-? file.orig
-$ \textbf{cat file.orig}
-original content
-unwanted change
--- a/en/examples/daily.revert.unmodify.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg status}
-M file
-$ \textbf{hg revert file}
-$ \textbf{cat file}
-original content
--- a/en/examples/extdiff.diff.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg diff}
-diff -r  myfile
-
-
-@@ -1,1 +1,2 @@ The first line.
- The first line.
-+The second line.
--- a/en/examples/extdiff.extdiff-ctx.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg extdiff -o -NprcC5}
-
-
-***************
-*** 1 ****
-
-  The first line.
-+ The second line.
--- a/en/examples/extdiff.extdiff.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{hg extdiff}
-
-
-@@ -1 +1,2 @@
- The first line.
-+The second line.
--- a/en/examples/filenames.dirs.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg status src}
-? src/main.py
-? src/watcher/_watcher.c
-? src/watcher/watcher.py
-? src/xyzzy.txt
--- a/en/examples/filenames.files.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg add COPYING README examples/simple.py}
--- a/en/examples/filenames.filter.exclude.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg status -X '**.py' src}
-? src/watcher/_watcher.c
-? src/xyzzy.txt
--- a/en/examples/filenames.filter.include.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg status -I '*.in'}
-? MANIFEST.in
--- a/en/examples/filenames.glob.group.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg status 'glob:*.\{in,py\}'}
-? MANIFEST.in
-? setup.py
--- a/en/examples/filenames.glob.question.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg status 'glob:**.?'}
-? src/watcher/_watcher.c
--- a/en/examples/filenames.glob.range.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg status 'glob:**[nr-t]'}
-? MANIFEST.in
-? src/xyzzy.txt
--- a/en/examples/filenames.glob.star-starstar.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg status 'glob:*.py'}
-? setup.py
-$ \textbf{hg status 'glob:**.py'}
-A examples/simple.py
-A src/main.py
-? examples/performant.py
-? setup.py
-? src/watcher/watcher.py
--- a/en/examples/filenames.glob.star.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg add 'glob:*.py'}
-adding main.py
--- a/en/examples/filenames.glob.starstar.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg status 'glob:**.py'}
-A examples/simple.py
-A src/main.py
-? examples/performant.py
-? setup.py
-? src/watcher/watcher.py
--- a/en/examples/filenames.wdir-relname.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-$ \textbf{hg status}
-A COPYING
-A README
-A examples/simple.py
-? MANIFEST.in
-? examples/performant.py
-? setup.py
-? src/main.py
-? src/watcher/_watcher.c
-? src/watcher/watcher.py
-? src/xyzzy.txt
-$ \textbf{hg status `hg root`}
-A ../COPYING
-A ../README
-A ../examples/simple.py
-? ../MANIFEST.in
-? ../examples/performant.py
-? ../setup.py
-? main.py
-? watcher/_watcher.c
-? watcher/watcher.py
-? xyzzy.txt
--- a/en/examples/filenames.wdir-subdir.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-$ \textbf{cd src}
-$ \textbf{hg add -n}
-adding ../MANIFEST.in
-adding ../examples/performant.py
-adding ../setup.py
-adding main.py
-adding watcher/_watcher.c
-adding watcher/watcher.py
-adding xyzzy.txt
-$ \textbf{hg add -n .}
-adding main.py
-adding watcher/_watcher.c
-adding watcher/watcher.py
-adding xyzzy.txt
--- a/en/examples/hook.msglen.go.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cat .hg/hgrc}
-[hooks]
-pretxncommit.msglen = test `hg tip --template \{desc\} | wc -c` -ge 10
-$ \textbf{echo a > a}
-$ \textbf{hg add a}
-$ \textbf{hg commit -A -m 'too short'}
-transaction abort!
-rollback completed
-abort: pretxncommit.msglen hook exited with status 1
-$ \textbf{hg commit -A -m 'long enough'}
--- a/en/examples/hook.msglen.run.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cat .hg/hgrc}
-[hooks]
-pretxncommit.msglen = test `hg tip --template \{desc\} | wc -c` -ge 10
-$ \textbf{echo a > a}
-$ \textbf{hg add a}
-$ \textbf{hg commit -A -m 'too short'}
-abort: pretxncommit.msglen hook exited with status 1
-transaction abort!
-rollback completed
-$ \textbf{hg commit -A -m 'long enough'}
--- a/en/examples/hook.simple.ext.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{echo 'commit.when = echo -n "date of commit: "; date' >> .hg/hgrc}
-$ \textbf{echo a >> a}
-$ \textbf{hg commit -m 'i have two hooks'}
-committed 
-
--- a/en/examples/hook.simple.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{hg init hook-test}
-$ \textbf{cd hook-test}
-$ \textbf{echo '[hooks]' >> .hg/hgrc}
-$ \textbf{echo 'commit = echo committed $HG_NODE' >> .hg/hgrc}
-$ \textbf{cat .hg/hgrc}
-[hooks]
-commit = echo committed $HG_NODE
-$ \textbf{echo a > a}
-$ \textbf{hg add a}
-$ \textbf{hg commit -m 'testing commit hook'}
-committed 
--- a/en/examples/hook.simple.pretxncommit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{cat check_bug_id}
-#!/bin/sh
-# check that a commit comment mentions a numeric bug id
-hg log -r $1 --template \{desc\} | grep -q "\textbackslash{}<bug *[0-9]"
-$ \textbf{echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' >> .hg/hgrc}
-$ \textbf{echo a >> a}
-$ \textbf{hg commit -m 'i am not mentioning a bug id'}
-transaction abort!
-rollback completed
-abort: pretxncommit.bug_id_required hook exited with status 1
-$ \textbf{hg commit -m 'i refer you to bug 666'}
-committed 
-
--- a/en/examples/hook.ws.better.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-$ \textbf{cat .hg/hgrc}
-[hooks]
-pretxncommit.whitespace = .hg/check_whitespace.py
-$ \textbf{echo 'a ' >> a}
-$ \textbf{hg commit -A -m 'add new line with trailing whitespace'}
-a, line 2: trailing whitespace added
-commit message saved to .hg/commit.save
-transaction abort!
-rollback completed
-abort: pretxncommit.whitespace hook exited with status 1
-$ \textbf{sed -i 's, *$,,' a}
-$ \textbf{hg commit -A -m 'trimmed trailing whitespace'}
-a, line 2: trailing whitespace added
-commit message saved to .hg/commit.save
-transaction abort!
-rollback completed
-abort: pretxncommit.whitespace hook exited with status 1
--- a/en/examples/hook.ws.simple.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{cat .hg/hgrc}
-[hooks]
-pretxncommit.whitespace = hg export tip | (! egrep -q '^\textbackslash{}+.*[ \textbackslash{}t]$')
-$ \textbf{echo 'a ' > a}
-$ \textbf{hg commit -A -m 'test with trailing whitespace'}
-adding a
-transaction abort!
-rollback completed
-abort: pretxncommit.whitespace hook exited with status 1
-$ \textbf{echo 'a' > a}
-$ \textbf{hg commit -A -m 'drop trailing whitespace and try again'}
--- a/en/examples/issue29.go.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$ \textbf{hg init issue29}
-$ \textbf{cd issue29}
-$ \textbf{echo a > a}
-$ \textbf{hg ci -Ama}
-adding a
-$ \textbf{echo b > b}
-$ \textbf{hg ci -Amb}
-adding b
-$ \textbf{hg up 0}
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{mkdir b}
-$ \textbf{echo b > b/b}
-$ \textbf{hg ci -Amc}
-adding b/b
-$ \textbf{hg merge}
-
--- a/en/examples/mq.dodiff.diff.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{echo 'this is my original thought' > oldfile}
-$ \textbf{echo 'i have changed my mind' > newfile}
-$ \textbf{diff -u oldfile newfile > tiny.patch}
-$ \textbf{cat tiny.patch}
-
-
-@@ -1 +1 @@
--this is my original thought
-+i have changed my mind
-$ \textbf{patch < tiny.patch}
-patching file oldfile
-$ \textbf{cat oldfile}
-i have changed my mind
--- a/en/examples/mq.guards.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg qinit}
-$ \textbf{hg qnew hello.patch}
-$ \textbf{echo hello > hello}
-$ \textbf{hg add hello}
-$ \textbf{hg qrefresh}
-$ \textbf{hg qnew goodbye.patch}
-$ \textbf{echo goodbye > goodbye}
-$ \textbf{hg add goodbye}
-$ \textbf{hg qrefresh}
--- a/en/examples/mq.guards.qguard.neg.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg qguard hello.patch -quux}
-$ \textbf{hg qguard hello.patch}
-hello.patch: -quux
--- a/en/examples/mq.guards.qguard.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg qguard}
-goodbye.patch: unguarded
--- a/en/examples/mq.guards.qguard.pos.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg qguard +foo}
-$ \textbf{hg qguard}
-goodbye.patch: +foo
--- a/en/examples/mq.guards.qselect.cat.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cat .hg/patches/guards}
-foo
--- a/en/examples/mq.guards.qselect.error.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg qselect +foo}
-abort: guard '+foo' starts with invalid character: '+'
--- a/en/examples/mq.guards.qselect.foo.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg qpop -a}
-Patch queue now empty
-$ \textbf{hg qselect}
-no active guards
-$ \textbf{hg qselect foo}
-number of unguarded, unapplied patches has changed from 1 to 2
-$ \textbf{hg qselect}
-foo
--- a/en/examples/mq.guards.qselect.foobar.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg qselect foo bar}
-number of unguarded, unapplied patches has changed from 0 to 2
-$ \textbf{hg qpop -a}
-no patches applied
-$ \textbf{hg qpush -a}
-applying hello.patch
-applying goodbye.patch
-Now at: goodbye.patch
--- a/en/examples/mq.guards.qselect.qpush.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg qpush -a}
-applying hello.patch
-applying goodbye.patch
-Now at: goodbye.patch
--- a/en/examples/mq.guards.qselect.quux.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{hg qselect quux}
-number of guarded, applied patches has changed from 0 to 2
-$ \textbf{hg qpop -a}
-Patch queue now empty
-$ \textbf{hg qpush -a}
-patch series already fully applied
--- a/en/examples/mq.guards.series.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cat .hg/patches/series}
-hello.patch #-quux
-goodbye.patch #+foo
--- a/en/examples/mq.id.out.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-$ \textbf{hg qapplied}
-first.patch
-second.patch
-$ \textbf{hg log -r qbase:qtip}
-changeset:   
-tag:         first.patch
-tag:         qbase
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     patch queue: first.patch
-
-changeset:   
-tag:         second.patch
-tag:         qtip
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     patch queue: second.patch
-
-$ \textbf{hg export second.patch}
-# HG changeset patch
-# User Bryan O'Sullivan <bos@serpentine.com>
-
-# Node ID 
-# Parent  
-patch queue: second.patch
-
-diff -r  -r  other.c
-
-
-@@ -0,0 +1,1 @@
-+double u;
--- a/en/examples/mq.id.output.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-$ \textbf{hg qapplied}
-first.patch
-second.patch
-$ \textbf{hg log -r qbase:qtip}
-changeset:   
-tag:         first.patch
-tag:         qbase
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     [mq]: first.patch
-
-changeset:   
-tag:         qtip
-tag:         second.patch
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     [mq]: second.patch
-
-$ \textbf{hg export second.patch}
-# HG changeset patch
-# User Bryan O'Sullivan <bos@serpentine.com>
-
-# Node ID 
-# Parent  
-[mq]: second.patch
-
-diff -r  -r  other.c
-
-
-@@ -0,0 +1,1 @@
-+double u;
--- a/en/examples/mq.qinit-help.help.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$ \textbf{hg help qinit}
-hg qinit [-c]
-
-init a new queue repository
-
-    The queue repository is unversioned by default. If -c is
-    specified, qinit will create a separate nested repository
-    for patches (qinit -c may also be run later to convert
-    an unversioned patch repository into a versioned one).
-    You can use qcommit to commit changes to this queue repository.
-
-options:
-
- -c --create-repo  create queue repository
-
-use "hg -v help qinit" to show global options
--- a/en/examples/mq.tarball.download.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{download netplug-1.2.5.tar.bz2}
-$ \textbf{tar jxf netplug-1.2.5.tar.bz2}
-$ \textbf{cd netplug-1.2.5}
-$ \textbf{hg init}
-$ \textbf{hg commit -q --addremove --message netplug-1.2.5}
-$ \textbf{cd ..}
-$ \textbf{hg clone netplug-1.2.5 netplug}
-18 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/mq.tarball.newsource.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{hg qpop -a}
-Patch queue now empty
-$ \textbf{cd ..}
-$ \textbf{download netplug-1.2.8.tar.bz2}
-$ \textbf{hg clone netplug-1.2.5 netplug-1.2.8}
-18 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd netplug-1.2.8}
-$ \textbf{hg locate -0 | xargs -0 rm}
-$ \textbf{cd ..}
-$ \textbf{tar jxf netplug-1.2.8.tar.bz2}
-$ \textbf{cd netplug-1.2.8}
-$ \textbf{hg commit --addremove --message netplug-1.2.8}
--- a/en/examples/mq.tarball.qinit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-$ \textbf{cd netplug}
-$ \textbf{hg qinit}
-$ \textbf{hg qnew -m 'fix build problem with gcc 4' build-fix.patch}
-$ \textbf{perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c}
-$ \textbf{hg qrefresh}
-$ \textbf{hg tip -p}
-changeset:   
-tag:         qtip
-tag:         build-fix.patch
-tag:         tip
-tag:         qbase
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     fix build problem with gcc 4
-
-diff -r  -r  netlink.c
-
-
-@@ -275,7 +275,7 @@ netlink_open(void)
-         exit(1);
-     \}
- 
--    int addr_len = sizeof(addr);
-+    socklen_t addr_len = sizeof(addr);
- 
-     if (getsockname(fd, (struct sockaddr *) &addr, &addr_len) == -1) \{
-         do_log(LOG_ERR, "Could not get socket details: %m");
-
--- a/en/examples/mq.tarball.repush.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{cd ../netplug}
-$ \textbf{hg pull ../netplug-1.2.8}
-pulling from ../netplug-1.2.8
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 12 changes to 12 files
-(run 'hg update' to get a working copy)
-$ \textbf{hg qpush -a}
-applying build-fix.patch
-Now at: build-fix.patch
--- a/en/examples/mq.tools.lsdiff.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-$ \textbf{lsdiff -nvv remove-redundant-null-checks.patch}
-22	File #1  	a/drivers/char/agp/sgi-agp.c
-	24	Hunk #1	static int __devinit agp_sgi_init(void)
-37	File #2  	a/drivers/char/hvcs.c
-	39	Hunk #1	static struct tty_operations hvcs_ops = 
-	53	Hunk #2	static int hvcs_alloc_index_list(int n)
-69	File #3  	a/drivers/message/fusion/mptfc.c
-	71	Hunk #1	mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in
-85	File #4  	a/drivers/message/fusion/mptsas.c
-	87	Hunk #1	mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
-98	File #5  	a/drivers/net/fs_enet/fs_enet-mii.c
-	100	Hunk #1	static struct fs_enet_mii_bus *create_bu
-111	File #6  	a/drivers/net/wireless/ipw2200.c
-	113	Hunk #1	static struct ipw_fw_error *ipw_alloc_er
-	126	Hunk #2	static ssize_t clear_error(struct device
-	140	Hunk #3	static void ipw_irq_tasklet(struct ipw_p
-	150	Hunk #4	static void ipw_pci_remove(struct pci_de
-164	File #7  	a/drivers/scsi/libata-scsi.c
-	166	Hunk #1	int ata_cmd_ioctl(struct scsi_device *sc
-178	File #8  	a/drivers/video/au1100fb.c
-	180	Hunk #1	void __exit au1100fb_cleanup(void)
--- a/en/examples/mq.tools.tools.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-$ \textbf{diffstat -p1 remove-redundant-null-checks.patch}
- drivers/char/agp/sgi-agp.c        |    5 ++---
- drivers/char/hvcs.c               |   11 +++++------
- drivers/message/fusion/mptfc.c    |    6 ++----
- drivers/message/fusion/mptsas.c   |    3 +--
- drivers/net/fs_enet/fs_enet-mii.c |    3 +--
- drivers/net/wireless/ipw2200.c    |   22 ++++++----------------
- drivers/scsi/libata-scsi.c        |    4 +---
- drivers/video/au1100fb.c          |    3 +--
- 8 files changed, 19 insertions(+), 38 deletions(-)
-$ \textbf{filterdiff -i '*/video/*' remove-redundant-null-checks.patch}
-
-
-@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void)
- \{
- 	driver_unregister(&au1100fb_driver);
- 
--	if (drv_info.opt_mode)
--		kfree(drv_info.opt_mode);
-+	kfree(drv_info.opt_mode);
- \}
- 
- module_init(au1100fb_init);
--- a/en/examples/mq.tutorial.add.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{echo 'file 3, line 1' >> file3}
-$ \textbf{hg qnew add-file3.patch}
-$ \textbf{hg qnew -f add-file3.patch}
-abort: patch "add-file3.patch" already exists
--- a/en/examples/mq.tutorial.qinit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg init mq-sandbox}
-$ \textbf{cd mq-sandbox}
-$ \textbf{echo 'line 1' > file1}
-$ \textbf{echo 'another line 1' > file2}
-$ \textbf{hg add file1 file2}
-$ \textbf{hg commit -m'first change'}
-$ \textbf{hg qinit}
--- a/en/examples/mq.tutorial.qnew.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     first change
-
-$ \textbf{hg qnew first.patch}
-$ \textbf{hg tip}
-changeset:   
-tag:         qtip
-tag:         first.patch
-tag:         tip
-tag:         qbase
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     [mq]: first.patch
-
-$ \textbf{ls .hg/patches}
-first.patch  series  status
--- a/en/examples/mq.tutorial.qnew2.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-$ \textbf{hg qnew second.patch}
-$ \textbf{hg log --style=compact --limit=2}
-2[qtip,second.patch,tip]   
-  [mq]: second.patch
-
-1[first.patch,qbase]   
-  [mq]: first.patch
-
-$ \textbf{echo 'line 4' >> file1}
-$ \textbf{hg qrefresh}
-$ \textbf{hg tip --style=compact --patch}
-2[qtip,second.patch,tip]   
-  [mq]: second.patch
-
-diff -r  -r  file1
-
-
-@@ -1,3 +1,4 @@ line 1
- line 1
- line 2
- line 3
-+line 4
-
-$ \textbf{hg annotate file1}
-0: line 1
-1: line 2
-1: line 3
-2: line 4
--- a/en/examples/mq.tutorial.qpop.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-$ \textbf{hg qapplied}
-first.patch
-second.patch
-$ \textbf{hg qpop}
-Now at: first.patch
-$ \textbf{hg qseries}
-first.patch
-second.patch
-$ \textbf{hg qapplied}
-first.patch
-$ \textbf{cat file1}
-line 1
-line 2
-line 3
--- a/en/examples/mq.tutorial.qpush-a.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg qpush -a}
-applying second.patch
-Now at: second.patch
-$ \textbf{cat file1}
-line 1
-line 2
-line 3
-line 4
--- a/en/examples/mq.tutorial.qrefresh.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-$ \textbf{echo 'line 2' >> file1}
-$ \textbf{hg diff}
-diff -r  file1
-
-
-@@ -1,1 +1,2 @@ line 1
- line 1
-+line 2
-$ \textbf{hg qrefresh}
-$ \textbf{hg diff}
-$ \textbf{hg tip --style=compact --patch}
-1[qtip,first.patch,tip,qbase]   
-  [mq]: first.patch
-
-diff -r  -r  file1
-
-
-@@ -1,1 +1,2 @@ line 1
- line 1
-+line 2
-
--- a/en/examples/mq.tutorial.qrefresh2.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$ \textbf{echo 'line 3' >> file1}
-$ \textbf{hg status}
-M file1
-$ \textbf{hg qrefresh}
-$ \textbf{hg tip --style=compact --patch}
-1[qtip,first.patch,tip,qbase]   
-  [mq]: first.patch
-
-diff -r  -r  file1
-
-
-@@ -1,1 +1,3 @@ line 1
- line 1
-+line 2
-+line 3
-
--- a/en/examples/mq.tutorial.qseries.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{hg qseries}
-first.patch
-second.patch
-$ \textbf{hg qapplied}
-first.patch
-second.patch
--- a/en/examples/rename.divergent	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/rename.divergent	Tue Apr 21 00:36:40 2009 +0900
@@ -14,7 +14,7 @@
 #$ name: rename.anne
 
 cd anne
-hg mv foo bar
+hg rename foo bar
 hg ci -m 'Rename foo to bar'
 
 #$ name: rename.bob
--- a/en/examples/rename.divergent.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg clone orig anne}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{hg clone orig bob}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/rename.divergent.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-# See http://www.selenic.com/mercurial/bts/issue455
-$ \textbf{cd ../orig}
-$ \textbf{hg pull -u ../anne}
-pulling from ../anne
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-$ \textbf{hg pull ../bob}
-pulling from ../bob
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-(run 'hg heads' to see heads, 'hg merge' to merge)
-$ \textbf{hg merge}
-warning: detected divergent renames of foo to:
- bar
- quux
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ \textbf{ls}
-bar  quux
--- a/en/examples/rename.divergent.rename.anne.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd anne}
-$ \textbf{hg mv foo bar}
-$ \textbf{hg ci -m 'Rename foo to bar'}
--- a/en/examples/rename.divergent.rename.bob.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ../bob}
-$ \textbf{hg mv foo quux}
-$ \textbf{hg ci -m 'Rename foo to quux'}
--- a/en/examples/rollback.add.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg add b}
-$ \textbf{hg commit -m 'Add file b, this time for real'}
--- a/en/examples/rollback.commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg status}
-M a
-$ \textbf{echo b > b}
-$ \textbf{hg commit -m 'Add file b'}
--- a/en/examples/rollback.rollback.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-$ \textbf{hg rollback}
-rolling back last transaction
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     First commit
-
-$ \textbf{hg status}
-M a
-? b
--- a/en/examples/rollback.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg status}
-? b
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Add file b
-
--- a/en/examples/rollback.twice.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg rollback}
-rolling back last transaction
-$ \textbf{hg rollback}
-no rollback information available
--- a/en/examples/run-example	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/run-example	Tue Apr 21 00:36:40 2009 +0900
@@ -7,6 +7,7 @@
 import cStringIO
 import errno
 import getopt
+import glob
 import os
 import pty
 import re
@@ -18,23 +19,23 @@
 import tempfile
 import time
 
-tex_subs = {
-    '\\': '\\textbackslash{}',
-    '{': '\\{',
-    '}': '\\}',
+xml_subs = {
+    '<': '&lt;',
+    '>': '&gt;',
+    '&': '&amp;',
     }
 
 def gensubs(s):
     start = 0
     for i, c in enumerate(s):
-        sub = tex_subs.get(c)
+        sub = xml_subs.get(c)
         if sub:
             yield s[start:i]
             start = i + 1
             yield sub
     yield s[start:]
 
-def tex_escape(s):
+def xml_escape(s):
     return ''.join(gensubs(s))
         
 def maybe_unlink(name):
@@ -53,7 +54,92 @@
             return p
     return None
         
+def result_name(name):
+    return os.path.normpath(os.path.join('results', name.replace(os.sep, '-')))
+
+def wopen(name):
+    path = os.path.dirname(name)
+    if path:
+        try:
+            os.makedirs(path)
+        except OSError, err:
+            if err.errno != errno.EEXIST:
+                raise
+    return open(name, 'w')
+
 class example:
+    entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml'))
+
+    def __init__(self, name, verbose, keep_change):
+        self.name = os.path.normpath(name)
+        self.verbose = verbose
+        self.keep_change = keep_change
+        
+    def status(self, s):
+        sys.stdout.write(s)
+        if not s.endswith('\n'):
+            sys.stdout.flush()
+
+    def rename_output(self, base, ignore=[]):
+        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
+        def mangle(s):
+            return mangle_re.sub('', s)
+        def matchfp(fp1, fp2):
+            while True:
+                s1 = mangle(fp1.readline())
+                s2 = mangle(fp2.readline())
+                if cmp(s1, s2):
+                    break
+                if not s1:
+                    return True
+            return False
+
+        oldname = result_name(base + '.out')
+        tmpname = result_name(base + '.tmp')
+        errname = result_name(base + '.err')
+        errfp = open(errname, 'w+')
+        for line in open(tmpname):
+            errfp.write(mangle_re.sub('', line))
+        os.rename(tmpname, result_name(base + '.lxo'))
+        errfp.seek(0)
+        try:
+            oldfp = open(oldname)
+        except IOError, err:
+            if err.errno != errno.ENOENT:
+                raise
+            os.rename(errname, oldname)
+            return False
+        if matchfp(oldfp, errfp):
+            os.unlink(errname)
+            return False
+        else:
+            print >> sys.stderr, '\nOutput of %s has changed!' % base
+            if self.keep_change:
+                os.rename(errname, oldname)
+                return False
+            else:
+                os.system('diff -u %s %s 1>&2' % (oldname, errname))
+            return True
+
+class static_example(example):
+    def run(self):
+        self.status('running %s\n' % self.name)
+        s = open(self.name).read().rstrip()
+        s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
+        ofp = wopen(result_name(self.name + '.tmp'))
+        ofp.write('<!-- BEGIN %s -->\n' % self.name)
+        ofp.write('<programlisting>')
+        ofp.write(s)
+        ofp.write('</programlisting>\n')
+        ofp.write('<!-- END %s -->\n' % self.name)
+        ofp.close()
+        self.rename_output(self.name)
+        norm = self.name.replace(os.sep, '-')
+        example.entities[
+            '<!ENTITY %s SYSTEM "results/%s.lxo">' % (norm, norm)] = 1
+
+
+class shell_example(example):
     shell = '/usr/bin/env bash'
     ps1 = '__run_example_ps1__ '
     ps2 = '__run_example_ps2__ '
@@ -61,9 +147,8 @@
     
     timeout = 10
 
-    def __init__(self, name, verbose):
-        self.name = name
-        self.verbose = verbose
+    def __init__(self, name, verbose, keep_change):
+        example.__init__(self, name, verbose, keep_change)
         self.poll = select.poll()
 
     def parse(self):
@@ -76,11 +161,6 @@
                 yield cfp.getvalue()
                 cfp.seek(0)
                 cfp.truncate()
-        
-    def status(self, s):
-        sys.stdout.write(s)
-        if not s.endswith('\n'):
-            sys.stdout.flush()
 
     def send(self, s):
         if self.verbose:
@@ -146,12 +226,12 @@
         maybe_unlink(self.name + '.run')
 
         rcfile = os.path.join(tmpdir, '.hgrc')
-        rcfp = open(rcfile, 'w')
+        rcfp = wopen(rcfile)
         print >> rcfp, '[ui]'
         print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>"
         
         rcfile = os.path.join(tmpdir, '.bashrc')
-        rcfp = open(rcfile, 'w')
+        rcfp = wopen(rcfile)
         print >> rcfp, 'PS1="%s"' % self.ps1
         print >> rcfp, 'PS2="%s"' % self.ps2
         print >> rcfp, 'unset HISTFILE'
@@ -230,12 +310,22 @@
                                 return 1
                             assert os.sep not in out
                             if ofp is not None:
+                                ofp.write('</screen>\n')
+                                ofp.write('<!-- END %s -->\n' % ofp_basename)
                                 ofp.close()
                                 err |= self.rename_output(ofp_basename, ignore)
                             if out:
                                 ofp_basename = '%s.%s' % (self.name, out)
+                                norm = os.path.normpath(ofp_basename)
+                                norm = norm.replace(os.sep, '-')
+                                example.entities[
+                                    '<!ENTITY interaction.%s '
+                                    'SYSTEM "results/%s.lxo">'
+                                    % (norm, norm)] = 1
                                 read_hint = ofp_basename + ' '
-                                ofp = open(ofp_basename + '.tmp', 'w')
+                                ofp = wopen(result_name(ofp_basename + '.tmp'))
+                                ofp.write('<!-- BEGIN %s -->\n' % ofp_basename)
+                                ofp.write('<screen>')
                             else:
                                 ofp = None
                         elif pi == 'ignore':
@@ -248,14 +338,15 @@
                         # first, print the command we ran
                         if not hunk.startswith('#'):
                             nl = hunk.endswith('\n')
-                            hunk = ('%s \\textbf{%s}' %
+                            hunk = ('<prompt>%s</prompt> '
+                                    '<userinput>%s</userinput>' %
                                     (prompts[ps],
-                                     tex_escape(hunk.rstrip('\n'))))
+                                     xml_escape(hunk.rstrip('\n'))))
                             if nl: hunk += '\n'
                         ofp.write(hunk)
                         # then its output
-                        ofp.write(tex_escape(output))
-                    ps = newps
+                        ofp.write(xml_escape(output))
+                        ps = newps
                 self.status('\n')
             except:
                 print >> sys.stderr, '(killed)'
@@ -267,6 +358,8 @@
                     ps, output = self.sendreceive('exit\n', read_hint)
                     if ofp is not None:
                         ofp.write(output)
+                        ofp.write('</screen>\n')
+                        ofp.write('<!-- END %s -->\n' % ofp_basename)
                         ofp.close()
                         err |= self.rename_output(ofp_basename, ignore)
                     os.close(self.cfd)
@@ -281,69 +374,40 @@
                     elif os.WIFSIGNALED(rc):
                         print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
                 else:
-                    open(self.name + '.run', 'w')
-#                return err
-                return 0
+                    wopen(result_name(self.name + '.run'))
+                return err
         finally:
             shutil.rmtree(tmpdir)
 
-    def rename_output(self, base, ignore):
-        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
-        def mangle(s):
-            return mangle_re.sub('', s)
-        def matchfp(fp1, fp2):
-            while True:
-                s1 = mangle(fp1.readline())
-                s2 = mangle(fp2.readline())
-                if cmp(s1, s2):
-                    break
-                if not s1:
-                    return True
-            return False
-
-        oldname = base + '.out'
-        tmpname = base + '.tmp'
-        errname = base + '.err'
-        errfp = open(errname, 'w+')
-        for line in open(tmpname):
-            errfp.write(mangle_re.sub('', line))
-        os.rename(tmpname, base + '.lxo')
-        errfp.seek(0)
-        try:
-            oldfp = open(oldname)
-        except IOError, err:
-            if err.errno != errno.ENOENT:
-                raise
-            os.rename(errname, oldname)
-            return False
-        if matchfp(oldfp, errfp):
-            os.unlink(errname)
-            return False
-        else:
-            print >> sys.stderr, '\nOutput of %s has changed!' % base
-            os.system('diff -u %s %s 1>&2' % (oldname, errname))
-            return True
-
 def print_help(exit, msg=None):
     if msg:
         print >> sys.stderr, 'Error:', msg
     print >> sys.stderr, 'Usage: run-example [options] [test...]'
     print >> sys.stderr, 'Options:'
-    print >> sys.stderr, '  -a --all       run all tests in this directory'
+    print >> sys.stderr, '  -a --all       run all examples in this directory'
     print >> sys.stderr, '  -h --help      print this help message'
+    print >> sys.stderr, '     --keep      keep new output as desired output'
     print >> sys.stderr, '  -v --verbose   display extra debug output'
     sys.exit(exit)
 
 def main(path='.'):
+    if os.path.realpath(path).split(os.sep)[-1] != 'examples':
+        print >> sys.stderr, 'Not being run from the examples directory!'
+        sys.exit(1)
+
     opts, args = getopt.getopt(sys.argv[1:], '?ahv',
-                               ['all', 'help', 'verbose'])
+                               ['all', 'help', 'keep', 'verbose'])
     verbose = False
     run_all = False
+    keep_change = False
+
     for o, a in opts:
         if o in ('-h', '-?', '--help'):
             print_help(0)
         if o in ('-a', '--all'):
             run_all = True
+        if o in ('--keep',):
+            keep_change = True
         if o in ('-v', '--verbose'):
             verbose = True
     errs = 0
@@ -355,19 +419,20 @@
                 print >> sys.stderr, '%s: %s' % (a, err.strerror)
                 errs += 1
                 continue
-            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
-                if example(a, verbose).run():
-                    errs += 1
+            if stat.S_ISREG(st.st_mode):
+                if st.st_mode & 0111:
+                    if shell_example(a, verbose, keep_change).run():
+                        errs += 1
+                elif a.endswith('.lst'):
+                    static_example(a, verbose, keep_change).run()
             else:
                 print >> sys.stderr, '%s: not a file, or not executable' % a
                 errs += 1
     elif run_all:
-        names = os.listdir(path)
+        names = glob.glob("*") + glob.glob("app*/*") + glob.glob("ch*/*")
         names.sort()
         for name in names:
-            if name == 'run-example' or name.startswith('.'): continue
-            if name.endswith('.out') or name.endswith('~'): continue
-            if name.endswith('.run'): continue
+            if name == 'run-example' or name.endswith('~'): continue
             pathname = os.path.join(path, name)
             try:
                 st = os.lstat(pathname)
@@ -376,12 +441,20 @@
                 if err.errno != errno.ENOENT:
                     raise
                 continue
-            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
-                if example(pathname, verbose).run():
-                    errs += 1
-        print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
+            if stat.S_ISREG(st.st_mode):
+                if st.st_mode & 0111:
+                    if shell_example(pathname, verbose, keep_change).run():
+                        errs += 1
+                elif pathname.endswith('.lst'):
+                    static_example(pathname, verbose, keep_change).run()
+        print >> wopen(os.path.join(path, '.run')), time.asctime()
     else:
         print_help(1, msg='no test names given, and --all not provided')
+
+    fp = wopen('auto-snippets.xml')
+    for key in sorted(example.entities.iterkeys()):
+        print >> fp, key
+    fp.close()
     return errs
 
 if __name__ == '__main__':
--- a/en/examples/tag.init.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{hg init mytag}
-$ \textbf{cd mytag}
-$ \textbf{echo hello > myfile}
-$ \textbf{hg commit -A -m 'Initial commit'}
-adding myfile
--- a/en/examples/tag.log.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg log}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added tag v1.0 for changeset 
-
-changeset:   
-tag:         v1.0
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Initial commit
-
--- a/en/examples/tag.log.v1.0.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{echo goodbye > myfile2}
-$ \textbf{hg commit -A -m 'Second commit'}
-adding myfile2
-$ \textbf{hg log -r v1.0}
-changeset:   
-tag:         v1.0
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Initial commit
-
--- a/en/examples/tag.remove.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg tag --remove v1.0}
-$ \textbf{hg tags}
-tip                                
--- a/en/examples/tag.replace.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{hg tag -r 1 v1.1}
-$ \textbf{hg tags}
-tip                                
-v1.1                               
-$ \textbf{hg tag -r 2 v1.1}
-abort: a tag named v1.1 already exists (use -f to force)
-$ \textbf{hg tag -f -r 2 v1.1}
-$ \textbf{hg tags}
-tip                                
-v1.1                               
--- a/en/examples/tag.tag.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg tag v1.0}
--- a/en/examples/tag.tags.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{hg tags}
-tip                                
-v1.0                               
--- a/en/examples/tag.tip.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added tag v1.1 for changeset 
-
--- a/en/examples/template.simple.changelog.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/template.simple.combine.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-
-
-
-
-
--- a/en/examples/template.simple.compact.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/template.simple.datekeyword.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-
-
-
--- a/en/examples/template.simple.keywords.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/template.simple.manyfilters.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/template.simple.normal.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
--- a/en/examples/template.simple.rev.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/template.simple.simplest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-
-
--- a/en/examples/template.simple.simplesub.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
--- a/en/examples/template.svnstyle	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/template.svnstyle	Tue Apr 21 00:36:40 2009 +0900
@@ -34,6 +34,7 @@
 hg log -r0 --template '{node}'
 
 #$ name: simplest
+#$ ignore: \d+-\d+-\d+ \d+:\d+ \+.*
 
 cat svn.style
 hg log -r1 --style svn.style
--- a/en/examples/template.svnstyle.id.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg log -r0 --template '\{node\}'}
--- a/en/examples/template.svnstyle.result.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{hg log -r1 --style svn.style}
-------------------------------------------------------------------------
-
-r1 | bos 
-
-added line to end of <<hello>> file.
-
-in addition, added a file with the helpful name (at least i hope that some
-might consider it so) of goodbye.
-
-------------------------------------------------------------------------
--- a/en/examples/template.svnstyle.short.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{svn log -r9653}
-------------------------------------------------------------------------
-r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines
-
-On reporting a route error, also include the status for the error,
-rather than indicating a status of 0 when an error has occurred.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-------------------------------------------------------------------------
--- a/en/examples/template.svnstyle.simplest.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{cat svn.style}
-changeset = "\{node|short\}\textbackslash{}n"
-$ \textbf{hg log -r1 --style svn.style}
-
--- a/en/examples/template.svnstyle.style.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cat svn.style}
-header = '------------------------------------------------------------------------\textbackslash{}n\textbackslash{}n'
-changeset = svn.template
--- a/en/examples/template.svnstyle.syntax.error.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg log -r1 --style broken.style}
-abort: broken.style:1: parse error
--- a/en/examples/template.svnstyle.syntax.input.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{cat broken.style}
-changeset =
--- a/en/examples/template.svnstyle.template.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{cat svn.template}
-r\{rev\} | \{author|user\} | \{date|isodate\} (\{date|rfc822date\})
-
-\{desc|strip|fill76\}
-
-------------------------------------------------------------------------
--- a/en/examples/tour	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/tour	Tue Apr 21 00:36:40 2009 +0900
@@ -31,7 +31,7 @@
 #$ name: log-r
 
 hg log -r 3
-hg log -r ff5d7b70a2a9
+hg log -r 0272e0d5a517
 hg log -r 1 -r 4
 
 #$ name: log.range
@@ -52,10 +52,17 @@
 hg clone hello my-hello
 cd my-hello
 
-#$ name: sed
+#$ name: cat1
+cat hello.c
+
+#$ name:
 
 sed -i '/printf/a\\tprintf("hello again!\\n");' hello.c
 
+#$ name: cat2
+# ... edit edit edit ...
+cat hello.c
+
 #$ name: status
 
 ls
@@ -73,6 +80,10 @@
 
 hg commit
 
+#$ name: merge.dummy1
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-hello
+
 #$ name: tip
 
 hg tip -vp
@@ -135,14 +146,23 @@
 
 hg push http://hg.serpentine.com/tutorial/hello
 
+#$ name:
+cp hello.c ../new-hello.c
+sed -i '/printf/i\\tprintf("once more, hello.\\n");' ../new-hello.c
+
 #$ name: merge.clone
 
 cd ..
 hg clone hello my-new-hello
 cd my-new-hello
-sed -i '/printf/i\\tprintf("once more, hello.\\n");' hello.c
+# The file new-hello.c is lightly edited.
+cp ../new-hello.c hello.c
 hg commit -m 'A new hello for a new day.'
 
+#$ name: merge.dummy2
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-new-hello
+
 #$ name: merge.cat
 
 cat hello.c
@@ -152,6 +172,10 @@
 
 hg pull ../my-hello
 
+#$ name: merge.dummy3
+
+hg log -r 6 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV6.my-new-hello
+
 #$ name: merge.heads
 
 hg heads
@@ -173,6 +197,10 @@
 
 hg commit -m 'Merged changes'
 
+#$ name: merge.dummy4
+
+hg log -r 7 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV7.my-new-hello
+
 #$ name: merge.tip
 
 hg tip
--- a/en/examples/tour-merge-conflict	Mon Apr 20 23:50:34 2009 +0900
+++ b/en/examples/tour-merge-conflict	Tue Apr 21 00:36:40 2009 +0900
@@ -68,5 +68,6 @@
 Nigerian dictator Sani Abacha.
 EOF
 
+hg resolve -m letter.txt
 hg commit -m 'Send me your money'
 hg tip
--- a/en/examples/tour-merge-conflict.commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-$ \textbf{cat > letter.txt <<EOF}
-> \textbf{Greetings!}
-> \textbf{I am Bryan O'Sullivan, no relation of the former}
-> \textbf{Nigerian dictator Sani Abacha.}
-> \textbf{EOF}
-$ \textbf{hg commit -m 'Send me your money'}
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Send me your money
-
--- a/en/examples/tour-merge-conflict.cousin.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone scam scam-cousin}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd scam-cousin}
-$ \textbf{cat > letter.txt <<EOF}
-> \textbf{Greetings!}
-> \textbf{I am Shehu Musa Abacha, cousin to the former}
-> \textbf{Nigerian dictator Sani Abacha.}
-> \textbf{EOF}
-$ \textbf{hg commit -m '419 scam, with cousin'}
--- a/en/examples/tour-merge-conflict.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-$ \textbf{export HGMERGE=merge}
-$ \textbf{hg merge}
-merging letter.txt
-merge: warning: conflicts during merge
-merging letter.txt failed!
-0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-There are unresolved merges, you can redo the full merge using:
-  hg update -C 1
-  hg merge 2
-$ \textbf{cat letter.txt}
-Greetings!
-
-I am Shehu Musa Abacha, cousin to the former
-=======
-I am Alhaji Abba Abacha, son of the former
-
-Nigerian dictator Sani Abacha.
--- a/en/examples/tour-merge-conflict.pull.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone scam-cousin scam-merge}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd scam-merge}
-$ \textbf{hg pull -u ../scam-son}
-pulling from ../scam-son
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-not updating, since new heads added
-(run 'hg heads' to see heads, 'hg merge' to merge)
--- a/en/examples/tour-merge-conflict.son.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone scam scam-son}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd scam-son}
-$ \textbf{cat > letter.txt <<EOF}
-> \textbf{Greetings!}
-> \textbf{I am Alhaji Abba Abacha, son of the former}
-> \textbf{Nigerian dictator Sani Abacha.}
-> \textbf{EOF}
-$ \textbf{hg commit -m '419 scam, with son'}
--- a/en/examples/tour-merge-conflict.wife.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{cat > letter.txt <<EOF}
-> \textbf{Greetings!}
-> \textbf{I am Mariam Abacha, the wife of former}
-> \textbf{Nigerian dictator Sani Abacha.}
-> \textbf{EOF}
-$ \textbf{hg add letter.txt}
-$ \textbf{hg commit -m '419 scam, first draft'}
--- a/en/examples/tour.clone-pull.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone hello hello-pull}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/tour.clone-push.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone hello hello-push}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/tour.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg clone http://hg.serpentine.com/tutorial/hello}
-destination directory: hello
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 5 changesets with 5 changes to 2 files
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/tour.commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg commit}
--- a/en/examples/tour.diff.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-$ \textbf{hg diff}
-diff -r  hello.c
-
-
-@@ -8,5 +8,6 @@ int main(int argc, char **argv)
- int main(int argc, char **argv)
- \{
- 	printf("hello, world!\textbackslash{}");
-+	printf("hello again!\textbackslash{}n");
- 	return 0;
- \}
--- a/en/examples/tour.help.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-$ \textbf{hg help init}
-hg init [-e CMD] [--remotecmd CMD] [DEST]
-
-create a new repository in the given directory
-
-    Initialize a new repository in the given directory.  If the given
-    directory does not exist, it is created.
-
-    If no directory is given, the current directory is used.
-
-    It is possible to specify an ssh:// URL as the destination.
-    Look at the help text for the pull command for important details
-    about ssh:// URLs.
-
-options:
-
- -e --ssh        specify ssh command to use
-    --remotecmd  specify hg command to run on the remote side
-
-use "hg -v help init" to show global options
--- a/en/examples/tour.incoming.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cd hello-pull}
-$ \textbf{hg incoming ../my-hello}
-comparing with ../my-hello
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
--- a/en/examples/tour.log-r.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-$ \textbf{hg log -r 3}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Get make to generate the final binary from a .o file.
-
-$ \textbf{hg log -r }
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Get make to generate the final binary from a .o file.
-
-$ \textbf{hg log -r 1 -r 4}
-changeset:   
-user:        mpm@selenic.com
-
-summary:     Create a makefile
-
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Trim comments.
-
--- a/en/examples/tour.log-v.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg log -v -r 3}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-files:       Makefile
-description:
-Get make to generate the final binary from a .o file.
-
-
--- a/en/examples/tour.log-vp.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-$ \textbf{hg log -v -p -r 2}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-files:       hello.c
-description:
-Introduce a typo into hello.c.
-
-
-diff -r  -r  hello.c
-
-
-@@ -11,6 +11,6 @@
- 
- int main(int argc, char **argv)
- \{
--	printf("hello, world!\textbackslash{}n");
-+	printf("hello, world!\textbackslash{}");
- 	return 0;
- \}
-
--- a/en/examples/tour.log.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-$ \textbf{hg log}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Trim comments.
-
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Get make to generate the final binary from a .o file.
-
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Introduce a typo into hello.c.
-
-changeset:   
-user:        mpm@selenic.com
-
-summary:     Create a makefile
-
-changeset:   
-user:        mpm@selenic.com
-
-summary:     Create a standard "hello, world" program
-
--- a/en/examples/tour.log.range.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-$ \textbf{hg log -r 2:4}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Introduce a typo into hello.c.
-
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Get make to generate the final binary from a .o file.
-
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Trim comments.
-
--- a/en/examples/tour.ls-a.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-$ \textbf{cd hello}
-$ \textbf{ls -a}
-.  ..  .hg  Makefile  hello.c
--- a/en/examples/tour.ls.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-$ \textbf{ls -l}
-total 4
-
-$ \textbf{ls hello}
-Makefile  hello.c
--- a/en/examples/tour.merge.cat.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-$ \textbf{cat hello.c}
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include <stdio.h>
-
-int main(int argc, char **argv)
-\{
-	printf("once more, hello.\textbackslash{}n");
-	printf("hello, world!\textbackslash{}");
-	return 0;
-\}
-$ \textbf{cat ../my-hello/hello.c}
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include <stdio.h>
-
-int main(int argc, char **argv)
-\{
-	printf("hello, world!\textbackslash{}");
-	printf("hello again!\textbackslash{}n");
-	return 0;
-\}
--- a/en/examples/tour.merge.clone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone hello my-new-hello}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd my-new-hello}
-$ \textbf{sed -i '/printf/i\textbackslash{}\textbackslash{}tprintf("once more, hello.\textbackslash{}\textbackslash{}n");' hello.c}
-$ \textbf{hg commit -m 'A new hello for a new day.'}
--- a/en/examples/tour.merge.commit.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{hg commit -m 'Merged changes'}
--- a/en/examples/tour.merge.heads.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-$ \textbf{hg heads}
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     A new hello for a new day.
-
--- a/en/examples/tour.merge.merge.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg merge}
-merging hello.c
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
--- a/en/examples/tour.merge.parents.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-$ \textbf{hg parents}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     A new hello for a new day.
-
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
-$ \textbf{cat hello.c}
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include <stdio.h>
-
-int main(int argc, char **argv)
-\{
-	printf("once more, hello.\textbackslash{}n");
-	printf("hello, world!\textbackslash{}");
-	printf("hello again!\textbackslash{}n");
-	return 0;
-\}
--- a/en/examples/tour.merge.pull.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-$ \textbf{hg pull ../my-hello}
-pulling from ../my-hello
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files (+1 heads)
-(run 'hg heads' to see heads, 'hg merge' to merge)
--- a/en/examples/tour.merge.tip.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Merged changes
-
--- a/en/examples/tour.merge.update.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-$ \textbf{hg update}
-abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
--- a/en/examples/tour.older.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{hg update 2}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{hg parents}
-changeset:   
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Introduce a typo into hello.c.
-
-$ \textbf{hg update}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/en/examples/tour.outgoing.net.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$ \textbf{hg outgoing http://hg.serpentine.com/tutorial/hello}
-comparing with http://hg.serpentine.com/tutorial/hello
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
--- a/en/examples/tour.outgoing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-$ \textbf{cd my-hello}
-$ \textbf{hg outgoing ../hello-push}
-comparing with ../hello-push
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
--- a/en/examples/tour.parents.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg parents}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
--- a/en/examples/tour.pull.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Trim comments.
-
-$ \textbf{hg pull ../my-hello}
-pulling from ../my-hello
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-(run 'hg update' to get a working copy)
-$ \textbf{hg tip}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-summary:     Added an extra line of output
-
--- a/en/examples/tour.push.net.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg push http://hg.serpentine.com/tutorial/hello}
-pushing to http://hg.serpentine.com/tutorial/hello
-searching for changes
-ssl required
--- a/en/examples/tour.push.nothing.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{hg push ../hello-push}
-pushing to ../hello-push
-searching for changes
-no changes found
--- a/en/examples/tour.push.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{hg push ../hello-push}
-pushing to ../hello-push
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
--- a/en/examples/tour.reclone.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{cd ..}
-$ \textbf{hg clone hello my-hello}
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{cd my-hello}
--- a/en/examples/tour.sed.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-$ \textbf{sed -i '/printf/a\textbackslash{}\textbackslash{}tprintf("hello again!\textbackslash{}\textbackslash{}n");' hello.c}
--- a/en/examples/tour.status.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-$ \textbf{ls}
-Makefile  hello.c
-$ \textbf{hg status}
-M hello.c
--- a/en/examples/tour.tip.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-$ \textbf{hg tip -vp}
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan <bos@serpentine.com>
-
-files:       hello.c
-description:
-Added an extra line of output
-
-
-diff -r  -r  hello.c
-
-
-@@ -8,5 +8,6 @@ int main(int argc, char **argv)
- int main(int argc, char **argv)
- \{
- 	printf("hello, world!\textbackslash{}");
-+	printf("hello again!\textbackslash{}n");
- 	return 0;
- \}
-
--- a/en/examples/tour.update.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-$ \textbf{grep printf hello.c}
-	printf("hello, world!\textbackslash{}");
-$ \textbf{hg update tip}
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-$ \textbf{grep printf hello.c}
-	printf("hello, world!\textbackslash{}");
-	printf("hello again!\textbackslash{}n");
--- a/en/examples/tour.version.out	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-$ \textbf{hg version}
-Mercurial Distributed SCM (version )
-
-Copyright (C) 2005-2007 Matt Mackall <mpm@selenic.com> and others
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- a/en/feature-branches.dot	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-digraph feature_branches {
-	master -> crypto;
-	master -> filesystems;
-	master -> ipc;
-	master -> memory;
-	master -> network;
-	master -> security;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/feature-branches.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+digraph feature_branches {
+	master -> crypto;
+	master -> filesystems;
+	master -> ipc;
+	master -> memory;
+	master -> network;
+	master -> security;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/filelog.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="filelog.svg"
+   sodipodi:docbase="/home/arun/hgbook/en"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective57" />
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3128"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient2887">
+      <stop
+         style="stop-color:#91cfcf;stop-opacity:1;"
+         offset="0"
+         id="stop2889" />
+      <stop
+         style="stop-color:aqua;stop-opacity:0;"
+         offset="1"
+         id="stop2891" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2795">
+      <stop
+         style="stop-color:#ccc;stop-opacity:1;"
+         offset="0"
+         id="stop2797" />
+      <stop
+         style="stop-color:#ccc;stop-opacity:0;"
+         offset="1"
+         id="stop2799" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3170"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(121.2183,94.95434)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3172"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3174"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3176"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3208"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3210"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3212"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(121.2183,94.95434)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3214"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3256"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)"
+       x1="74.301666"
+       y1="431.67441"
+       x2="260.05884"
+       y2="369.95322" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3258"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3260"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)"
+       x1="74.387527"
+       y1="431.80576"
+       x2="259.97339"
+       y2="369.82224" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3262"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="455.8122"
+     inkscape:cy="520"
+     inkscape:document-units="px"
+     inkscape:current-layer="g2940"
+     inkscape:window-width="1680"
+     inkscape:window-height="970"
+     inkscape:window-x="3"
+     inkscape:window-y="46"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3180"
+       width="273.81375"
+       height="199.06245"
+       x="369.1796"
+       y="351.79019" />
+    <rect
+       style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3178"
+       width="273.81339"
+       height="199.06233"
+       x="72.699799"
+       y="351.78983" />
+    <g
+       id="g3144"
+       transform="translate(80.467048,0.71578)">
+      <g
+         id="g2940">
+        <rect
+           style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect2914"
+           width="227.38896"
+           height="39.500999"
+           x="311.92496"
+           y="395.08627" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="323.72824"
+           y="416.7626"
+           id="text2918"><tspan
+             sodipodi:role="line"
+             id="tspan2920"
+             x="323.72824"
+             y="416.7626"
+             style="font-family:Courier">.hg/store/data/_r_e_a_d_m_e.i</tspan></text>
+      </g>
+      <g
+         transform="translate(3.79093e-5,-80.1853)"
+         id="g2945">
+        <g
+           id="g2955">
+          <rect
+             y="475.4968"
+             x="15.550935"
+             height="39.500999"
+             width="227.17694"
+             id="rect2947"
+             style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text2949"
+             y="498.35123"
+             x="31.230644"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="498.35123"
+               x="31.230644"
+               id="tspan2951"
+               sodipodi:role="line">README</tspan></text>
+        </g>
+      </g>
+      <path
+         inkscape:connector-type="polyline"
+         id="path2960"
+         d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         sodipodi:nodetypes="cz" />
+    </g>
+    <g
+       id="g3156"
+       transform="translate(80.467048,0.71578)">
+      <g
+         transform="translate(116,0)"
+         id="g2831">
+        <rect
+           style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect1906"
+           width="228.18446"
+           height="60.499123"
+           x="195.52719"
+           y="465.51859" />
+        <g
+           id="g2803"
+           transform="translate(-0.893671,1.833581)">
+          <text
+             id="text1884"
+             y="483.92801"
+             x="208.95944"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="483.92801"
+               x="208.95944"
+               id="tspan1886"
+               sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text>
+          <text
+             id="text1888"
+             y="507.79309"
+             x="208.95944"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="507.79309"
+               x="208.95944"
+               id="tspan1890"
+               sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text>
+        </g>
+      </g>
+      <g
+         id="g2907">
+        <rect
+           style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect2843"
+           width="227.17728"
+           height="39.500999"
+           x="15.550805"
+           y="475.4968" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="31.230644"
+           y="498.35123"
+           id="text2847"><tspan
+             sodipodi:role="line"
+             id="tspan2849"
+             x="31.230644"
+             y="498.35123"
+             style="font-family:Courier">src/hello.c</tspan></text>
+      </g>
+      <path
+         inkscape:connection-end="#g2831"
+         inkscape:connection-start="#g2907"
+         inkscape:connector-type="polyline"
+         id="path2962"
+         d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         sodipodi:nodetypes="cs" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="98.496666"
+       y="373.96353"
+       id="text3216"><tspan
+         sodipodi:role="line"
+         id="tspan3218"
+         x="98.496666"
+         y="373.96353">Working directory</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="391.39197"
+       y="373.96353"
+       id="text3228"><tspan
+         sodipodi:role="line"
+         id="tspan3230"
+         x="391.39197"
+         y="373.96353">Repository</tspan></text>
+  </g>
+</svg>
Binary file en/figs/kdiff3.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/metadata.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="metadata.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path2944"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="232.14286"
+     inkscape:cy="490.68696"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="181"
+     inkscape:window-y="58" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 326.94646,467.18359 L 326.94646,510.98123"
+       id="path1910"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2962"
+       inkscape:connection-start="#rect2764" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 326.94646,531.98123 L 326.94646,591.77887"
+       id="path1912"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2962"
+       inkscape:connection-end="#rect3000" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 316.1622,531.98123 L 192.30212,652.57648"
+       id="path1916"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect3038"
+       inkscape:connection-start="#rect2962" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 254.23217,467.18359 L 254.23216,510.98123"
+       id="path3088"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect1872"
+       inkscape:connection-end="#rect2960" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 254.23215,531.98123 L 254.23215,591.77887"
+       id="path3090"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2960"
+       inkscape:connection-end="#rect2998" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 248.84002,531.98123 L 186.90999,652.57648"
+       id="path3092"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2960"
+       inkscape:connection-end="#rect3038" />
+    <rect
+       style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1872"
+       width="51.42857"
+       height="20"
+       x="228.51788"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2764"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2766"
+       width="51.42857"
+       height="20"
+       x="155.80359"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2768"
+       width="51.42857"
+       height="20"
+       x="83.089294"
+       y="446.68359" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,456.68359 L 155.30359,456.68359"
+       id="path2770"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2768"
+       inkscape:connection-end="#rect2766" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,456.68359 L 228.01788,456.68359"
+       id="path2772"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2766"
+       inkscape:connection-end="#rect1872" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,456.68359 L 300.73218,456.68359"
+       id="path2774"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect1872"
+       inkscape:connection-end="#rect2764" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.303571,456.68359 L 82.589294,456.68359"
+       id="path2778"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2768" />
+    <rect
+       style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2960"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2962"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2964"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2966"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="511.48123" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,521.48121 L 155.30359,521.48121"
+       id="path2968"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,521.48121 L 228.01788,521.48121"
+       id="path2970"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,521.48121 L 300.73218,521.48121"
+       id="path2972"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,521.48121 L 82.5893,521.48121"
+       id="path2974"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2998"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3000"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3002"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3004"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="592.27887" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,602.27884 L 155.30359,602.27884"
+       id="path3006"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,602.27884 L 228.01788,602.27884"
+       id="path3008"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,602.27884 L 300.73218,602.27884"
+       id="path3010"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,602.27884 L 82.5893,602.27884"
+       id="path3012"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3034"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="653.07648" />
+    <rect
+       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3038"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="653.07648" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3040"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="653.07648" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,663.07646 L 155.30359,663.07646"
+       id="path3042"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,663.07646 L 228.01788,663.07646"
+       id="path3044"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,663.07646 L 82.5893,663.07646"
+       id="path3048"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.072548"
+       y="432.64789"
+       id="text3094"><tspan
+         sodipodi:role="line"
+         id="tspan3096"
+         x="82.072548"
+         y="432.64789">Changelog</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.306923"
+       y="498.97327"
+       id="text3098"><tspan
+         sodipodi:role="line"
+         id="tspan3100"
+         x="82.306923"
+         y="498.97327">Manifest</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.14286"
+       y="580.08569"
+       id="text3102"><tspan
+         sodipodi:role="line"
+         id="tspan3104"
+         x="82.14286"
+         y="580.08569">Filelogs</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/mq-stack.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.43"
+   sodipodi:docname="mq-stack.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4142136"
+     inkscape:cx="299.33323"
+     inkscape:cy="815.646"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1014"
+     inkscape:window-height="689"
+     inkscape:window-x="0"
+     inkscape:window-y="25" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect1307"
+       width="202.93683"
+       height="24.243662"
+       x="230.01944"
+       y="221.70146" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89606"
+       y="237.13383"
+       id="text1309"><tspan
+         sodipodi:role="line"
+         id="tspan1311"
+         x="237.89606"
+         y="237.13383">prevent-compiler-reorder.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect1320"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="251.34325" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="266.77563"
+       id="text1322"><tspan
+         sodipodi:role="line"
+         id="tspan1324"
+         x="237.89598"
+         y="266.77563">namespace-cleanup.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect2217"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="280.98505" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="296.41742"
+       id="text2219"><tspan
+         sodipodi:role="line"
+         id="tspan2221"
+         x="237.89598"
+         y="296.41742">powerpc-port-fixes.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect3114"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="310.6268" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="326.05917"
+       id="text3116"><tspan
+         sodipodi:role="line"
+         id="tspan3118"
+         x="237.89598"
+         y="326.05917">report-devinfo-correctly.patch</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="200.01021"
+       y="191.68094"
+       id="text3170"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3172"
+         x="200.01021"
+         y="191.68094"
+         style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="255.26627"
+       y="248.79449"
+       id="text3190"
+       sodipodi:linespacing="125%"
+       transform="scale(0.786716,1.271107)"><tspan
+         sodipodi:role="line"
+         id="tspan3192"
+         x="255.26627"
+         y="248.79449"
+         style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.86807"
+       y="173.17117"
+       id="text4085"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4087"
+         x="195.86807"
+         y="173.17117"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">present in series,</tspan><tspan
+         sodipodi:role="line"
+         x="195.86807"
+         y="188.17117"
+         id="tspan4089"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">but not applied</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.0712"
+       y="288.91745"
+       id="text4091"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4093"
+         x="195.0712"
+         y="288.91745"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">patches applied,</tspan><tspan
+         sodipodi:role="line"
+         x="195.0712"
+         y="303.91745"
+         id="tspan4111"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">changesets present</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.0712"
+       y="229.28813"
+       id="text4095"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4097"
+         x="195.0712"
+         y="229.28813"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">topmost</tspan><tspan
+         sodipodi:role="line"
+         x="195.0712"
+         y="244.28813"
+         id="tspan4109"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">applied patch</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.4975"
+       y="238.29692"
+       id="text4137"><tspan
+         sodipodi:role="line"
+         id="tspan4139"
+         x="450.4975"
+         y="238.29692">201ad3209902</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.05804"
+       y="267.93872"
+       id="text4141"><tspan
+         sodipodi:role="line"
+         id="tspan4143"
+         x="450.05804"
+         y="267.93872">126b84e593ae</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.6557"
+       y="297.58051"
+       id="text4145"><tspan
+         sodipodi:role="line"
+         id="tspan4147"
+         x="450.6557"
+         y="297.58051">a655daf15409</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.71429"
+       y="327.22226"
+       id="text4149"><tspan
+         sodipodi:role="line"
+         id="tspan4151"
+         x="450.71429"
+         y="327.22226">e50d59aaea3a</tspan></text>
+    <rect
+       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect3106"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="150.41792" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="165.8503"
+       id="text3108"><tspan
+         sodipodi:role="line"
+         id="tspan3110"
+         x="237.89598"
+         y="165.8503">forbid-illegal-params.patch</tspan></text>
+    <rect
+       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect2241"
+       width="202.93683"
+       height="24.243662"
+       x="230.16466"
+       y="180.05968" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="238.04128"
+       y="195.49205"
+       id="text2243"><tspan
+         sodipodi:role="line"
+         id="tspan2245"
+         x="238.04128"
+         y="195.49205">fix-memory-leak.patch</tspan></text>
+  </g>
+</svg>
Binary file en/figs/note.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/revlog.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="revlog.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3092">
+      <stop
+         style="stop-color:#44436f;stop-opacity:1;"
+         offset="0"
+         id="stop3094" />
+      <stop
+         style="stop-color:#abade5;stop-opacity:1;"
+         offset="1"
+         id="stop3096" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3118"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3120"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3129"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934"
+       gradientTransform="translate(-0.928574,-1.428574)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3133"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934"
+       gradientTransform="translate(-0.928574,-1.428574)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3708"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5164"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5584"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5784"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5786"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5895"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5958"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.64"
+     inkscape:cx="566.02368"
+     inkscape:cy="688.16826"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="29"
+     inkscape:window-y="79"
+     inkscape:connector-spacing="11" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="168.74846"
+       x="211.58516"
+       height="89.506805"
+       width="101.60232"
+       id="rect3068"
+       style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g3215"
+       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)">
+      <rect
+         y="447.71451"
+         x="299.67859"
+         height="48.571426"
+         width="103.14286"
+         id="rect2899"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2903"
+         y="464.8139"
+         x="308.89639"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.8139"
+           x="308.89639"
+           sodipodi:role="line"
+           id="tspan2905">Second parent</tspan></text>
+      <text
+         id="text2907"
+         y="485.50256"
+         x="308.20175"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.50256"
+           x="308.20175"
+           id="tspan2909"
+           sodipodi:role="line">32bf9a5f22c0</tspan></text>
+    </g>
+    <g
+       id="g3250"
+       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)">
+      <rect
+         y="311.28598"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect2936"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2940"
+         y="328.38538"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="328.38538"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan2942">Revision hash</tspan></text>
+      <text
+         id="text2944"
+         y="349.07404"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="349.07404"
+           x="197.13031"
+           id="tspan2946"
+           sodipodi:role="line">34b8b7a15ea1</tspan></text>
+    </g>
+    <g
+       id="g3243"
+       transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)">
+      <rect
+         y="363.07654"
+         x="187.5"
+         height="75"
+         width="213.85715"
+         id="rect2950"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2958"
+         y="400.86459"
+         x="196.02321"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:black;fill-opacity:1;font-family:Courier"
+           y="400.86459"
+           x="196.02321"
+           id="tspan2960"
+           sodipodi:role="line">...</tspan></text>
+      <text
+         id="text2954"
+         y="380.17593"
+         x="196.71785"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="380.17593"
+           x="196.71785"
+           sodipodi:role="line"
+           id="tspan2956"
+           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
+    </g>
+    <g
+       id="g5529"
+       transform="translate(-6.710312,-8.165836e-6)">
+      <rect
+         style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3509"
+         width="101.60232"
+         height="89.506805"
+         x="218.29547"
+         y="497.4801" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
+         id="g3513">
+        <g
+           id="g3515">
+          <rect
+             y="447.72418"
+             x="188.6071"
+             height="48.571426"
+             width="103.14286"
+             id="rect3517"
+             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text3519"
+             y="464.82358"
+             x="197.82495"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               y="464.82358"
+               x="197.82495"
+               sodipodi:role="line"
+               id="tspan3521">First parent</tspan></text>
+          <text
+             id="text3523"
+             y="485.51224"
+             x="197.13031"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="485.51224"
+               x="197.13031"
+               id="tspan3525"
+               sodipodi:role="line">000000000000</tspan></text>
+        </g>
+        <g
+           id="g3527">
+          <rect
+             y="447.71451"
+             x="299.67859"
+             height="48.571426"
+             width="103.14286"
+             id="rect3529"
+             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text3531"
+             y="464.8139"
+             x="308.89639"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               y="464.8139"
+               x="308.89639"
+               sodipodi:role="line"
+               id="tspan3533">Second parent</tspan></text>
+          <text
+             id="text3535"
+             y="485.50256"
+             x="308.20175"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="485.50256"
+               x="308.20175"
+               id="tspan3537"
+               sodipodi:role="line">000000000000</tspan></text>
+        </g>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
+         id="g3539">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3541"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3543"><tspan
+             id="tspan3545"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Revision hash</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3547"><tspan
+             sodipodi:role="line"
+             id="tspan3549"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)"
+         id="g3551">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3553"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3555"><tspan
+             sodipodi:role="line"
+             id="tspan3557"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3559"><tspan
+             style="fill:black;fill-opacity:1"
+             id="tspan3561"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Revision data (delta or snapshot)</tspan></text>
+      </g>
+    </g>
+    <g
+       id="g4868"
+       transform="translate(-1.676208,-2.342463e-5)">
+      <rect
+         style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3567"
+         width="101.60232"
+         height="89.506805"
+         x="213.26137"
+         y="59.171272" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
+         id="g3573">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3575"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3577"><tspan
+             id="tspan3579"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">First parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3581"><tspan
+             sodipodi:role="line"
+             id="tspan3583"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">34b8b7a15ea1</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
+         id="g3585">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3587"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3589"><tspan
+             id="tspan3591"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Second parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3593"><tspan
+             sodipodi:role="line"
+             id="tspan3595"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)"
+         id="g3597">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3599"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3601"><tspan
+             id="tspan3603"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Revision hash</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3605"><tspan
+             sodipodi:role="line"
+             id="tspan3607"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">1b67dc96f27a</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)"
+         id="g3609">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3611"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3613"><tspan
+             sodipodi:role="line"
+             id="tspan3615"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3617"><tspan
+             style="fill:black;fill-opacity:1"
+             id="tspan3619"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Revision data (delta or snapshot)</tspan></text>
+      </g>
+    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)"
+       d="M 240.78255,143.08593 L 241.42595,171.75349"
+       id="path3801"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3573"
+       inkscape:connection-end="#g3250" />
+    <g
+       id="g5677">
+      <rect
+         style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3393"
+         width="101.60232"
+         height="89.506805"
+         x="150.76137"
+         y="278.32565" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3399">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3401"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3403"><tspan
+             id="tspan3405"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">First parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3407"><tspan
+             sodipodi:role="line"
+             id="tspan3409"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3411">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3413"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3415"><tspan
+             id="tspan3417"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Second parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3419"><tspan
+             sodipodi:role="line"
+             id="tspan3421"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3423">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3425"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3427"><tspan
+             id="tspan3429"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Revision hash</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3431"><tspan
+             sodipodi:role="line"
+             id="tspan3433"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">5b80c922ebdd</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)"
+         id="g3435">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3437"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3439"><tspan
+             sodipodi:role="line"
+             id="tspan3441"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3443"><tspan
+             style="fill:black;fill-opacity:1"
+             id="tspan3445"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Revision data (delta or snapshot)</tspan></text>
+      </g>
+    </g>
+    <g
+       id="g5646"
+       transform="translate(-0.227432,0)">
+      <rect
+         style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3451"
+         width="101.60232"
+         height="89.506805"
+         x="272.63638"
+         y="278.32565" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3457">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3459"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3461"><tspan
+             id="tspan3463"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">First parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3465"><tspan
+             sodipodi:role="line"
+             id="tspan3467"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">ecacb6b4c9fd</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3469">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3471"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3473"><tspan
+             id="tspan3475"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Second parent</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3477"><tspan
+             sodipodi:role="line"
+             id="tspan3479"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3481">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3483"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3485"><tspan
+             id="tspan3487"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Revision hash</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3489"><tspan
+             sodipodi:role="line"
+             id="tspan3491"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">32bf9a5f22c0</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)"
+         id="g3493">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3495"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3497"><tspan
+             sodipodi:role="line"
+             id="tspan3499"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3501"><tspan
+             style="fill:black;fill-opacity:1"
+             id="tspan3503"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Revision data (delta or snapshot)</tspan></text>
+      </g>
+    </g>
+    <rect
+       y="387.90286"
+       x="272.40894"
+       height="89.506805"
+       width="101.60232"
+       id="rect5081"
+       style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g5087"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="447.72418"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect5089"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5091"
+         y="464.82358"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.82358"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan5093">First parent</tspan></text>
+      <text
+         id="text5095"
+         y="485.51224"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.51224"
+           x="197.13031"
+           id="tspan5097"
+           sodipodi:role="line">ff9dc8bc2a8b</tspan></text>
+    </g>
+    <g
+       id="g5099"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="447.71451"
+         x="299.67859"
+         height="48.571426"
+         width="103.14286"
+         id="rect5101"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5103"
+         y="464.8139"
+         x="308.89639"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.8139"
+           x="308.89639"
+           sodipodi:role="line"
+           id="tspan5105">Second parent</tspan></text>
+      <text
+         id="text5107"
+         y="485.50256"
+         x="308.20175"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.50256"
+           x="308.20175"
+           id="tspan5109"
+           sodipodi:role="line">000000000000</tspan></text>
+    </g>
+    <g
+       id="g5111"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="311.28598"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect5113"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5115"
+         y="328.38538"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="328.38538"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan5117">Revision hash</tspan></text>
+      <text
+         id="text5119"
+         y="349.07404"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="349.07404"
+           x="197.13031"
+           id="tspan5121"
+           sodipodi:role="line">ecacb6b4c9fd</tspan></text>
+    </g>
+    <g
+       id="g5123"
+       transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)">
+      <rect
+         y="363.07654"
+         x="187.5"
+         height="75"
+         width="213.85715"
+         id="rect5125"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5127"
+         y="400.86459"
+         x="196.02321"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:black;fill-opacity:1;font-family:Courier"
+           y="400.86459"
+           x="196.02321"
+           id="tspan5129"
+           sodipodi:role="line">...</tspan></text>
+      <text
+         id="text5131"
+         y="380.17593"
+         x="196.71785"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="380.17593"
+           x="196.71785"
+           sodipodi:role="line"
+           id="tspan5133"
+           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
+    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 299.69935,362.24027 L 299.69931,393.49494"
+       id="path5203"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3457"
+       inkscape:connection-end="#g5111" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 182.35357,362.22647 L 241.2842,503.07224"
+       id="path5271"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3399"
+       inkscape:connection-end="#g3539" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 287.63109,471.81747 L 250.9438,503.07223"
+       id="path5285"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g5087"
+       inkscape:connection-end="#g3539" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 290.80419,250.07192 L 297.80065,283.90394"
+       id="path5077"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3215"
+       inkscape:connection-end="#g3481" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 229.63373,250.07601 L 190.07484,283.90394"
+       id="path5075"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g3423" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="100.79968"
+       id="text5897"><tspan
+         sodipodi:role="line"
+         id="tspan5899"
+         x="131.5625"
+         y="100.79968"
+         style="text-align:end;text-anchor:end">Head revision</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="115.79968"
+         id="tspan5901"
+         style="text-align:end;text-anchor:end">(no children)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="207.04968"
+       id="text5903"><tspan
+         sodipodi:role="line"
+         id="tspan5905"
+         x="131.5625"
+         y="207.04968"
+         style="text-align:end;text-anchor:end">Merge revision</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="222.04968"
+         id="tspan5907"
+         style="text-align:end;text-anchor:end">(two parents)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.92578"
+       y="451.58093"
+       id="text5909"><tspan
+         sodipodi:role="line"
+         id="tspan5911"
+         x="131.92578"
+         y="451.58093"
+         style="text-align:end;text-anchor:end">Branches</tspan><tspan
+         sodipodi:role="line"
+         x="131.92578"
+         y="466.58093"
+         id="tspan5913"
+         style="text-align:end;text-anchor:end">(two revisions,</tspan><tspan
+         sodipodi:role="line"
+         x="131.92578"
+         y="481.58093"
+         id="tspan5915"
+         style="text-align:end;text-anchor:end">same parent)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 111.71875,433.61218 L 154.7268,368.52294"
+       id="path5917"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 134.375,464.86218 L 277.86691,440.37816"
+       id="path5919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g5123" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="536.73718"
+       id="text5927"><tspan
+         sodipodi:role="line"
+         id="tspan5929"
+         x="131.5625"
+         y="536.73718">First revision</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="551.73718"
+         id="tspan5931">(both parents null)</tspan></text>
+    <rect
+       style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2830"
+       width="43.664806"
+       height="20.562374"
+       x="217.0432"
+       y="232.10075" />
+    <text
+       xml:space="preserve"
+       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="220.94551"
+       y="239.33966"
+       id="text2832"><tspan
+         id="tspan2836"
+         sodipodi:role="line"
+         x="220.94551"
+         y="239.33966">First parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="220.65144"
+       y="248.09805"
+       id="text2879"><tspan
+         sodipodi:role="line"
+         id="tspan2881"
+         x="220.65144"
+         y="248.09805"
+         style="font-family:Courier">5b80c922ebdd</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 139.84375,107.83093 L 210.15625,107.83093"
+       id="path5965"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 137.5,213.29968 L 210.49036,214.09055"
+       id="path5967"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 136.34375,544.54968 L 206.65625,544.54968"
+       id="path5969"
+       inkscape:connector-type="polyline"
+       inkscape:transform-center-y="-171.09375"
+       inkscape:transform-center-x="53.90625" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/snapshot.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2807"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="snapshots.svg">
+  <defs
+     id="defs2809" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="252.04111"
+     inkscape:cy="605.75448"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="721"
+     inkscape:window-x="0"
+     inkscape:window-y="25" />
+  <metadata
+     id="metadata2812">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2817"
+       width="118.18347"
+       height="245.32632"
+       x="243.05112"
+       y="315.4133"
+       inkscape:transform-center-x="136.84403"
+       inkscape:transform-center-y="-66.529183" />
+    <rect
+       y="315.04153"
+       x="46.965065"
+       height="97.803009"
+       width="108.92702"
+       id="rect2815"
+       style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g3814">
+      <rect
+         y="348.94302"
+         x="59.285713"
+         height="30"
+         width="84.285713"
+         id="rect2819"
+         style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         ry="0" />
+      <text
+         id="text2821"
+         y="368.02701"
+         x="72.717636"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="368.02701"
+           x="72.717636"
+           id="tspan2823"
+           sodipodi:role="line">Index, rev 7</tspan></text>
+    </g>
+    <text
+       id="text3722"
+       y="301.29074"
+       x="46.187778"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       xml:space="preserve"><tspan
+         y="301.29074"
+         x="46.187778"
+         id="tspan3724"
+         sodipodi:role="line">Revlog index (.i file)</tspan></text>
+    <text
+       id="text3726"
+       y="301.29074"
+       x="241.90207"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       xml:space="preserve"><tspan
+         y="301.29074"
+         x="241.90207"
+         id="tspan3728"
+         sodipodi:role="line">Revlog data (.d file)</tspan></text>
+    <path
+       style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z "
+       id="path3839"
+       sodipodi:nodetypes="ccccc" />
+    <rect
+       style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3752"
+       width="92.720184"
+       height="67.005905"
+       x="255.42564"
+       y="368.64264" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="264.45859"
+       y="387.30099"
+       id="text3754"><tspan
+         sodipodi:role="line"
+         id="tspan3756"
+         x="264.45859"
+         y="387.30099">Snapshot, rev 4</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3761"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="442.04395" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="460.17206"
+       id="text3763"><tspan
+         sodipodi:role="line"
+         id="tspan3765"
+         x="263.2662"
+         y="460.17206">Delta, rev 4 to 5</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3774"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="477.97485" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="496.10297"
+       id="text3776"><tspan
+         sodipodi:role="line"
+         id="tspan3778"
+         x="263.2662"
+         y="496.10297">Delta, rev 5 to 6</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3782"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="513.90576" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="532.03387"
+       id="text3784"><tspan
+         sodipodi:role="line"
+         id="tspan3786"
+         x="263.2662"
+         y="532.03387">Delta, rev 6 to 7</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3889"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="332.32489" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="350.453"
+       id="text3891"><tspan
+         sodipodi:role="line"
+         id="tspan3893"
+         x="263.2662"
+         y="350.453">Delta, rev 2 to 3</tspan></text>
+  </g>
+</svg>
Binary file en/figs/throbber.gif has changed
Binary file en/figs/tip.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/tour-history.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="tour-history.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="232.14286"
+     inkscape:cy="672.75296"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="5"
+     inkscape:window-y="49" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="244.60992"
+       y="305.245"
+       id="text1902"><tspan
+         sodipodi:role="line"
+         id="tspan1904"
+         x="244.60992"
+         y="305.245">(newest)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="244.60992"
+       y="492.745"
+       id="text1906"><tspan
+         sodipodi:role="line"
+         id="tspan1908"
+         x="244.60992"
+         y="492.745">(oldest)</tspan></text>
+    <rect
+       style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1907"
+       width="94.285713"
+       height="20.714285"
+       x="309.28571"
+       y="324.86218" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="333.38464"
+       y="338.48334"
+       id="text1909"><tspan
+         sodipodi:role="line"
+         id="tspan1911"
+         x="333.38464"
+         y="338.48334"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1913">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 332.14286,375.21932 L 335.71429,347.36218"
+       id="path2802" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 372.69968,375.21932 L 369.12825,347.36218"
+       id="path2986" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="335.14285"
+       y="387.21933"
+       id="text2988"><tspan
+         sodipodi:role="line"
+         x="335.14285"
+         y="387.21933"
+         id="tspan3020"
+         style="text-align:end;text-anchor:end">revision</tspan><tspan
+         sodipodi:role="line"
+         x="335.14285"
+         y="402.21933"
+         id="tspan3014"
+         style="text-align:end;text-anchor:end">number</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="368.71429"
+       y="387.21933"
+       id="text2994"><tspan
+         sodipodi:role="line"
+         id="tspan2996"
+         x="368.71429"
+         y="387.21933">changeset</tspan><tspan
+         sodipodi:role="line"
+         x="368.71429"
+         y="402.21933"
+         id="tspan2998">identifier</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/tour-merge-conflict.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="tour-merge-conflict.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3053"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="164.78349"
+     inkscape:cy="590.07679"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="5"
+     inkscape:window-y="49" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g1988"
+       transform="translate(84.85711,0)">
+      <g
+         id="g1876">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1872"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1874"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1898"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1900"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1902" /></flowRegion><flowPara
+           id="flowPara1904">Greetings!</flowPara><flowPara
+           id="flowPara1906" /><flowPara
+           id="flowPara1908">I am Mariam Abacha, the wife of former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
+    <g
+       id="g1966"
+       transform="translate(82,0.35715)">
+      <g
+         transform="translate(-77.85718,-140.0714)"
+         id="g1910">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1912"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1914"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         transform="translate(-77.85718,-140.0714)"
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1916"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1918"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1920" /></flowRegion><flowPara
+           id="flowPara1922">Greetings!</flowPara><flowPara
+           id="flowPara1924" /><flowPara
+           id="flowPara1926">I am <flowSpan
+   style="font-style:italic;fill:red"
+   id="flowSpan3094">Shehu Musa Abacha, cousin to</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
+    <g
+       id="g1977"
+       transform="translate(81.99999,-0.35715)">
+      <g
+         transform="translate(83.57141,-139.3571)"
+         id="g1932">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1934"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1936"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         transform="translate(83.57141,-139.3571)"
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1938"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1940"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1942" /></flowRegion><flowPara
+           id="flowPara1944">Greetings!</flowPara><flowPara
+           id="flowPara1946" /><flowPara
+           id="flowPara1948">I am <flowSpan
+   style="font-style:italic;fill:red"
+   id="flowSpan3096">Alhaji Abba Abacha, son of</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 215.502,457.71933 L 196.35507,424.5765"
+       id="path1999"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g1988"
+       inkscape:connection-end="#g1966" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 277.06936,457.71933 L 296.21629,424.5765"
+       id="path2001"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g1988"
+       inkscape:connection-end="#g1977" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="302.42859"
+       y="515.08905"
+       id="text1905"><tspan
+         sodipodi:role="line"
+         id="tspan1907"
+         x="302.42859"
+         y="515.08905">Base version</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="45.57143"
+       y="374.1619"
+       id="text1917"><tspan
+         sodipodi:role="line"
+         id="tspan1919"
+         x="45.57143"
+         y="374.1619">Our changes</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="385.71429"
+       y="374.1619"
+       id="text1921"><tspan
+         sodipodi:role="line"
+         id="tspan1923"
+         x="385.71429"
+         y="374.1619">Their changes</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/tour-merge-merge.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,380 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="tour-merge-merge.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="247.53795"
+     inkscape:cy="871.05738"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="38"
+     inkscape:window-y="95" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2995"
+       width="94.285713"
+       height="20.714285"
+       x="532.85718"
+       y="203.0479" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="297.76227" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="311.38342"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="311.38342"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,343.63731 L 185.14286,319.47656"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="91.428574"
+       y="250.47656" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="116.09886"
+       y="264.56592"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="116.09886"
+         y="264.56592"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 173.95727,296.76228 L 149.75702,272.19085"
+       id="path1971"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2863"
+       inkscape:connection-start="#rect2830" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="186.71414"
+       y="204.40514" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="210.81311"
+       y="218.02673"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="210.81311"
+         y="218.02673"
+         style="font-family:Courier"><tspan
+   id="tspan1966"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 191.06908,296.76228 L 227.93092,226.11942"
+       id="path2919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2830" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="295.28571"
+       y="217.56711"
+       id="text2871"><tspan
+         sodipodi:role="line"
+         id="tspan2873"
+         x="295.28571"
+         y="217.56711">tip (and head)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="76"
+       y="264.91769"
+       id="text2875"><tspan
+         sodipodi:role="line"
+         id="tspan2877"
+         x="76"
+         y="264.91769"
+         style="text-align:end;text-anchor:end">head</tspan></text>
+    <rect
+       style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1913"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="156.90514" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 144.22399,249.47657 L 179.49029,178.61943"
+       id="path1915"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2863"
+       inkscape:connection-end="#rect1913" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 222.20966,203.40514 L 196.79033,178.61943"
+       id="path1917"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2911"
+       inkscape:connection-end="#rect1913" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="166.16823"
+       y="168.52228"
+       id="text2806"><tspan
+         sodipodi:role="line"
+         id="tspan2808"
+         x="166.16823"
+         y="168.52228"
+         style="font-family:Courier">merge</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="246"
+       y="162.63338"
+       id="text2810"><tspan
+         sodipodi:role="line"
+         id="tspan2812"
+         x="246"
+         y="162.63338">working directory</tspan><tspan
+         sodipodi:role="line"
+         x="246"
+         y="177.63338"
+         id="tspan2814">during merge</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2816"
+       width="94.285713"
+       height="20.714285"
+       x="483.14636"
+       y="297.76227" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="507.24527"
+       y="311.38342"
+       id="text2818"><tspan
+         sodipodi:role="line"
+         id="tspan2820"
+         x="507.24527"
+         y="311.38342"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2822">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 530.28921,343.6373 L 530.28921,319.47655"
+       id="path2824"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2826"
+       width="94.285713"
+       height="20.714285"
+       x="436.57492"
+       y="250.47656" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="461.24484"
+       y="264.56613"
+       id="text2828"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2830"
+         x="461.24484"
+         y="264.56613"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2832">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 519.10362,296.76227 L 494.90337,272.19084"
+       id="path2834"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2836"
+       width="94.285995"
+       height="20.714283"
+       x="483.14001"
+       y="156.548" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="555.95911"
+       y="218.02698"
+       id="text2838"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2840"
+         x="555.95911"
+         y="218.02698"
+         style="font-family:Courier"><tspan
+   id="tspan2842"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 536.21543,296.76227 L 574.03453,224.76218"
+       id="path2844"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="594.43207"
+       y="169.78796"
+       id="text2846"><tspan
+         sodipodi:role="line"
+         id="tspan2848"
+         x="594.43207"
+         y="169.78796">tip</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 489.37034,249.47656 L 524.65575,178.26229"
+       id="path2856"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2836" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 567.85714,202.0479 L 542.42591,178.26229"
+       id="path2858"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2836"
+       inkscape:connection-start="#rect2995" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="504.54507"
+       y="170.39714"
+       id="text2860"><tspan
+         sodipodi:role="line"
+         id="tspan2863"
+         x="504.54507"
+         y="170.39714"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2997">7</tspan>: REV7_my_new_hello</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="90.323105"
+       y="120.21933"
+       id="text2929"><tspan
+         sodipodi:role="line"
+         id="tspan2931"
+         x="90.323105"
+         y="120.21933"
+         style="font-weight:bold">Working directory during merge</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="435.35226"
+       y="120.21933"
+       id="text2937"><tspan
+         sodipodi:role="line"
+         id="tspan2939"
+         x="435.35226"
+         y="120.21933"
+         style="font-weight:bold">Repository after merge committed</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/tour-merge-pull.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="tour-merge-pull.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="233.63208"
+     inkscape:cy="832.54381"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="237"
+     inkscape:window-y="103" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="91.428574"
+       y="244.71933" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="116.09886"
+       y="258.80865"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="116.09886"
+         y="258.80865"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 173.95727,291.00504 L 149.75702,266.43361"
+       id="path1971"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2863"
+       inkscape:connection-start="#rect2830" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="186.71414"
+       y="198.6479" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="210.81311"
+       y="212.26949"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="210.81311"
+         y="212.26949"
+         style="font-family:Courier"><tspan
+   id="tspan1966"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 191.06908,291.00504 L 227.93092,220.36218"
+       id="path2919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2830" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="295.28571"
+       y="211.80988"
+       id="text2871"><tspan
+         sodipodi:role="line"
+         id="tspan2873"
+         x="295.28571"
+         y="211.80988">tip (and head)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="76"
+       y="259.16046"
+       id="text2875"><tspan
+         sodipodi:role="line"
+         id="tspan2877"
+         x="76"
+         y="259.16046"
+         style="text-align:end;text-anchor:end">head</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/tour-merge-sep-repos.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docname="tour-merge-sep-repos.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="307.20351"
+     inkscape:cy="716.87911"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="5"
+     inkscape:window-y="49" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1963"
+       width="94.285995"
+       height="20.714283"
+       x="138"
+       y="245.18723" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09877"
+       y="258.80865"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="162.09877"
+         y="258.80865"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.143,291.06218 L 185.143,266.90143"
+       id="path1971"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="136.90039"
+       y="232.25546"
+       id="text2921"><tspan
+         sodipodi:role="line"
+         id="tspan2923"
+         x="136.90039"
+         y="232.25546">my-hello</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="479.49289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="493.11404"
+       id="text2865"><tspan
+         sodipodi:role="line"
+         id="tspan2867"
+         x="394.81305"
+         y="493.11404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2869">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2871"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="432.61789" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="446.23904"
+       id="text2873"><tspan
+         sodipodi:role="line"
+         id="tspan2875"
+         x="394.81305"
+         y="446.23904"
+         style="font-family:Courier"><tspan
+   id="tspan2877"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2879"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="385.74289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="399.36404"
+       id="text2881"><tspan
+         sodipodi:role="line"
+         id="tspan2883"
+         x="394.81305"
+         y="399.36404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2885">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2887"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="338.86792" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="352.48907"
+       id="text2889"><tspan
+         sodipodi:role="line"
+         id="tspan2891"
+         x="394.81305"
+         y="352.48907"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2893">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2895"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="291.99289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="305.61404"
+       id="text2897"><tspan
+         sodipodi:role="line"
+         id="tspan2899"
+         x="394.81305"
+         y="305.61404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2901">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,478.4929 L 417.85701,454.33218"
+       id="path2903"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,431.6179 L 417.85701,407.45718"
+       id="path2905"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,384.7429 L 417.85701,360.58221"
+       id="path2907"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,337.86793 L 417.85701,313.70718"
+       id="path2909"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="370.71414"
+       y="245.17511" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81274"
+       y="258.79678"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="394.81274"
+         y="258.79678"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2917">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85715,291.05004 L 417.85715,266.88929"
+       id="path2919"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="369.61453"
+       y="232.25546"
+       id="text2925"><tspan
+         sodipodi:role="line"
+         id="tspan2927"
+         x="369.61453"
+         y="232.25546">my-new-hello</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="300.54352"
+       y="252.12723"
+       id="text2933"><tspan
+         sodipodi:role="line"
+         id="tspan2935"
+         x="300.54352"
+         y="252.12723"
+         style="text-align:center;text-anchor:middle">newest changes</tspan><tspan
+         sodipodi:role="line"
+         x="300.54352"
+         y="267.12723"
+         style="text-align:center;text-anchor:middle"
+         id="tspan3132">differ</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="262.15436"
+       y="398.37112"
+       id="text2929"><tspan
+         sodipodi:role="line"
+         x="262.15436"
+         y="398.37112"
+         id="tspan3013"
+         style="text-align:start;text-anchor:start">common history</tspan></text>
+    <g
+       id="g3107"
+       transform="translate(0,0.855744)">
+      <path
+         id="path3101"
+         d="M 300.35713,381.29075 L 300.35713,304.50504"
+         style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" />
+      <path
+         id="path3105"
+         d="M 291.07142,301.64789 L 309.28571,301.64789"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+    <path
+       style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 300.53571,486.38926 L 300.53571,409.60355"
+       id="path3113" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 291.25,488.49641 L 309.46429,488.49641"
+       id="path3115" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="480.71429"
+       y="250.91507"
+       id="text1949"><tspan
+         sodipodi:role="line"
+         id="tspan1951"
+         x="480.71429"
+         y="250.91507"
+         style="text-align:start;text-anchor:start">head revision</tspan><tspan
+         sodipodi:role="line"
+         x="480.71429"
+         y="265.91507"
+         id="tspan1953"
+         style="text-align:start;text-anchor:start">(has no children)</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/undo-manual-merge.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+digraph undo_manual {
+	"first change" -> "second change";
+	"second change" -> "third change";
+	backout [label="back out\nsecond change", shape=box];
+	"second change" -> backout;
+	"third change" -> "manual\nmerge";
+	backout -> "manual\nmerge";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/undo-manual.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,6 @@
+digraph undo_manual {
+	"first change" -> "second change";
+	"second change" -> "third change";
+	backout [label="back out\nsecond change", shape=box];
+	"second change" -> backout;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/undo-non-tip.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,9 @@
+digraph undo_non_tip {
+	"first change" -> "second change";
+	"second change" -> "third change";
+	backout [label="back out\nsecond change", shape=box];
+	"second change" -> backout;
+	merge [label="automated\nmerge", shape=box];
+	"third change" -> merge;
+	backout -> merge;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/undo-simple.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,4 @@
+digraph undo_simple {
+	"first change" -> "second change";
+	"second change" -> "back out\nsecond change";
+}
Binary file en/figs/warning.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/wdir-after-commit.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-after-commit.svg">
+  <defs
+     id="defs5973">
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-6.0462,-0.664361)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6772"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="390.0539"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="0"
+     inkscape:window-y="25">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="245.98355"
+       x="328.23956"
+       height="258.57144"
+       width="174.28572"
+       id="rect6047"
+       style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6261"
+       transform="translate(234,0)">
+      <rect
+         y="258.7149"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect5983"
+         style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5985"
+         y="284.47562"
+         x="138.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="284.47562"
+           x="138.7962"
+           id="tspan5987"
+           sodipodi:role="line">dfbbb33f3fa3</tspan></text>
+    </g>
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect5996"
+       width="134.53746"
+       height="44.537449"
+       x="348.11371"
+       y="320.38159" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="372.7962"
+       y="346.1423"
+       id="text5998"><tspan
+         sodipodi:role="line"
+         id="tspan6000"
+         x="372.7962"
+         y="346.1423"
+         style="font-family:Courier">e7639888bb2f</tspan></text>
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6004"
+       width="134.53746"
+       height="44.537449"
+       x="348.11371"
+       y="382.04825" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="370.65421"
+       y="407.80896"
+       id="text6006"><tspan
+         sodipodi:role="line"
+         id="tspan6008"
+         x="370.65421"
+         y="407.80896"
+         style="font-family:Courier">7b064d8bac5e</tspan></text>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6018"
+       d="M 415.38242,303.62646 L 415.38242,320.00744"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <path
+       inkscape:connection-end="#rect6004"
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 415.38242,365.29315 L 415.38243,381.67412"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="348.11359"
+       y="443.71487" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="372.79706"
+       y="469.47556"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="372.79706"
+         y="469.47556"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 415.38238,426.95981 L 415.38235,443.34087"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="327.66046"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="327.66046"
+         y="231.36218">History in repository</tspan></text>
+    <rect
+       y="245.94225"
+       x="557.28418"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(262.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">dfbbb33f3fa3</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(263.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="576.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="576.63208"
+         y="270.479">First parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="576.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="576.07544"
+         y="364.49615">Second parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="556.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="556.61743"
+         y="231.36218">Parents of working directory</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 576.82542,297.63008 L 483.02528,287.95831"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#g6261" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="316.86407"
+       y="275.6496"
+       id="text6573"><tspan
+         sodipodi:role="line"
+         id="tspan6575"
+         x="316.86407"
+         y="275.6496"
+         style="text-align:end;text-anchor:end">New</tspan><tspan
+         sodipodi:role="line"
+         x="316.86407"
+         y="290.6496"
+         id="tspan6577"
+         style="text-align:end;text-anchor:end">changeset</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/wdir-branch.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-branch.svg">
+  <defs
+     id="defs5973">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="345.85973"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="0"
+     inkscape:window-y="25">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="246.06918"
+       x="64.325172"
+       height="204.26233"
+       width="333.2135"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g1935">
+      <rect
+         y="266.24374"
+         x="84.113708"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.00446"
+         x="108.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="108.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+    </g>
+    <g
+       id="g6976"
+       transform="translate(70,0)">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 160.92915,311.15532 L 167.83571,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g1935" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="110.11359"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="134.79706"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="134.79706"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 177.38238,372.82195 L 177.38235,389.20303"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       y="245.94225"
+       x="447.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(152.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">ffb20e1701ea</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(153.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="466.63208"
+         y="270.479">First parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="466.07544"
+         y="364.49615">Second parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="446.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="446.61743"
+         y="231.36218">Parents of working directory</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82542,300.21999 L 377.00207,294.39744"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect1925" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <g
+       id="g2845">
+      <rect
+         y="266.24374"
+         x="242.09048"
+         height="44.537449"
+         width="134.53746"
+         id="rect1925"
+         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text1927"
+         y="292.00446"
+         x="266.77298"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="266.77298"
+           id="tspan1929"
+           sodipodi:role="line">ffb20e1701ea</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path1933"
+       d="M 260.89978,311.15532 L 225.84185,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="109.45568"
+       y="231.4554"
+       id="text2837"><tspan
+         sodipodi:role="line"
+         id="tspan2839"
+         x="109.45568"
+         y="231.4554">Pre-existing head</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="237.54184"
+       y="231.4554"
+       id="text2841"><tspan
+         sodipodi:role="line"
+         id="tspan2843"
+         x="237.54184"
+         y="231.4554">Newly created head (and tip)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 148.05048,235.87482 L 149.94915,265.86962"
+       id="path2850"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g1935" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 303.83495,238.08453 L 306.87874,265.86962"
+       id="path2852"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g2845" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/wdir-merge.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-merge.svg">
+  <defs
+     id="defs5973">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.28"
+     inkscape:cx="345.85973"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="0"
+     inkscape:window-y="25">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="246.06918"
+       x="64.325172"
+       height="204.26233"
+       width="333.2135"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6976"
+       transform="translate(70,0)">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 160.92915,311.15532 L 167.83571,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g1935" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="110.11359"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="134.79706"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="134.79706"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 177.38238,372.82195 L 177.38235,389.20303"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       y="245.94225"
+       x="447.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(152.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">ffb20e1701ea</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(153.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="466.63208"
+         y="270.479">First parent (unchanged)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="466.07544"
+         y="364.49615">Second parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="446.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="446.61743"
+         y="231.36218">Parents of working directory</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82542,300.21999 L 377.00207,294.39744"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect1925" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <g
+       id="g2845">
+      <rect
+         y="266.24374"
+         x="242.09048"
+         height="44.537449"
+         width="134.53746"
+         id="rect1925"
+         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text1927"
+         y="292.00446"
+         x="266.77298"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="266.77298"
+           id="tspan1929"
+           sodipodi:role="line">ffb20e1701ea</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path1933"
+       d="M 260.89978,311.15532 L 225.84185,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="109.45568"
+       y="231.4554"
+       id="text2837"><tspan
+         sodipodi:role="line"
+         id="tspan2839"
+         x="109.45568"
+         y="231.4554">Pre-existing head</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="237.54184"
+       y="231.4554"
+       id="text2841"><tspan
+         sodipodi:role="line"
+         id="tspan2843"
+         x="237.54184"
+         y="231.4554">Newly created head (and tip)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 148.05048,235.87482 L 149.94915,265.86962"
+       id="path2850"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g1935" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 303.83495,238.08453 L 306.87874,265.86962"
+       id="path2852"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g2845" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82545,379.17944 L 219.0253,307.95488"
+       id="path3016"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6135"
+       inkscape:connection-end="#g1935" />
+    <g
+       id="g1935">
+      <rect
+         y="266.24374"
+         x="84.113708"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.00446"
+         x="108.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="108.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/wdir-pre-branch.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-branch.svg">
+  <defs
+     id="defs5973">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="390.0539"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="0"
+     inkscape:window-y="25">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="245.94225"
+       x="20.198257"
+       height="204.51619"
+       width="174.36833"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect5996"
+       width="134.53746"
+       height="44.537449"
+       x="40.113693"
+       y="266.24374" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="64.796204"
+       y="292.00446"
+       id="text5998"><tspan
+         sodipodi:role="line"
+         id="tspan6000"
+         x="64.796204"
+         y="292.00446"
+         style="font-family:Courier">e7639888bb2f</tspan></text>
+    <g
+       id="g6976">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connection-end="#rect6004"
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 107.38242,311.15529 L 107.38242,327.53626"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="40.113571"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="64.797073"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="64.797073"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 107.38238,372.82195 L 107.38235,389.20301"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="19.660461"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="19.660461"
+         y="231.36218">History in repository</tspan></text>
+    <rect
+       y="245.94225"
+       x="249.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(-45.67459,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">7b064d8bac5e</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(-44.96042,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="268.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="268.63208"
+         y="270.479">First parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="268.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="268.07544"
+         y="364.49615">Second parent</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="248.61746"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="248.61746"
+         y="231.36218">Parents of working directory</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 268.82543,318.06163 L 175.02528,336.72225"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g6130" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/figs/wdir.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,348 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.44.1"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir.svg">
+  <defs
+     id="defs5973">
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="390.0539"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="620"
+     inkscape:window-x="0"
+     inkscape:window-y="25">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g6431"
+       transform="translate(0,-0.137863)">
+      <rect
+         style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6047"
+         width="174.36833"
+         height="204.51619"
+         x="94.198257"
+         y="246.08011" />
+      <rect
+         y="266.38159"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.1423"
+         x="138.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.1423"
+           x="138.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+      <rect
+         y="328.04825"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.80896"
+         x="136.65421"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.80896"
+           x="136.65421"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+      <path
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         d="M 181.38242,311.29315 L 181.38242,327.67412"
+         id="path6020"
+         inkscape:connector-type="polyline"
+         inkscape:connection-end="#rect6004" />
+      <rect
+         y="389.71487"
+         x="114.11357"
+         height="44.537449"
+         width="134.53746"
+         id="rect6039"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6041"
+         y="415.47556"
+         x="138.79707"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:#979797;fill-opacity:1;font-family:Courier"
+           y="415.47556"
+           x="138.79707"
+           id="tspan6043"
+           sodipodi:role="line">000000000000</tspan></text>
+      <path
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         d="M 181.38238,372.95981 L 181.38235,389.34087"
+         id="path6045"
+         inkscape:connector-type="polyline"
+         inkscape:connection-end="#rect6039" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="93.660484"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="93.660484"
+         y="231.36218">History in repository</tspan></text>
+    <g
+       id="g6416">
+      <rect
+         style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6140"
+         width="174.36833"
+         height="204.51619"
+         x="323.28412"
+         y="245.94225" />
+      <g
+         transform="translate(28.32541,24.38544)"
+         id="g6130">
+        <rect
+           y="257.95059"
+           x="314.87415"
+           height="44.537449"
+           width="134.53746"
+           id="rect6106"
+           style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           id="text6108"
+           y="283.7113"
+           x="339.55664"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           xml:space="preserve"><tspan
+             style="font-family:Courier"
+             y="283.7113"
+             x="339.55664"
+             id="tspan6110"
+             sodipodi:role="line">e7639888bb2f</tspan></text>
+      </g>
+      <g
+         transform="translate(29.03958,49.83106)"
+         id="g6135">
+        <rect
+           y="326.52203"
+           x="314.15985"
+           height="44.537449"
+           width="134.53746"
+           id="rect6112"
+           style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           inkscape:transform-center-x="129.28571"
+           inkscape:transform-center-y="102.85714" />
+        <text
+           id="text6114"
+           y="352.28271"
+           x="338.84335"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           xml:space="preserve"
+           inkscape:transform-center-x="128.69672"
+           inkscape:transform-center-y="102.7311"><tspan
+             style="fill:#979797;fill-opacity:1;font-family:Courier"
+             y="352.28271"
+             x="338.84335"
+             id="tspan6116"
+             sodipodi:role="line">000000000000</tspan></text>
+      </g>
+      <text
+         id="text6118"
+         y="270.479"
+         x="342.63208"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="270.479"
+           x="342.63208"
+           id="tspan6120"
+           sodipodi:role="line">First parent</tspan></text>
+      <text
+         id="text6122"
+         y="364.49615"
+         x="342.07544"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="364.49615"
+           x="342.07544"
+           id="tspan6124"
+           sodipodi:role="line">Second parent</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="322.61746"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="322.61746"
+         y="231.36218">Parents of working directory</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 342.82543,299.89384 L 249.02528,293.36123"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect5996" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+  </g>
+</svg>
--- a/en/filelog.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.45.1"
-   sodipodi:docname="filelog.svg"
-   sodipodi:docbase="/home/arun/hgbook/en"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3128"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient2887">
-      <stop
-         style="stop-color:#91cfcf;stop-opacity:1;"
-         offset="0"
-         id="stop2889" />
-      <stop
-         style="stop-color:aqua;stop-opacity:0;"
-         offset="1"
-         id="stop2891" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2795">
-      <stop
-         style="stop-color:#ccc;stop-opacity:1;"
-         offset="0"
-         id="stop2797" />
-      <stop
-         style="stop-color:#ccc;stop-opacity:0;"
-         offset="1"
-         id="stop2799" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3170"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(121.2183,94.95434)"
-       x1="81.322357"
-       y1="404.34424"
-       x2="201.52036"
-       y2="373.03967" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3172"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0,12)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3174"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
-       x1="81.322357"
-       y1="404.34424"
-       x2="201.52036"
-       y2="373.03967" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3176"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0,12)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3208"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
-       x1="81.322357"
-       y1="404.34424"
-       x2="201.52036"
-       y2="373.03967" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3210"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0,12)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3212"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(121.2183,94.95434)"
-       x1="81.322357"
-       y1="404.34424"
-       x2="201.52036"
-       y2="373.03967" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3214"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0,12)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3256"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)"
-       x1="74.301666"
-       y1="431.67441"
-       x2="260.05884"
-       y2="369.95322" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3258"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2795"
-       id="linearGradient3260"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)"
-       x1="74.387527"
-       y1="431.80576"
-       x2="259.97339"
-       y2="369.82224" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2887"
-       id="linearGradient3262"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)"
-       x1="62.634491"
-       y1="503.3392"
-       x2="248.49242"
-       y2="462.94327" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="455.8122"
-     inkscape:cy="520"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="1680"
-     inkscape:window-height="970"
-     inkscape:window-x="0"
-     inkscape:window-y="54" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3180"
-       width="273.81375"
-       height="199.06245"
-       x="369.1796"
-       y="351.79019" />
-    <rect
-       style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3178"
-       width="273.81339"
-       height="199.06233"
-       x="72.699799"
-       y="351.78983" />
-    <g
-       id="g3144"
-       transform="translate(80.467048,0.71578)">
-      <g
-         id="g2940">
-        <rect
-           style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect2914"
-           width="227.38896"
-           height="39.500999"
-           x="311.92496"
-           y="395.08627" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="323.72824"
-           y="416.7626"
-           id="text2918"><tspan
-             sodipodi:role="line"
-             id="tspan2920"
-             x="323.72824"
-             y="416.7626"
-             style="font-family:Courier">.hg/store/data/README.i</tspan></text>
-      </g>
-      <g
-         transform="translate(3.79093e-5,-80.1853)"
-         id="g2945">
-        <g
-           id="g2955">
-          <rect
-             y="475.4968"
-             x="15.550935"
-             height="39.500999"
-             width="227.17694"
-             id="rect2947"
-             style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-          <text
-             id="text2949"
-             y="498.35123"
-             x="31.230644"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               style="font-family:Courier"
-               y="498.35123"
-               x="31.230644"
-               id="tspan2951"
-               sodipodi:role="line">README</tspan></text>
-        </g>
-      </g>
-      <path
-         inkscape:connector-type="polyline"
-         id="path2960"
-         d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633"
-         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-         sodipodi:nodetypes="cz" />
-    </g>
-    <g
-       id="g3156"
-       transform="translate(80.467048,0.71578)">
-      <g
-         transform="translate(116,0)"
-         id="g2831">
-        <rect
-           style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect1906"
-           width="228.18446"
-           height="60.499123"
-           x="195.52719"
-           y="465.51859" />
-        <g
-           id="g2803"
-           transform="translate(-0.893671,1.833581)">
-          <text
-             id="text1884"
-             y="483.92801"
-             x="208.95944"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               style="font-family:Courier"
-               y="483.92801"
-               x="208.95944"
-               id="tspan1886"
-               sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text>
-          <text
-             id="text1888"
-             y="507.79309"
-             x="208.95944"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               style="font-family:Courier"
-               y="507.79309"
-               x="208.95944"
-               id="tspan1890"
-               sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text>
-        </g>
-      </g>
-      <g
-         id="g2907">
-        <rect
-           style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect2843"
-           width="227.17728"
-           height="39.500999"
-           x="15.550805"
-           y="475.4968" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="31.230644"
-           y="498.35123"
-           id="text2847"><tspan
-             sodipodi:role="line"
-             id="tspan2849"
-             x="31.230644"
-             y="498.35123"
-             style="font-family:Courier">src/hello.c</tspan></text>
-      </g>
-      <path
-         inkscape:connection-end="#g2831"
-         inkscape:connection-start="#g2907"
-         inkscape:connector-type="polyline"
-         id="path2962"
-         d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909"
-         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-         sodipodi:nodetypes="cs" />
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="98.496666"
-       y="373.96353"
-       id="text3216"><tspan
-         sodipodi:role="line"
-         id="tspan3218"
-         x="98.496666"
-         y="373.96353">Working directory</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="391.39197"
-       y="373.96353"
-       id="text3228"><tspan
-         sodipodi:role="line"
-         id="tspan3230"
-         x="391.39197"
-         y="373.96353">Repository</tspan></text>
-  </g>
-</svg>
--- a/en/filenames.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-\chapter{File names and pattern matching}
-\label{chap:names}
-
-Mercurial provides mechanisms that let you work with file names in a
-consistent and expressive way.
-
-\section{Simple file naming}
-
-Mercurial uses a unified piece of machinery ``under the hood'' to
-handle file names.  Every command behaves uniformly with respect to
-file names.  The way in which commands work with file names is as
-follows.
-
-If you explicitly name real files on the command line, Mercurial works
-with exactly those files, as you would expect.
-\interaction{filenames.files}
-
-When you provide a directory name, Mercurial will interpret this as
-``operate on every file in this directory and its subdirectories''.
-Mercurial traverses the files and subdirectories in a directory in
-alphabetical order.  When it encounters a subdirectory, it will
-traverse that subdirectory before continuing with the current
-directory.
-\interaction{filenames.dirs}
-
-\section{Running commands without any file names}
-
-Mercurial's commands that work with file names have useful default
-behaviours when you invoke them without providing any file names or
-patterns.  What kind of behaviour you should expect depends on what
-the command does.  Here are a few rules of thumb you can use to
-predict what a command is likely to do if you don't give it any names
-to work with.
-\begin{itemize}
-\item Most commands will operate on the entire working directory.
-  This is what the \hgcmd{add} command does, for example.
-\item If the command has effects that are difficult or impossible to
-  reverse, it will force you to explicitly provide at least one name
-  or pattern (see below).  This protects you from accidentally
-  deleting files by running \hgcmd{remove} with no arguments, for
-  example.
-\end{itemize}
-
-It's easy to work around these default behaviours if they don't suit
-you.  If a command normally operates on the whole working directory,
-you can invoke it on just the current directory and its subdirectories
-by giving it the name ``\dirname{.}''.
-\interaction{filenames.wdir-subdir}
-
-Along the same lines, some commands normally print file names relative
-to the root of the repository, even if you're invoking them from a
-subdirectory.  Such a command will print file names relative to your
-subdirectory if you give it explicit names.  Here, we're going to run
-\hgcmd{status} from a subdirectory, and get it to operate on the
-entire working directory while printing file names relative to our
-subdirectory, by passing it the output of the \hgcmd{root} command.
-\interaction{filenames.wdir-relname}
-
-\section{Telling you what's going on}
-
-The \hgcmd{add} example in the preceding section illustrates something
-else that's helpful about Mercurial commands.  If a command operates
-on a file that you didn't name explicitly on the command line, it will
-usually print the name of the file, so that you will not be surprised
-what's going on.
-
-The principle here is of \emph{least surprise}.  If you've exactly
-named a file on the command line, there's no point in repeating it
-back at you.  If Mercurial is acting on a file \emph{implicitly},
-because you provided no names, or a directory, or a pattern (see
-below), it's safest to tell you what it's doing.
-
-For commands that behave this way, you can silence them using the
-\hggopt{-q} option.  You can also get them to print the name of every
-file, even those you've named explicitly, using the \hggopt{-v}
-option.
-
-\section{Using patterns to identify files}
-
-In addition to working with file and directory names, Mercurial lets
-you use \emph{patterns} to identify files.  Mercurial's pattern
-handling is expressive.
-
-On Unix-like systems (Linux, MacOS, etc.), the job of matching file
-names to patterns normally falls to the shell.  On these systems, you
-must explicitly tell Mercurial that a name is a pattern.  On Windows,
-the shell does not expand patterns, so Mercurial will automatically
-identify names that are patterns, and expand them for you.
-
-To provide a pattern in place of a regular name on the command line,
-the mechanism is simple:
-\begin{codesample2}
-  syntax:patternbody
-\end{codesample2}
-That is, a pattern is identified by a short text string that says what
-kind of pattern this is, followed by a colon, followed by the actual
-pattern.
-
-Mercurial supports two kinds of pattern syntax.  The most frequently
-used is called \texttt{glob}; this is the same kind of pattern
-matching used by the Unix shell, and should be familiar to Windows
-command prompt users, too.  
-
-When Mercurial does automatic pattern matching on Windows, it uses
-\texttt{glob} syntax.  You can thus omit the ``\texttt{glob:}'' prefix
-on Windows, but it's safe to use it, too.
-
-The \texttt{re} syntax is more powerful; it lets you specify patterns
-using regular expressions, also known as regexps.
-
-By the way, in the examples that follow, notice that I'm careful to
-wrap all of my patterns in quote characters, so that they won't get
-expanded by the shell before Mercurial sees them.
-
-\subsection{Shell-style \texttt{glob} patterns}
-
-This is an overview of the kinds of patterns you can use when you're
-matching on glob patterns.
-
-The ``\texttt{*}'' character matches any string, within a single
-directory.
-\interaction{filenames.glob.star}
-
-The ``\texttt{**}'' pattern matches any string, and crosses directory
-boundaries.  It's not a standard Unix glob token, but it's accepted by
-several popular Unix shells, and is very useful.
-\interaction{filenames.glob.starstar}
-
-The ``\texttt{?}'' pattern matches any single character.
-\interaction{filenames.glob.question}
-
-The ``\texttt{[}'' character begins a \emph{character class}.  This
-matches any single character within the class.  The class ends with a
-``\texttt{]}'' character.  A class may contain multiple \emph{range}s
-of the form ``\texttt{a-f}'', which is shorthand for
-``\texttt{abcdef}''.
-\interaction{filenames.glob.range}
-If the first character after the ``\texttt{[}'' in a character class
-is a ``\texttt{!}'', it \emph{negates} the class, making it match any
-single character not in the class.
-
-A ``\texttt{\{}'' begins a group of subpatterns, where the whole group
-matches if any subpattern in the group matches.  The ``\texttt{,}''
-character separates subpatterns, and ``\texttt{\}}'' ends the group.
-\interaction{filenames.glob.group}
-
-\subsubsection{Watch out!}
-
-Don't forget that if you want to match a pattern in any directory, you
-should not be using the ``\texttt{*}'' match-any token, as this will
-only match within one directory.  Instead, use the ``\texttt{**}''
-token.  This small example illustrates the difference between the two.
-\interaction{filenames.glob.star-starstar}
-
-\subsection{Regular expression matching with \texttt{re} patterns}
-
-Mercurial accepts the same regular expression syntax as the Python
-programming language (it uses Python's regexp engine internally).
-This is based on the Perl language's regexp syntax, which is the most
-popular dialect in use (it's also used in Java, for example).
-
-I won't discuss Mercurial's regexp dialect in any detail here, as
-regexps are not often used.  Perl-style regexps are in any case
-already exhaustively documented on a multitude of web sites, and in
-many books.  Instead, I will focus here on a few things you should
-know if you find yourself needing to use regexps with Mercurial.
-
-A regexp is matched against an entire file name, relative to the root
-of the repository.  In other words, even if you're already in
-subbdirectory \dirname{foo}, if you want to match files under this
-directory, your pattern must start with ``\texttt{foo/}''.
-
-One thing to note, if you're familiar with Perl-style regexps, is that
-Mercurial's are \emph{rooted}.  That is, a regexp starts matching
-against the beginning of a string; it doesn't look for a match
-anywhere within the string.  To match anywhere in a string, start
-your pattern with ``\texttt{.*}''.
-
-\section{Filtering files}
-
-Not only does Mercurial give you a variety of ways to specify files;
-it lets you further winnow those files using \emph{filters}.  Commands
-that work with file names accept two filtering options.
-\begin{itemize}
-\item \hggopt{-I}, or \hggopt{--include}, lets you specify a pattern
-  that file names must match in order to be processed.
-\item \hggopt{-X}, or \hggopt{--exclude}, gives you a way to
-  \emph{avoid} processing files, if they match this pattern.
-\end{itemize}
-You can provide multiple \hggopt{-I} and \hggopt{-X} options on the
-command line, and intermix them as you please.  Mercurial interprets
-the patterns you provide using glob syntax by default (but you can use
-regexps if you need to).
-
-You can read a \hggopt{-I} filter as ``process only the files that
-match this filter''.
-\interaction{filenames.filter.include}
-The \hggopt{-X} filter is best read as ``process only the files that
-don't match this pattern''.
-\interaction{filenames.filter.exclude}
-
-\section{Ignoring unwanted files and directories}
-
-XXX.
-
-\section{Case sensitivity}
-\label{sec:names:case}
-
-If you're working in a mixed development environment that contains
-both Linux (or other Unix) systems and Macs or Windows systems, you
-should keep in the back of your mind the knowledge that they treat the
-case (``N'' versus ``n'') of file names in incompatible ways.  This is
-not very likely to affect you, and it's easy to deal with if it does,
-but it could surprise you if you don't know about it.
-
-Operating systems and filesystems differ in the way they handle the
-\emph{case} of characters in file and directory names.  There are
-three common ways to handle case in names.
-\begin{itemize}
-\item Completely case insensitive.  Uppercase and lowercase versions
-  of a letter are treated as identical, both when creating a file and
-  during subsequent accesses.  This is common on older DOS-based
-  systems.
-\item Case preserving, but insensitive.  When a file or directory is
-  created, the case of its name is stored, and can be retrieved and
-  displayed by the operating system.  When an existing file is being
-  looked up, its case is ignored.  This is the standard arrangement on
-  Windows and MacOS.  The names \filename{foo} and \filename{FoO}
-  identify the same file.  This treatment of uppercase and lowercase
-  letters as interchangeable is also referred to as \emph{case
-    folding}.
-\item Case sensitive.  The case of a name is significant at all times.
-  The names \filename{foo} and {FoO} identify different files.  This
-  is the way Linux and Unix systems normally work.
-\end{itemize}
-
-On Unix-like systems, it is possible to have any or all of the above
-ways of handling case in action at once.  For example, if you use a
-USB thumb drive formatted with a FAT32 filesystem on a Linux system,
-Linux will handle names on that filesystem in a case preserving, but
-insensitive, way.
-
-\subsection{Safe, portable repository storage}
-
-Mercurial's repository storage mechanism is \emph{case safe}.  It
-translates file names so that they can be safely stored on both case
-sensitive and case insensitive filesystems.  This means that you can
-use normal file copying tools to transfer a Mercurial repository onto,
-for example, a USB thumb drive, and safely move that drive and
-repository back and forth between a Mac, a PC running Windows, and a
-Linux box.
-
-\subsection{Detecting case conflicts}
-
-When operating in the working directory, Mercurial honours the naming
-policy of the filesystem where the working directory is located.  If
-the filesystem is case preserving, but insensitive, Mercurial will
-treat names that differ only in case as the same.
-
-An important aspect of this approach is that it is possible to commit
-a changeset on a case sensitive (typically Linux or Unix) filesystem
-that will cause trouble for users on case insensitive (usually Windows
-and MacOS) users.  If a Linux user commits changes to two files, one
-named \filename{myfile.c} and the other named \filename{MyFile.C},
-they will be stored correctly in the repository.  And in the working
-directories of other Linux users, they will be correctly represented
-as separate files.
-
-If a Windows or Mac user pulls this change, they will not initially
-have a problem, because Mercurial's repository storage mechanism is
-case safe.  However, once they try to \hgcmd{update} the working
-directory to that changeset, or \hgcmd{merge} with that changeset,
-Mercurial will spot the conflict between the two file names that the
-filesystem would treat as the same, and forbid the update or merge
-from occurring.
-
-\subsection{Fixing a case conflict}
-
-If you are using Windows or a Mac in a mixed environment where some of
-your collaborators are using Linux or Unix, and Mercurial reports a
-case folding conflict when you try to \hgcmd{update} or \hgcmd{merge},
-the procedure to fix the problem is simple.
-
-Just find a nearby Linux or Unix box, clone the problem repository
-onto it, and use Mercurial's \hgcmd{rename} command to change the
-names of any offending files or directories so that they will no
-longer cause case folding conflicts.  Commit this change, \hgcmd{pull}
-or \hgcmd{push} it across to your Windows or MacOS system, and
-\hgcmd{update} to the revision with the non-conflicting names.
-
-The changeset with case-conflicting names will remain in your
-project's history, and you still won't be able to \hgcmd{update} your
-working directory to that changeset on a Windows or MacOS system, but
-you can continue development unimpeded.
-
-\begin{note}
-  Prior to version~0.9.3, Mercurial did not use a case safe repository
-  storage mechanism, and did not detect case folding conflicts.  If
-  you are using an older version of Mercurial on Windows or MacOS, I
-  strongly recommend that you upgrade.
-\end{note}
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/fixhtml.py	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-#
-# This script attempts to work around some of the more bizarre and
-# quirky behaviours of htlatex.
-#
-# - We've persuaded htlatex to produce UTF-8, which unfortunately
-#   causes it to use huge character sequences to represent even the
-#   safe 7-bit ASCII subset of UTF-8.  We fix that up.
-#
-# - BUT we have to treat angle brackets (for example, redirections in
-#   shell script snippets) specially, otherwise they'll break the
-#   generated HTML.  (Reported by Johannes Hoff.)
-#
-# - For some reason, htlatex gives a unique ID to each fancyvrb
-#   environment, which makes writing a sane, small CSS stylesheet
-#   impossible.  We squish all those IDs down to nothing.
-
-import os
-import sys
-import re
-
-angle_re = re.compile(r'(&#x003[CE];)')
-unicode_re = re.compile(r'&#x00([0-7][0-9A-F]);')
-fancyvrb_re = re.compile(r'id="fancyvrb\d+"', re.I)
-ligature_re = re.compile(r'&#xFB0([0-4]);')
-
-tmpsuffix = '.tmp.' + str(os.getpid())
-
-def hide_angle(m):
-    return m.group(1).lower()
-
-def fix_ascii(m):
-    return chr(int(m.group(1), 16))
-
-ligatures = ['ff', 'fi', 'fl', 'ffi', 'ffl']
-
-def expand_ligature(m):
-    return ligatures[int(m.group(1))]
-
-for name in sys.argv[1:]:
-    tmpname = name + tmpsuffix
-    ofp = file(tmpname, 'w')
-    for line in file(name):
-        line = angle_re.sub(hide_angle, line)
-        line = unicode_re.sub(fix_ascii, line)
-        line = ligature_re.sub(expand_ligature, line)
-        line = fancyvrb_re.sub('id="fancyvrb"', line)
-        ofp.write(line)
-    ofp.close()
-    os.rename(tmpname, name)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/fixsvg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+test -d hello || hg clone http://hg.serpentine.com/tutorial/hello
+
+set -e
+
+for i in 0 1 2 3 4
+do
+  export REV$i=$(hg --cwd hello log -r $i --template '{node|short}' | cut -c1-4)
+done
+export REV_my_hello=$(cat /tmp/REV5.my-hello)
+export REV_my_new_hello=$(cat /tmp/REV5.my-new-hello)
+export REV6_my_new_hello=$(cat /tmp/REV6.my-new-hello)
+export REV7_my_new_hello=$(cat /tmp/REV7.my-new-hello)
+
+FILE=$1
+OUTFILE=$FILE-tmp.svg
+rm -f $OUTFILE
+echo "Fixing $FILE"
+cp $FILE $OUTFILE
+perl -p -i -e "s#REV0#$REV0#" $OUTFILE
+perl -p -i -e "s#REV1#$REV1#" $OUTFILE
+perl -p -i -e "s#REV2#$REV2#" $OUTFILE
+perl -p -i -e "s#REV3#$REV3#" $OUTFILE
+perl -p -i -e "s#REV4#$REV4#" $OUTFILE
+perl -p -i -e "s#REV_my_hello#$REV_my_hello#" $OUTFILE
+perl -p -i -e "s#REV_my_new_hello#$REV_my_new_hello#" $OUTFILE
+perl -p -i -e "s#REV6_my_new_hello#$REV6_my_new_hello#" $OUTFILE
+perl -p -i -e "s#REV7_my_new_hello#$REV7_my_new_hello#" $OUTFILE
--- a/en/hgbook.css	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,441 +0,0 @@
-body {
-  font: 12px/1.5 Verdana, sans-serif;
-  padding-top: 50px;
-  padding-left: 80px;
-  padding-right: 80px;
-  padding-bottom: 90px;
-}
-.ptmr7t- {
-  font-family: monospace;
-}
-.ptmr7t-x-x-172 {
-  font-size: 172%;
-  font-family: monospace;
-}
-.ptmr7t-x-x-120 {
-  font-size: 120%;
-}
-.zpzccmry-x-x-120 {
-  font-size: 120%;
-  font-weight: bold;
-  font-style: italic;
-}
-.zpzccmry-x-x-120 {
-  font-weight: bold;
-  font-style: italic;
-}
-.pcrr7tn- {
-  font-family: monospace;
-}
-.ptmri7t- {
-  font-style: italic;
-}
-.ptmr7t-x-x-50 {
-  font-size: 50%;
-  font-family: monospace;
-}
-.ptmb7t- {
-  font-weight: bold;
-}
-.zptmcmr- {
-  font-style: italic;
-}
-.zptmcmrm- {
-  font-style: italic;
-}
-.zpzccmry- {
-  font-weight: bold;
-  font-style: italic;
-}
-.pcrb7t- {
-  font-family: monospace;
-  font-weight: bold;
-}
-.pcrro7t- {
-  font-family: monospace;
-  font-style: oblique;
-}
-p.noindent {
-  text-indent: 0em;
-  margin: 0em;
-}
-p.nopar {
-  text-indent: 0em;
-}
-p.indent {
-  text-indent: 1.5em;
-  margin: 0em;
-}
-a img {
-  border-top: 0;
-  border-left: 0;
-  border-right: 0;
-}
-center {
-  margin-top: 1em;
-  margin-bottom: 1em;
-}
-td center {
-  margin-top: 0em;
-  margin-bottom: 0em;
-}
-.Canvas {
-  position: relative;
-}
-img.math {
-  vertical-align: middle;
-}
-li p.indent {
-  text-indent: 0em;
-}
-.enumerate1 {
-  list-style-type: decimal;
-}
-.enumerate2 {
-  list-style-type: lower-alpha;
-}
-.enumerate3 {
-  list-style-type: lower-roman;
-}
-.enumerate4 {
-  list-style-type: upper-alpha;
-}
-div.newtheorem {
-  margin-bottom: 2em;
-  margin-top: 2em;
-}
-.obeylines-h,.obeylines-v {
-  white-space: nowrap;
-}
-div.obeylines-v p {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.overline {
-  text-decoration: overline;
-}
-.overline img {
-  border-top: 1px solid black;
-}
-td.displaylines {
-  text-align: center;
-  white-space: nowrap;
-}
-.centerline {
-  text-align: center;
-}
-.rightline {
-  text-align: right;
-}
-div.verbatim {
-  font-family: monospace;
-  white-space: nowrap;
-}
-table.verbatim {
-  width: 100%;
-}
-.fbox {
-  background: url(note.png) no-repeat #cec;
-  padding-left: 65px;
-  padding-top: 1em;
-  padding-bottom: 1em;
-  padding-right: 1em;
-  text-indent: 0pt;
-  border: dotted black 1px;
-}
-div.center div.fbox {
-  text-align: center;
-  clear: both;
-  padding-left: 3.0pt;
-  padding-right: 3.0pt;
-  text-indent: 0pt;
-  border: solid black 0.4pt;
-}
-table.minipage {
-  width: 100%;
-}
-div.center, div.center div.center {
-  text-align: center;
-  margin-left: 1em;
-  margin-right: 1em;
-}
-div.center div {
-  text-align: left;
-}
-div.flushright, div.flushright div.flushright {
-  text-align: right;
-}
-div.flushright div {
-  text-align: left;
-}
-div.flushleft {
-  text-align: left;
-}
-.underline {
-  text-decoration: underline;
-}
-.underline img {
-  border-bottom: 1px solid black;
-  margin-bottom: 1pt;
-}
-.framebox-c, .framebox-l, .framebox-r {
-  padding-left: 3.0pt;
-  padding-right: 3.0pt;
-  text-indent: 0pt;
-  border: solid black 0.4pt;
-}
-.framebox-c {
-  text-align: center;
-}
-.framebox-l {
-  text-align: left;
-}
-.framebox-r {
-  text-align: right;
-}
-span.thank-mark {
-  vertical-align: super
-}
-span.footnote-mark sup.textsuperscript, span.footnote-mark a sup.textsuperscript {
-  font-size: 80%;
-}
-div.tabular, div.center div.tabular {
-  text-align: center;
-  margin-top: 0.5em;
-  margin-bottom: 0.5em;
-}
-table.tabular td p {
-  margin-top: 0em;
-}
-table.tabular {
-  margin-left: auto;
-  margin-right: auto;
-}
-div.td00 {
-  margin-left: 0pt;
-  margin-right: 0pt;
-}
-div.td01 {
-  margin-left: 0pt;
-  margin-right: 5pt;
-}
-div.td10 {
-  margin-left: 5pt;
-  margin-right: 0pt;
-}
-div.td11 {
-  margin-left: 5pt;
-  margin-right: 5pt;
-}
-table[rules] {
-  border-left: solid black 0.4pt;
-  border-right: solid black 0.4pt;
-}
-td.td00 {
-  padding-left: 0pt;
-  padding-right: 0pt;
-}
-td.td01 {
-  padding-left: 0pt;
-  padding-right: 5pt;
-}
-td.td10 {
-  padding-left: 5pt;
-  padding-right: 0pt;
-}
-td.td11 {
-  padding-left: 5pt;
-  padding-right: 5pt;
-}
-table[rules] {
-  border-left: solid black 0.4pt;
-  border-right: solid black 0.4pt;
-}
-.hline hr, .cline hr {
-  height : 1px;
-  margin: 0px;
-}
-.tabbing-right {
-  text-align: right;
-}
-span.TEX {
-  letter-spacing: -0.125em;
-}
-span.TEX span.E {
-  position: relative;top: 0.5ex;left: -0.0417em;
-}
-a span.TEX span.E {
-  text-decoration: none;
-}
-span.LATEX span.A {
-  position: relative;
-  top: -0.5ex;
-  left: -0.4em;
-  font-size: 85%;
-}
-span.LATEX span.TEX {
-  position: relative;
-  left: -0.4em;
-}
-div.float img, div.float .caption {
-  text-align: center;
-}
-div.figure img, div.figure .caption {
-  text-align: center;
-}
-.marginpar {
-  width: 20%;
-  float: right;
-  text-align: left;
-  margin-left: auto;
-  margin-top: 0.5em;
-  font-size: 85%;
-  text-decoration: underline;
-}
-.marginpar p {
-  margin-top: 0.4em;
-  margin-bottom: 0.4em;
-}
-table.equation {
-  width: 100%;
-}
-.equation td {
-  text-align: center;
-}
-td.equation {
-  margin-top: 1em;
-  margin-bottom: 1em;
-} 
-td.equation-label {
-  width: 5%;
-  text-align: center;
-}
-td.eqnarray4 {
-  width: 5%;
-  white-space: normal;
-}
-td.eqnarray2 {
-  width: 5%;
-}
-table.eqnarray-star, table.eqnarray {
-  width: 100%;
-}
-div.eqnarray {
-  text-align: center;
-}
-div.array {
-  text-align: center;
-}
-div.pmatrix {
-  text-align: center;
-}
-table.pmatrix {
-  width: 100%;
-}
-span.pmatrix img {
-  vertical-align: middle;
-}
-div.pmatrix {
-  text-align: center;
-}
-table.pmatrix {
-  width: 100%;
-}
-img.cdots {
-  vertical-align: middle;
-}
-.partToc a, .partToc, .likepartToc a, .likepartToc {
-  line-height: 200%;
-  font-weight: bold;
-  font-size: 110%;
-}
-.chapterToc a, .chapterToc, .likechapterToc a, .likechapterToc, .appendixToc a, .appendixToc {
-  line-height: 200%;
-  font-weight: bold;
-}
-.caption td.id {
-  font-weight: bold;
-  white-space: nowrap;
-}
-table.caption {
-  text-align: center;
-}
-h1.partHead {
-  text-align: center;
-}
-p.bibitem {
-  text-indent: -2em;
-  margin-left: 2em;
-  margin-top: 0.6em;
-  margin-bottom: 0.6em;
-}
-p.bibitem-p {
-  text-indent: 0em;
-  margin-left: 2em;
-  margin-top: 0.6em;
-  margin-bottom: 0.6em;
-}
-.paragraphHead, .likeparagraphHead {
-  margin-top: 2em;
-  font-weight: bold;
-}
-.subparagraphHead, .likesubparagraphHead {
-  font-weight: bold;
-}
-.quote {
-  margin-bottom: 0.25em;
-  margin-top: 0.25em;
-  margin-left: 1em;
-  margin-right: 1em;
-  text-align: justify;
-}
-.verse {
-  white-space: nowrap;
-  margin-left: 2em}
-div.maketitle {
-  text-align: center;
-}
-h2.titleHead {
-  text-align: center;
-}
-div.maketitle {
-  margin-bottom: 2em;
-}
-div.author, div.date {
-  text-align: center;
-}
-div.thanks {
-  text-align: left;
-  margin-left: 10%;
-  font-size: 85%;
-  font-style: italic;
-}
-div.author {
-  white-space: nowrap;
-}
-.quotation {
-  margin-bottom: 0.25em;
-  margin-top: 0.25em;
-  margin-left: 1em;
-}
-h1.partHead {
-  text-align: center;
-}
-img.graphics {
-  margin-left: 10%;
-}
-.figure {
-  width: 100%;
-}
-P.fancyvrb {
-  white-space: nowrap;
-}
-hr {
-  border: 0;
-  height: 1px;
-}
-div#fancyvrb {
-  white-space: nowrap;
-  background: #eee;
-  padding: 1em;
-}
--- a/en/hgext.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-\chapter{Adding functionality with extensions}
-\label{chap:hgext}
-
-While the core of Mercurial is quite complete from a functionality
-standpoint, it's deliberately shorn of fancy features.  This approach
-of preserving simplicity keeps the software easy to deal with for both
-maintainers and users.
-
-However, Mercurial doesn't box you in with an inflexible command set:
-you can add features to it as \emph{extensions} (sometimes known as
-\emph{plugins}).  We've already discussed a few of these extensions in
-earlier chapters.
-\begin{itemize}
-\item Section~\ref{sec:tour-merge:fetch} covers the \hgext{fetch}
-  extension; this combines pulling new changes and merging them with
-  local changes into a single command, \hgxcmd{fetch}{fetch}.
-\item In chapter~\ref{chap:hook}, we covered several extensions that
-  are useful for hook-related functionality: \hgext{acl} adds access
-  control lists; \hgext{bugzilla} adds integration with the Bugzilla
-  bug tracking system; and \hgext{notify} sends notification emails on
-  new changes.
-\item The Mercurial Queues patch management extension is so invaluable
-  that it merits two chapters and an appendix all to itself.
-  Chapter~\ref{chap:mq} covers the basics;
-  chapter~\ref{chap:mq-collab} discusses advanced topics; and
-  appendix~\ref{chap:mqref} goes into detail on each command.
-\end{itemize}
-
-In this chapter, we'll cover some of the other extensions that are
-available for Mercurial, and briefly touch on some of the machinery
-you'll need to know about if you want to write an extension of your
-own.
-\begin{itemize}
-\item In section~\ref{sec:hgext:inotify}, we'll discuss the
-  possibility of \emph{huge} performance improvements using the
-  \hgext{inotify} extension.
-\end{itemize}
-
-\section{Improve performance with the \hgext{inotify} extension}
-\label{sec:hgext:inotify}
-
-Are you interested in having some of the most common Mercurial
-operations run as much as a hundred times faster?  Read on!
-
-Mercurial has great performance under normal circumstances.  For
-example, when you run the \hgcmd{status} command, Mercurial has to
-scan almost every directory and file in your repository so that it can
-display file status.  Many other Mercurial commands need to do the
-same work behind the scenes; for example, the \hgcmd{diff} command
-uses the status machinery to avoid doing an expensive comparison
-operation on files that obviously haven't changed.
-
-Because obtaining file status is crucial to good performance, the
-authors of Mercurial have optimised this code to within an inch of its
-life.  However, there's no avoiding the fact that when you run
-\hgcmd{status}, Mercurial is going to have to perform at least one
-expensive system call for each managed file to determine whether it's
-changed since the last time Mercurial checked.  For a sufficiently
-large repository, this can take a long time.
-
-To put a number on the magnitude of this effect, I created a
-repository containing 150,000 managed files.  I timed \hgcmd{status}
-as taking ten seconds to run, even when \emph{none} of those files had
-been modified.
-
-Many modern operating systems contain a file notification facility.
-If a program signs up to an appropriate service, the operating system
-will notify it every time a file of interest is created, modified, or
-deleted.  On Linux systems, the kernel component that does this is
-called \texttt{inotify}.
-
-Mercurial's \hgext{inotify} extension talks to the kernel's
-\texttt{inotify} component to optimise \hgcmd{status} commands.  The
-extension has two components.  A daemon sits in the background and
-receives notifications from the \texttt{inotify} subsystem.  It also
-listens for connections from a regular Mercurial command.  The
-extension modifies Mercurial's behaviour so that instead of scanning
-the filesystem, it queries the daemon.  Since the daemon has perfect
-information about the state of the repository, it can respond with a
-result instantaneously, avoiding the need to scan every directory and
-file in the repository.
-
-Recall the ten seconds that I measured plain Mercurial as taking to
-run \hgcmd{status} on a 150,000 file repository.  With the
-\hgext{inotify} extension enabled, the time dropped to 0.1~seconds, a
-factor of \emph{one hundred} faster.
-
-Before we continue, please pay attention to some caveats.
-\begin{itemize}
-\item The \hgext{inotify} extension is Linux-specific.  Because it
-  interfaces directly to the Linux kernel's \texttt{inotify}
-  subsystem, it does not work on other operating systems.
-\item It should work on any Linux distribution that was released after
-  early~2005.  Older distributions are likely to have a kernel that
-  lacks \texttt{inotify}, or a version of \texttt{glibc} that does not
-  have the necessary interfacing support.
-\item Not all filesystems are suitable for use with the
-  \hgext{inotify} extension.  Network filesystems such as NFS are a
-  non-starter, for example, particularly if you're running Mercurial
-  on several systems, all mounting the same network filesystem.  The
-  kernel's \texttt{inotify} system has no way of knowing about changes
-  made on another system.  Most local filesystems (e.g.~ext3, XFS,
-  ReiserFS) should work fine.
-\end{itemize}
-
-The \hgext{inotify} extension is not yet shipped with Mercurial as of
-May~2007, so it's a little more involved to set up than other
-extensions.  But the performance improvement is worth it!
-
-The extension currently comes in two parts: a set of patches to the
-Mercurial source code, and a library of Python bindings to the
-\texttt{inotify} subsystem.
-\begin{note}
-  There are \emph{two} Python \texttt{inotify} binding libraries.  One
-  of them is called \texttt{pyinotify}, and is packaged by some Linux
-  distributions as \texttt{python-inotify}.  This is \emph{not} the
-  one you'll need, as it is too buggy and inefficient to be practical.
-\end{note}
-To get going, it's best to already have a functioning copy of
-Mercurial installed.
-\begin{note}
-  If you follow the instructions below, you'll be \emph{replacing} and
-  overwriting any existing installation of Mercurial that you might
-  already have, using the latest ``bleeding edge'' Mercurial code.
-  Don't say you weren't warned!
-\end{note}
-\begin{enumerate}
-\item Clone the Python \texttt{inotify} binding repository.  Build and
-  install it.
-  \begin{codesample4}
-    hg clone http://hg.kublai.com/python/inotify
-    cd inotify
-    python setup.py build --force
-    sudo python setup.py install --skip-build
-  \end{codesample4}
-\item Clone the \dirname{crew} Mercurial repository.  Clone the
-  \hgext{inotify} patch repository so that Mercurial Queues will be
-  able to apply patches to your cope of the \dirname{crew} repository.
-  \begin{codesample4}
-    hg clone http://hg.intevation.org/mercurial/crew
-    hg clone crew inotify
-    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
-  \end{codesample4}
-\item Make sure that you have the Mercurial Queues extension,
-  \hgext{mq}, enabled.  If you've never used MQ, read
-  section~\ref{sec:mq:start} to get started quickly.
-\item Go into the \dirname{inotify} repo, and apply all of the
-  \hgext{inotify} patches using the \hgxopt{mq}{qpush}{-a} option to
-  the \hgxcmd{mq}{qpush} command.
-  \begin{codesample4}
-    cd inotify
-    hg qpush -a
-  \end{codesample4}
-  If you get an error message from \hgxcmd{mq}{qpush}, you should not
-  continue.  Instead, ask for help.
-\item Build and install the patched version of Mercurial.
-  \begin{codesample4}
-    python setup.py build --force
-    sudo python setup.py install --skip-build
-  \end{codesample4}
-\end{enumerate}
-Once you've build a suitably patched version of Mercurial, all you
-need to do to enable the \hgext{inotify} extension is add an entry to
-your \hgrc.
-\begin{codesample2}
-  [extensions]
-  inotify =
-\end{codesample2}
-When the \hgext{inotify} extension is enabled, Mercurial will
-automatically and transparently start the status daemon the first time
-you run a command that needs status in a repository.  It runs one
-status daemon per repository.
-
-The status daemon is started silently, and runs in the background.  If
-you look at a list of running processes after you've enabled the
-\hgext{inotify} extension and run a few commands in different
-repositories, you'll thus see a few \texttt{hg} processes sitting
-around, waiting for updates from the kernel and queries from
-Mercurial.
-
-The first time you run a Mercurial command in a repository when you
-have the \hgext{inotify} extension enabled, it will run with about the
-same performance as a normal Mercurial command.  This is because the
-status daemon needs to perform a normal status scan so that it has a
-baseline against which to apply later updates from the kernel.
-However, \emph{every} subsequent command that does any kind of status
-check should be noticeably faster on repositories of even fairly
-modest size.  Better yet, the bigger your repository is, the greater a
-performance advantage you'll see.  The \hgext{inotify} daemon makes
-status operations almost instantaneous on repositories of all sizes!
-
-If you like, you can manually start a status daemon using the
-\hgxcmd{inotify}{inserve} command.  This gives you slightly finer
-control over how the daemon ought to run.  This command will of course
-only be available when the \hgext{inotify} extension is enabled.
-
-When you're using the \hgext{inotify} extension, you should notice
-\emph{no difference at all} in Mercurial's behaviour, with the sole
-exception of status-related commands running a whole lot faster than
-they used to.  You should specifically expect that commands will not
-print different output; neither should they give different results.
-If either of these situations occurs, please report a bug.
-
-\section{Flexible diff support with the \hgext{extdiff} extension}
-\label{sec:hgext:extdiff}
-
-Mercurial's built-in \hgcmd{diff} command outputs plaintext unified
-diffs.
-\interaction{extdiff.diff}
-If you would like to use an external tool to display modifications,
-you'll want to use the \hgext{extdiff} extension.  This will let you
-use, for example, a graphical diff tool.
-
-The \hgext{extdiff} extension is bundled with Mercurial, so it's easy
-to set up.  In the \rcsection{extensions} section of your \hgrc,
-simply add a one-line entry to enable the extension.
-\begin{codesample2}
-  [extensions]
-  extdiff =
-\end{codesample2}
-This introduces a command named \hgxcmd{extdiff}{extdiff}, which by
-default uses your system's \command{diff} command to generate a
-unified diff in the same form as the built-in \hgcmd{diff} command.
-\interaction{extdiff.extdiff}
-The result won't be exactly the same as with the built-in \hgcmd{diff}
-variations, because the output of \command{diff} varies from one
-system to another, even when passed the same options.
-
-As the ``\texttt{making snapshot}'' lines of output above imply, the
-\hgxcmd{extdiff}{extdiff} command works by creating two snapshots of
-your source tree.  The first snapshot is of the source revision; the
-second, of the target revision or working directory.  The
-\hgxcmd{extdiff}{extdiff} command generates these snapshots in a
-temporary directory, passes the name of each directory to an external
-diff viewer, then deletes the temporary directory.  For efficiency, it
-only snapshots the directories and files that have changed between the
-two revisions.
-
-Snapshot directory names have the same base name as your repository.
-If your repository path is \dirname{/quux/bar/foo}, then \dirname{foo}
-will be the name of each snapshot directory.  Each snapshot directory
-name has its changeset ID appended, if appropriate.  If a snapshot is
-of revision \texttt{a631aca1083f}, the directory will be named
-\dirname{foo.a631aca1083f}.  A snapshot of the working directory won't
-have a changeset ID appended, so it would just be \dirname{foo} in
-this example.  To see what this looks like in practice, look again at
-the \hgxcmd{extdiff}{extdiff} example above.  Notice that the diff has
-the snapshot directory names embedded in its header.
-
-The \hgxcmd{extdiff}{extdiff} command accepts two important options.
-The \hgxopt{extdiff}{extdiff}{-p} option lets you choose a program to
-view differences with, instead of \command{diff}.  With the
-\hgxopt{extdiff}{extdiff}{-o} option, you can change the options that
-\hgxcmd{extdiff}{extdiff} passes to the program (by default, these
-options are ``\texttt{-Npru}'', which only make sense if you're
-running \command{diff}).  In other respects, the
-\hgxcmd{extdiff}{extdiff} command acts similarly to the built-in
-\hgcmd{diff} command: you use the same option names, syntax, and
-arguments to specify the revisions you want, the files you want, and
-so on.
-
-As an example, here's how to run the normal system \command{diff}
-command, getting it to generate context diffs (using the
-\cmdopt{diff}{-c} option) instead of unified diffs, and five lines of
-context instead of the default three (passing \texttt{5} as the
-argument to the \cmdopt{diff}{-C} option).
-\interaction{extdiff.extdiff-ctx}
-
-Launching a visual diff tool is just as easy.  Here's how to launch
-the \command{kdiff3} viewer.
-\begin{codesample2}
-  hg extdiff -p kdiff3 -o ''
-\end{codesample2}
-
-If your diff viewing command can't deal with directories, you can
-easily work around this with a little scripting.  For an example of
-such scripting in action with the \hgext{mq} extension and the
-\command{interdiff} command, see
-section~\ref{mq-collab:tips:interdiff}.
-
-\subsection{Defining command aliases}
-
-It can be cumbersome to remember the options to both the
-\hgxcmd{extdiff}{extdiff} command and the diff viewer you want to use,
-so the \hgext{extdiff} extension lets you define \emph{new} commands
-that will invoke your diff viewer with exactly the right options.
-
-All you need to do is edit your \hgrc, and add a section named
-\rcsection{extdiff}.  Inside this section, you can define multiple
-commands.  Here's how to add a \texttt{kdiff3} command.  Once you've
-defined this, you can type ``\texttt{hg kdiff3}'' and the
-\hgext{extdiff} extension will run \command{kdiff3} for you.
-\begin{codesample2}
-  [extdiff]
-  cmd.kdiff3 =
-\end{codesample2}
-If you leave the right hand side of the definition empty, as above,
-the \hgext{extdiff} extension uses the name of the command you defined
-as the name of the external program to run.  But these names don't
-have to be the same.  Here, we define a command named ``\texttt{hg
-  wibble}'', which runs \command{kdiff3}.
-\begin{codesample2}
-  [extdiff]
-  cmd.wibble = kdiff3
-\end{codesample2}
-
-You can also specify the default options that you want to invoke your
-diff viewing program with.  The prefix to use is ``\texttt{opts.}'',
-followed by the name of the command to which the options apply.  This
-example defines a ``\texttt{hg vimdiff}'' command that runs the
-\command{vim} editor's \texttt{DirDiff} extension.
-\begin{codesample2}
-  [extdiff]  
-  cmd.vimdiff = vim
-  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
-\end{codesample2}
-
-\section{Cherrypicking changes with the \hgext{transplant} extension}
-\label{sec:hgext:transplant}
-
-Need to have a long chat with Brendan about this.
-
-\section{Send changes via email with the \hgext{patchbomb} extension}
-\label{sec:hgext:patchbomb}
-
-Many projects have a culture of ``change review'', in which people
-send their modifications to a mailing list for others to read and
-comment on before they commit the final version to a shared
-repository.  Some projects have people who act as gatekeepers; they
-apply changes from other people to a repository to which those others
-don't have access.
-
-Mercurial makes it easy to send changes over email for review or
-application, via its \hgext{patchbomb} extension.  The extension is so
-namd because changes are formatted as patches, and it's usual to send
-one changeset per email message.  Sending a long series of changes by
-email is thus much like ``bombing'' the recipient's inbox, hence
-``patchbomb''.
-
-As usual, the basic configuration of the \hgext{patchbomb} extension
-takes just one or two lines in your \hgrc.
-\begin{codesample2}
-  [extensions]
-  patchbomb =
-\end{codesample2}
-Once you've enabled the extension, you will have a new command
-available, named \hgxcmd{patchbomb}{email}.
-
-The safest and best way to invoke the \hgxcmd{patchbomb}{email}
-command is to \emph{always} run it first with the
-\hgxopt{patchbomb}{email}{-n} option.  This will show you what the
-command \emph{would} send, without actually sending anything.  Once
-you've had a quick glance over the changes and verified that you are
-sending the right ones, you can rerun the same command, with the
-\hgxopt{patchbomb}{email}{-n} option removed.
-
-The \hgxcmd{patchbomb}{email} command accepts the same kind of
-revision syntax as every other Mercurial command.  For example, this
-command will send every revision between 7 and \texttt{tip},
-inclusive.
-\begin{codesample2}
-  hg email -n 7:tip
-\end{codesample2}
-You can also specify a \emph{repository} to compare with.  If you
-provide a repository but no revisions, the \hgxcmd{patchbomb}{email}
-command will send all revisions in the local repository that are not
-present in the remote repository.  If you additionally specify
-revisions or a branch name (the latter using the
-\hgxopt{patchbomb}{email}{-b} option), this will constrain the
-revisions sent.
-
-It's perfectly safe to run the \hgxcmd{patchbomb}{email} command
-without the names of the people you want to send to: if you do this,
-it will just prompt you for those values interactively.  (If you're
-using a Linux or Unix-like system, you should have enhanced
-\texttt{readline}-style editing capabilities when entering those
-headers, too, which is useful.)
-
-When you are sending just one revision, the \hgxcmd{patchbomb}{email}
-command will by default use the first line of the changeset
-description as the subject of the single email message it sends.
-
-If you send multiple revisions, the \hgxcmd{patchbomb}{email} command
-will usually send one message per changeset.  It will preface the
-series with an introductory message, in which you should describe the
-purpose of the series of changes you're sending.
-
-\subsection{Changing the behaviour of patchbombs}
-
-Not every project has exactly the same conventions for sending changes
-in email; the \hgext{patchbomb} extension tries to accommodate a
-number of variations through command line options.
-\begin{itemize}
-\item You can write a subject for the introductory message on the
-  command line using the \hgxopt{patchbomb}{email}{-s} option.  This
-  takes one argument, the text of the subject to use.
-\item To change the email address from which the messages originate,
-  use the \hgxopt{patchbomb}{email}{-f} option.  This takes one
-  argument, the email address to use.
-\item The default behaviour is to send unified diffs (see
-  section~\ref{sec:mq:patch} for a description of the format), one per
-  message.  You can send a binary bundle instead with the
-  \hgxopt{patchbomb}{email}{-b} option.  
-\item Unified diffs are normally prefaced with a metadata header.  You
-  can omit this, and send unadorned diffs, with the
-  \hgxopt{patchbomb}{email}{--plain} option.
-\item Diffs are normally sent ``inline'', in the same body part as the
-  description of a patch.  This makes it easiest for the largest
-  number of readers to quote and respond to parts of a diff, as some
-  mail clients will only quote the first MIME body part in a message.
-  If you'd prefer to send the description and the diff in separate
-  body parts, use the \hgxopt{patchbomb}{email}{-a} option.
-\item Instead of sending mail messages, you can write them to an
-  \texttt{mbox}-format mail folder using the
-  \hgxopt{patchbomb}{email}{-m} option.  That option takes one
-  argument, the name of the file to write to.
-\item If you would like to add a \command{diffstat}-format summary to
-  each patch, and one to the introductory message, use the
-  \hgxopt{patchbomb}{email}{-d} option.  The \command{diffstat}
-  command displays a table containing the name of each file patched,
-  the number of lines affected, and a histogram showing how much each
-  file is modified.  This gives readers a qualitative glance at how
-  complex a patch is.
-\end{itemize}
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/hook.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1413 +0,0 @@
-\chapter{Handling repository events with hooks}
-\label{chap:hook}
-
-Mercurial offers a powerful mechanism to let you perform automated
-actions in response to events that occur in a repository.  In some
-cases, you can even control Mercurial's response to those events.
-
-The name Mercurial uses for one of these actions is a \emph{hook}.
-Hooks are called ``triggers'' in some revision control systems, but
-the two names refer to the same idea.
-
-\section{An overview of hooks in Mercurial}
-
-Here is a brief list of the hooks that Mercurial supports.  We will
-revisit each of these hooks in more detail later, in
-section~\ref{sec:hook:ref}.
-
-\begin{itemize}
-\item[\small\hook{changegroup}] This is run after a group of
-  changesets has been brought into the repository from elsewhere.
-\item[\small\hook{commit}] This is run after a new changeset has been
-  created in the local repository.
-\item[\small\hook{incoming}] This is run once for each new changeset
-  that is brought into the repository from elsewhere.  Notice the
-  difference from \hook{changegroup}, which is run once per
-  \emph{group} of changesets brought in.
-\item[\small\hook{outgoing}] This is run after a group of changesets
-  has been transmitted from this repository.
-\item[\small\hook{prechangegroup}] This is run before starting to
-  bring a group of changesets into the repository.
-\item[\small\hook{precommit}] Controlling. This is run before starting
-  a commit.
-\item[\small\hook{preoutgoing}] Controlling. This is run before
-  starting to transmit a group of changesets from this repository.
-\item[\small\hook{pretag}] Controlling. This is run before creating a tag.
-\item[\small\hook{pretxnchangegroup}] Controlling. This is run after a
-  group of changesets has been brought into the local repository from
-  another, but before the transaction completes that will make the
-  changes permanent in the repository.
-\item[\small\hook{pretxncommit}] Controlling. This is run after a new
-  changeset has been created in the local repository, but before the
-  transaction completes that will make it permanent.
-\item[\small\hook{preupdate}] Controlling. This is run before starting
-  an update or merge of the working directory.
-\item[\small\hook{tag}] This is run after a tag is created.
-\item[\small\hook{update}] This is run after an update or merge of the
-  working directory has finished.
-\end{itemize}
-Each of the hooks whose description begins with the word
-``Controlling'' has the ability to determine whether an activity can
-proceed.  If the hook succeeds, the activity may proceed; if it fails,
-the activity is either not permitted or undone, depending on the hook.
-
-\section{Hooks and security}
-
-\subsection{Hooks are run with your privileges}
-
-When you run a Mercurial command in a repository, and the command
-causes a hook to run, that hook runs on \emph{your} system, under
-\emph{your} user account, with \emph{your} privilege level.  Since
-hooks are arbitrary pieces of executable code, you should treat them
-with an appropriate level of suspicion.  Do not install a hook unless
-you are confident that you know who created it and what it does.
-
-In some cases, you may be exposed to hooks that you did not install
-yourself.  If you work with Mercurial on an unfamiliar system,
-Mercurial will run hooks defined in that system's global \hgrc\ file.
-
-If you are working with a repository owned by another user, Mercurial
-can run hooks defined in that user's repository, but it will still run
-them as ``you''.  For example, if you \hgcmd{pull} from that
-repository, and its \sfilename{.hg/hgrc} defines a local
-\hook{outgoing} hook, that hook will run under your user account, even
-though you don't own that repository.
-
-\begin{note}
-  This only applies if you are pulling from a repository on a local or
-  network filesystem.  If you're pulling over http or ssh, any
-  \hook{outgoing} hook will run under whatever account is executing
-  the server process, on the server.
-\end{note}
-
-XXX To see what hooks are defined in a repository, use the
-\hgcmdargs{config}{hooks} command.  If you are working in one
-repository, but talking to another that you do not own (e.g.~using
-\hgcmd{pull} or \hgcmd{incoming}), remember that it is the other
-repository's hooks you should be checking, not your own.
-
-\subsection{Hooks do not propagate}
-
-In Mercurial, hooks are not revision controlled, and do not propagate
-when you clone, or pull from, a repository.  The reason for this is
-simple: a hook is a completely arbitrary piece of executable code.  It
-runs under your user identity, with your privilege level, on your
-machine.
-
-It would be extremely reckless for any distributed revision control
-system to implement revision-controlled hooks, as this would offer an
-easily exploitable way to subvert the accounts of users of the
-revision control system.
-
-Since Mercurial does not propagate hooks, if you are collaborating
-with other people on a common project, you should not assume that they
-are using the same Mercurial hooks as you are, or that theirs are
-correctly configured.  You should document the hooks you expect people
-to use.
-
-In a corporate intranet, this is somewhat easier to control, as you
-can for example provide a ``standard'' installation of Mercurial on an
-NFS filesystem, and use a site-wide \hgrc\ file to define hooks that
-all users will see.  However, this too has its limits; see below.
-
-\subsection{Hooks can be overridden}
-
-Mercurial allows you to override a hook definition by redefining the
-hook.  You can disable it by setting its value to the empty string, or
-change its behaviour as you wish.
-
-If you deploy a system-~or site-wide \hgrc\ file that defines some
-hooks, you should thus understand that your users can disable or
-override those hooks.
-
-\subsection{Ensuring that critical hooks are run}
-
-Sometimes you may want to enforce a policy that you do not want others
-to be able to work around.  For example, you may have a requirement
-that every changeset must pass a rigorous set of tests.  Defining this
-requirement via a hook in a site-wide \hgrc\ won't work for remote
-users on laptops, and of course local users can subvert it at will by
-overriding the hook.
-
-Instead, you can set up your policies for use of Mercurial so that
-people are expected to propagate changes through a well-known
-``canonical'' server that you have locked down and configured
-appropriately.
-
-One way to do this is via a combination of social engineering and
-technology.  Set up a restricted-access account; users can push
-changes over the network to repositories managed by this account, but
-they cannot log into the account and run normal shell commands.  In
-this scenario, a user can commit a changeset that contains any old
-garbage they want.
-
-When someone pushes a changeset to the server that everyone pulls
-from, the server will test the changeset before it accepts it as
-permanent, and reject it if it fails to pass the test suite.  If
-people only pull changes from this filtering server, it will serve to
-ensure that all changes that people pull have been automatically
-vetted.
-
-\section{Care with \texttt{pretxn} hooks in a shared-access repository}
-
-If you want to use hooks to do some automated work in a repository
-that a number of people have shared access to, you need to be careful
-in how you do this.
-
-Mercurial only locks a repository when it is writing to the
-repository, and only the parts of Mercurial that write to the
-repository pay attention to locks.  Write locks are necessary to
-prevent multiple simultaneous writers from scribbling on each other's
-work, corrupting the repository.
-
-Because Mercurial is careful with the order in which it reads and
-writes data, it does not need to acquire a lock when it wants to read
-data from the repository.  The parts of Mercurial that read from the
-repository never pay attention to locks.  This lockless reading scheme
-greatly increases performance and concurrency.
-
-With great performance comes a trade-off, though, one which has the
-potential to cause you trouble unless you're aware of it.  To describe
-this requires a little detail about how Mercurial adds changesets to a
-repository and reads those changes.
-
-When Mercurial \emph{writes} metadata, it writes it straight into the
-destination file.  It writes file data first, then manifest data
-(which contains pointers to the new file data), then changelog data
-(which contains pointers to the new manifest data).  Before the first
-write to each file, it stores a record of where the end of the file
-was in its transaction log.  If the transaction must be rolled back,
-Mercurial simply truncates each file back to the size it was before the
-transaction began.
-
-When Mercurial \emph{reads} metadata, it reads the changelog first,
-then everything else.  Since a reader will only access parts of the
-manifest or file metadata that it can see in the changelog, it can
-never see partially written data.
-
-Some controlling hooks (\hook{pretxncommit} and
-\hook{pretxnchangegroup}) run when a transaction is almost complete.
-All of the metadata has been written, but Mercurial can still roll the
-transaction back and cause the newly-written data to disappear.
-
-If one of these hooks runs for long, it opens a window of time during
-which a reader can see the metadata for changesets that are not yet
-permanent, and should not be thought of as ``really there''.  The
-longer the hook runs, the longer that window is open.
-
-\subsection{The problem illustrated}
-
-In principle, a good use for the \hook{pretxnchangegroup} hook would
-be to automatically build and test incoming changes before they are
-accepted into a central repository.  This could let you guarantee that
-nobody can push changes to this repository that ``break the build''.
-But if a client can pull changes while they're being tested, the
-usefulness of the test is zero; an unsuspecting someone can pull
-untested changes, potentially breaking their build.
-
-The safest technological answer to this challenge is to set up such a
-``gatekeeper'' repository as \emph{unidirectional}.  Let it take
-changes pushed in from the outside, but do not allow anyone to pull
-changes from it (use the \hook{preoutgoing} hook to lock it down).
-Configure a \hook{changegroup} hook so that if a build or test
-succeeds, the hook will push the new changes out to another repository
-that people \emph{can} pull from.
-
-In practice, putting a centralised bottleneck like this in place is
-not often a good idea, and transaction visibility has nothing to do
-with the problem.  As the size of a project---and the time it takes to
-build and test---grows, you rapidly run into a wall with this ``try
-before you buy'' approach, where you have more changesets to test than
-time in which to deal with them.  The inevitable result is frustration
-on the part of all involved.
-
-An approach that scales better is to get people to build and test
-before they push, then run automated builds and tests centrally
-\emph{after} a push, to be sure all is well.  The advantage of this
-approach is that it does not impose a limit on the rate at which the
-repository can accept changes.
-
-\section{A short tutorial on using hooks}
-\label{sec:hook:simple}
-
-It is easy to write a Mercurial hook.  Let's start with a hook that
-runs when you finish a \hgcmd{commit}, and simply prints the hash of
-the changeset you just created.  The hook is called \hook{commit}.
-
-\begin{figure}[ht]
-  \interaction{hook.simple.init}
-  \caption{A simple hook that runs when a changeset is committed}
-  \label{ex:hook:init}
-\end{figure}
-
-All hooks follow the pattern in example~\ref{ex:hook:init}.  You add
-an entry to the \rcsection{hooks} section of your \hgrc\.  On the left
-is the name of the event to trigger on; on the right is the action to
-take.  As you can see, you can run an arbitrary shell command in a
-hook.  Mercurial passes extra information to the hook using
-environment variables (look for \envar{HG\_NODE} in the example).
-
-\subsection{Performing multiple actions per event}
-
-Quite often, you will want to define more than one hook for a
-particular kind of event, as shown in example~\ref{ex:hook:ext}.
-Mercurial lets you do this by adding an \emph{extension} to the end of
-a hook's name.  You extend a hook's name by giving the name of the
-hook, followed by a full stop (the ``\texttt{.}'' character), followed
-by some more text of your choosing.  For example, Mercurial will run
-both \texttt{commit.foo} and \texttt{commit.bar} when the
-\texttt{commit} event occurs.
-
-\begin{figure}[ht]
-  \interaction{hook.simple.ext}
-  \caption{Defining a second \hook{commit} hook}
-  \label{ex:hook:ext}
-\end{figure}
-
-To give a well-defined order of execution when there are multiple
-hooks defined for an event, Mercurial sorts hooks by extension, and
-executes the hook commands in this sorted order.  In the above
-example, it will execute \texttt{commit.bar} before
-\texttt{commit.foo}, and \texttt{commit} before both.
-
-It is a good idea to use a somewhat descriptive extension when you
-define a new hook.  This will help you to remember what the hook was
-for.  If the hook fails, you'll get an error message that contains the
-hook name and extension, so using a descriptive extension could give
-you an immediate hint as to why the hook failed (see
-section~\ref{sec:hook:perm} for an example).
-
-\subsection{Controlling whether an activity can proceed}
-\label{sec:hook:perm}
-
-In our earlier examples, we used the \hook{commit} hook, which is
-run after a commit has completed.  This is one of several Mercurial
-hooks that run after an activity finishes.  Such hooks have no way of
-influencing the activity itself.
-
-Mercurial defines a number of events that occur before an activity
-starts; or after it starts, but before it finishes.  Hooks that
-trigger on these events have the added ability to choose whether the
-activity can continue, or will abort.  
-
-The \hook{pretxncommit} hook runs after a commit has all but
-completed.  In other words, the metadata representing the changeset
-has been written out to disk, but the transaction has not yet been
-allowed to complete.  The \hook{pretxncommit} hook has the ability to
-decide whether the transaction can complete, or must be rolled back.
-
-If the \hook{pretxncommit} hook exits with a status code of zero, the
-transaction is allowed to complete; the commit finishes; and the
-\hook{commit} hook is run.  If the \hook{pretxncommit} hook exits with
-a non-zero status code, the transaction is rolled back; the metadata
-representing the changeset is erased; and the \hook{commit} hook is
-not run.
-
-\begin{figure}[ht]
-  \interaction{hook.simple.pretxncommit}
-  \caption{Using the \hook{pretxncommit} hook to control commits}
-  \label{ex:hook:pretxncommit}
-\end{figure}
-
-The hook in example~\ref{ex:hook:pretxncommit} checks that a commit
-comment contains a bug ID.  If it does, the commit can complete.  If
-not, the commit is rolled back.
-
-\section{Writing your own hooks}
-
-When you are writing a hook, you might find it useful to run Mercurial
-either with the \hggopt{-v} option, or the \rcitem{ui}{verbose} config
-item set to ``true''.  When you do so, Mercurial will print a message
-before it calls each hook.
-
-\subsection{Choosing how your hook should run}
-\label{sec:hook:lang}
-
-You can write a hook either as a normal program---typically a shell
-script---or as a Python function that is executed within the Mercurial
-process.
-
-Writing a hook as an external program has the advantage that it
-requires no knowledge of Mercurial's internals.  You can call normal
-Mercurial commands to get any added information you need.  The
-trade-off is that external hooks are slower than in-process hooks.
-
-An in-process Python hook has complete access to the Mercurial API,
-and does not ``shell out'' to another process, so it is inherently
-faster than an external hook.  It is also easier to obtain much of the
-information that a hook requires by using the Mercurial API than by
-running Mercurial commands.
-
-If you are comfortable with Python, or require high performance,
-writing your hooks in Python may be a good choice.  However, when you
-have a straightforward hook to write and you don't need to care about
-performance (probably the majority of hooks), a shell script is
-perfectly fine.
-
-\subsection{Hook parameters}
-\label{sec:hook:param}
-
-Mercurial calls each hook with a set of well-defined parameters.  In
-Python, a parameter is passed as a keyword argument to your hook
-function.  For an external program, a parameter is passed as an
-environment variable.
-
-Whether your hook is written in Python or as a shell script, the
-hook-specific parameter names and values will be the same.  A boolean
-parameter will be represented as a boolean value in Python, but as the
-number 1 (for ``true'') or 0 (for ``false'') as an environment
-variable for an external hook.  If a hook parameter is named
-\texttt{foo}, the keyword argument for a Python hook will also be
-named \texttt{foo}, while the environment variable for an external
-hook will be named \texttt{HG\_FOO}.
-
-\subsection{Hook return values and activity control}
-
-A hook that executes successfully must exit with a status of zero if
-external, or return boolean ``false'' if in-process.  Failure is
-indicated with a non-zero exit status from an external hook, or an
-in-process hook returning boolean ``true''.  If an in-process hook
-raises an exception, the hook is considered to have failed.
-
-For a hook that controls whether an activity can proceed, zero/false
-means ``allow'', while non-zero/true/exception means ``deny''.
-
-\subsection{Writing an external hook}
-
-When you define an external hook in your \hgrc\ and the hook is run,
-its value is passed to your shell, which interprets it.  This means
-that you can use normal shell constructs in the body of the hook.
-
-An executable hook is always run with its current directory set to a
-repository's root directory.
-
-Each hook parameter is passed in as an environment variable; the name
-is upper-cased, and prefixed with the string ``\texttt{HG\_}''.
-
-With the exception of hook parameters, Mercurial does not set or
-modify any environment variables when running a hook.  This is useful
-to remember if you are writing a site-wide hook that may be run by a
-number of different users with differing environment variables set.
-In multi-user situations, you should not rely on environment variables
-being set to the values you have in your environment when testing the
-hook.
-
-\subsection{Telling Mercurial to use an in-process hook}
-
-The \hgrc\ syntax for defining an in-process hook is slightly
-different than for an executable hook.  The value of the hook must
-start with the text ``\texttt{python:}'', and continue with the
-fully-qualified name of a callable object to use as the hook's value.
-
-The module in which a hook lives is automatically imported when a hook
-is run.  So long as you have the module name and \envar{PYTHONPATH}
-right, it should ``just work''.
-
-The following \hgrc\ example snippet illustrates the syntax and
-meaning of the notions we just described.
-\begin{codesample2}
-  [hooks]
-  commit.example = python:mymodule.submodule.myhook
-\end{codesample2}
-When Mercurial runs the \texttt{commit.example} hook, it imports
-\texttt{mymodule.submodule}, looks for the callable object named
-\texttt{myhook}, and calls it.
-
-\subsection{Writing an in-process hook}
-
-The simplest in-process hook does nothing, but illustrates the basic
-shape of the hook API:
-\begin{codesample2}
-  def myhook(ui, repo, **kwargs):
-      pass
-\end{codesample2}
-The first argument to a Python hook is always a
-\pymodclass{mercurial.ui}{ui} object.  The second is a repository object;
-at the moment, it is always an instance of
-\pymodclass{mercurial.localrepo}{localrepository}.  Following these two
-arguments are other keyword arguments.  Which ones are passed in
-depends on the hook being called, but a hook can ignore arguments it
-doesn't care about by dropping them into a keyword argument dict, as
-with \texttt{**kwargs} above.
-
-\section{Some hook examples}
-
-\subsection{Writing meaningful commit messages}
-
-It's hard to imagine a useful commit message being very short.  The
-simple \hook{pretxncommit} hook of figure~\ref{ex:hook:msglen.go}
-will prevent you from committing a changeset with a message that is
-less than ten bytes long.
-
-\begin{figure}[ht]
-  \interaction{hook.msglen.go}
-  \caption{A hook that forbids overly short commit messages}
-  \label{ex:hook:msglen.go}
-\end{figure}
-
-\subsection{Checking for trailing whitespace}
-
-An interesting use of a commit-related hook is to help you to write
-cleaner code.  A simple example of ``cleaner code'' is the dictum that
-a change should not add any new lines of text that contain ``trailing
-whitespace''.  Trailing whitespace is a series of space and tab
-characters at the end of a line of text.  In most cases, trailing
-whitespace is unnecessary, invisible noise, but it is occasionally
-problematic, and people often prefer to get rid of it.
-
-You can use either the \hook{precommit} or \hook{pretxncommit} hook to
-tell whether you have a trailing whitespace problem.  If you use the
-\hook{precommit} hook, the hook will not know which files you are
-committing, so it will have to check every modified file in the
-repository for trailing white space.  If you want to commit a change
-to just the file \filename{foo}, but the file \filename{bar} contains
-trailing whitespace, doing a check in the \hook{precommit} hook will
-prevent you from committing \filename{foo} due to the problem with
-\filename{bar}.  This doesn't seem right.
-
-Should you choose the \hook{pretxncommit} hook, the check won't occur
-until just before the transaction for the commit completes.  This will
-allow you to check for problems only the exact files that are being
-committed.  However, if you entered the commit message interactively
-and the hook fails, the transaction will roll back; you'll have to
-re-enter the commit message after you fix the trailing whitespace and
-run \hgcmd{commit} again.
-
-\begin{figure}[ht]
-  \interaction{hook.ws.simple}
-  \caption{A simple hook that checks for trailing whitespace}
-  \label{ex:hook:ws.simple}
-\end{figure}
-
-Figure~\ref{ex:hook:ws.simple} introduces a simple \hook{pretxncommit}
-hook that checks for trailing whitespace.  This hook is short, but not
-very helpful.  It exits with an error status if a change adds a line
-with trailing whitespace to any file, but does not print any
-information that might help us to identify the offending file or
-line.  It also has the nice property of not paying attention to
-unmodified lines; only lines that introduce new trailing whitespace
-cause problems.
-
-\begin{figure}[ht]
-  \interaction{hook.ws.better}
-  \caption{A better trailing whitespace hook}
-  \label{ex:hook:ws.better}
-\end{figure}
-
-The example of figure~\ref{ex:hook:ws.better} is much more complex,
-but also more useful.  It parses a unified diff to see if any lines
-add trailing whitespace, and prints the name of the file and the line
-number of each such occurrence.  Even better, if the change adds
-trailing whitespace, this hook saves the commit comment and prints the
-name of the save file before exiting and telling Mercurial to roll the
-transaction back, so you can use
-\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{filename}} to reuse the
-saved commit message once you've corrected the problem.
-
-As a final aside, note in figure~\ref{ex:hook:ws.better} the use of
-\command{perl}'s in-place editing feature to get rid of trailing
-whitespace from a file.  This is concise and useful enough that I will
-reproduce it here.
-\begin{codesample2}
-  perl -pi -e 's,\\s+\$,,' filename
-\end{codesample2}
-
-\section{Bundled hooks}
-
-Mercurial ships with several bundled hooks.  You can find them in the
-\dirname{hgext} directory of a Mercurial source tree.  If you are
-using a Mercurial binary package, the hooks will be located in the
-\dirname{hgext} directory of wherever your package installer put
-Mercurial.
-
-\subsection{\hgext{acl}---access control for parts of a repository}
-
-The \hgext{acl} extension lets you control which remote users are
-allowed to push changesets to a networked server.  You can protect any
-portion of a repository (including the entire repo), so that a
-specific remote user can push changes that do not affect the protected
-portion.
-
-This extension implements access control based on the identity of the
-user performing a push, \emph{not} on who committed the changesets
-they're pushing.  It makes sense to use this hook only if you have a
-locked-down server environment that authenticates remote users, and
-you want to be sure that only specific users are allowed to push
-changes to that server.
-
-\subsubsection{Configuring the \hook{acl} hook}
-
-In order to manage incoming changesets, the \hgext{acl} hook must be
-used as a \hook{pretxnchangegroup} hook.  This lets it see which files
-are modified by each incoming changeset, and roll back a group of
-changesets if they modify ``forbidden'' files.  Example:
-\begin{codesample2}
-  [hooks]
-  pretxnchangegroup.acl = python:hgext.acl.hook
-\end{codesample2}
-
-The \hgext{acl} extension is configured using three sections.  
-
-The \rcsection{acl} section has only one entry, \rcitem{acl}{sources},
-which lists the sources of incoming changesets that the hook should
-pay attention to.  You don't normally need to configure this section.
-\begin{itemize}
-\item[\rcitem{acl}{serve}] Control incoming changesets that are arriving
-  from a remote repository over http or ssh.  This is the default
-  value of \rcitem{acl}{sources}, and usually the only setting you'll
-  need for this configuration item.
-\item[\rcitem{acl}{pull}] Control incoming changesets that are
-  arriving via a pull from a local repository.
-\item[\rcitem{acl}{push}] Control incoming changesets that are
-  arriving via a push from a local repository.
-\item[\rcitem{acl}{bundle}] Control incoming changesets that are
-  arriving from another repository via a bundle.
-\end{itemize}
-
-The \rcsection{acl.allow} section controls the users that are allowed to
-add changesets to the repository.  If this section is not present, all
-users that are not explicitly denied are allowed.  If this section is
-present, all users that are not explicitly allowed are denied (so an
-empty section means that all users are denied).
-
-The \rcsection{acl.deny} section determines which users are denied
-from adding changesets to the repository.  If this section is not
-present or is empty, no users are denied.
-
-The syntaxes for the \rcsection{acl.allow} and \rcsection{acl.deny}
-sections are identical.  On the left of each entry is a glob pattern
-that matches files or directories, relative to the root of the
-repository; on the right, a user name.
-
-In the following example, the user \texttt{docwriter} can only push
-changes to the \dirname{docs} subtree of the repository, while
-\texttt{intern} can push changes to any file or directory except
-\dirname{source/sensitive}.
-\begin{codesample2}
-  [acl.allow]
-  docs/** = docwriter
-
-  [acl.deny]
-  source/sensitive/** = intern
-\end{codesample2}
-
-\subsubsection{Testing and troubleshooting}
-
-If you want to test the \hgext{acl} hook, run it with Mercurial's
-debugging output enabled.  Since you'll probably be running it on a
-server where it's not convenient (or sometimes possible) to pass in
-the \hggopt{--debug} option, don't forget that you can enable
-debugging output in your \hgrc:
-\begin{codesample2}
-  [ui]
-  debug = true
-\end{codesample2}
-With this enabled, the \hgext{acl} hook will print enough information
-to let you figure out why it is allowing or forbidding pushes from
-specific users.
-
-\subsection{\hgext{bugzilla}---integration with Bugzilla}
-
-The \hgext{bugzilla} extension adds a comment to a Bugzilla bug
-whenever it finds a reference to that bug ID in a commit comment.  You
-can install this hook on a shared server, so that any time a remote
-user pushes changes to this server, the hook gets run.  
-
-It adds a comment to the bug that looks like this (you can configure
-the contents of the comment---see below):
-\begin{codesample2}
-  Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
-  the frobnitz repository, refers to this bug.
-
-  For complete details, see
-  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
-
-  Changeset description:
-        Fix bug 10483 by guarding against some NULL pointers
-\end{codesample2}
-The value of this hook is that it automates the process of updating a
-bug any time a changeset refers to it.  If you configure the hook
-properly, it makes it easy for people to browse straight from a
-Bugzilla bug to a changeset that refers to that bug.
-
-You can use the code in this hook as a starting point for some more
-exotic Bugzilla integration recipes.  Here are a few possibilities:
-\begin{itemize}
-\item Require that every changeset pushed to the server have a valid
-  bug~ID in its commit comment.  In this case, you'd want to configure
-  the hook as a \hook{pretxncommit} hook.  This would allow the hook
-  to reject changes that didn't contain bug IDs.
-\item Allow incoming changesets to automatically modify the
-  \emph{state} of a bug, as well as simply adding a comment.  For
-  example, the hook could recognise the string ``fixed bug 31337'' as
-  indicating that it should update the state of bug 31337 to
-  ``requires testing''.
-\end{itemize}
-
-\subsubsection{Configuring the \hook{bugzilla} hook}
-\label{sec:hook:bugzilla:config}
-
-You should configure this hook in your server's \hgrc\ as an
-\hook{incoming} hook, for example as follows:
-\begin{codesample2}
-  [hooks]
-  incoming.bugzilla = python:hgext.bugzilla.hook
-\end{codesample2}
-
-Because of the specialised nature of this hook, and because Bugzilla
-was not written with this kind of integration in mind, configuring
-this hook is a somewhat involved process.
-
-Before you begin, you must install the MySQL bindings for Python on
-the host(s) where you'll be running the hook.  If this is not
-available as a binary package for your system, you can download it
-from~\cite{web:mysql-python}.
-
-Configuration information for this hook lives in the
-\rcsection{bugzilla} section of your \hgrc.
-\begin{itemize}
-\item[\rcitem{bugzilla}{version}] The version of Bugzilla installed on
-  the server.  The database schema that Bugzilla uses changes
-  occasionally, so this hook has to know exactly which schema to use.
-  At the moment, the only version supported is \texttt{2.16}.
-\item[\rcitem{bugzilla}{host}] The hostname of the MySQL server that
-  stores your Bugzilla data.  The database must be configured to allow
-  connections from whatever host you are running the \hook{bugzilla}
-  hook on.
-\item[\rcitem{bugzilla}{user}] The username with which to connect to
-  the MySQL server.  The database must be configured to allow this
-  user to connect from whatever host you are running the
-  \hook{bugzilla} hook on.  This user must be able to access and
-  modify Bugzilla tables.  The default value of this item is
-  \texttt{bugs}, which is the standard name of the Bugzilla user in a
-  MySQL database.
-\item[\rcitem{bugzilla}{password}] The MySQL password for the user you
-  configured above.  This is stored as plain text, so you should make
-  sure that unauthorised users cannot read the \hgrc\ file where you
-  store this information.
-\item[\rcitem{bugzilla}{db}] The name of the Bugzilla database on the
-  MySQL server.  The default value of this item is \texttt{bugs},
-  which is the standard name of the MySQL database where Bugzilla
-  stores its data.
-\item[\rcitem{bugzilla}{notify}] If you want Bugzilla to send out a
-  notification email to subscribers after this hook has added a
-  comment to a bug, you will need this hook to run a command whenever
-  it updates the database.  The command to run depends on where you
-  have installed Bugzilla, but it will typically look something like
-  this, if you have Bugzilla installed in
-  \dirname{/var/www/html/bugzilla}:
-  \begin{codesample4}
-    cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
-  \end{codesample4}
-  The Bugzilla \texttt{processmail} program expects to be given a
-  bug~ID (the hook replaces ``\texttt{\%s}'' with the bug~ID) and an
-  email address.  It also expects to be able to write to some files in
-  the directory that it runs in.  If Bugzilla and this hook are not
-  installed on the same machine, you will need to find a way to run
-  \texttt{processmail} on the server where Bugzilla is installed.
-\end{itemize}
-
-\subsubsection{Mapping committer names to Bugzilla user names}
-
-By default, the \hgext{bugzilla} hook tries to use the email address
-of a changeset's committer as the Bugzilla user name with which to
-update a bug.  If this does not suit your needs, you can map committer
-email addresses to Bugzilla user names using a \rcsection{usermap}
-section.
-
-Each item in the \rcsection{usermap} section contains an email address
-on the left, and a Bugzilla user name on the right.
-\begin{codesample2}
-  [usermap]
-  jane.user@example.com = jane
-\end{codesample2}
-You can either keep the \rcsection{usermap} data in a normal \hgrc, or
-tell the \hgext{bugzilla} hook to read the information from an
-external \filename{usermap} file.  In the latter case, you can store
-\filename{usermap} data by itself in (for example) a user-modifiable
-repository.  This makes it possible to let your users maintain their
-own \rcitem{bugzilla}{usermap} entries.  The main \hgrc\ file might
-look like this:
-\begin{codesample2}
-  # regular hgrc file refers to external usermap file
-  [bugzilla]
-  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
-\end{codesample2}
-While the \filename{usermap} file that it refers to might look like
-this:
-\begin{codesample2}
-  # bugzilla-usermap.conf - inside a hg repository
-  [usermap]
-  stephanie@example.com = steph
-\end{codesample2}
-
-\subsubsection{Configuring the text that gets added to a bug}
-
-You can configure the text that this hook adds as a comment; you
-specify it in the form of a Mercurial template.  Several \hgrc\
-entries (still in the \rcsection{bugzilla} section) control this
-behaviour.
-\begin{itemize}
-\item[\texttt{strip}] The number of leading path elements to strip
-  from a repository's path name to construct a partial path for a URL.
-  For example, if the repositories on your server live under
-  \dirname{/home/hg/repos}, and you have a repository whose path is
-  \dirname{/home/hg/repos/app/tests}, then setting \texttt{strip} to
-  \texttt{4} will give a partial path of \dirname{app/tests}.  The
-  hook will make this partial path available when expanding a
-  template, as \texttt{webroot}.
-\item[\texttt{template}] The text of the template to use.  In addition
-  to the usual changeset-related variables, this template can use
-  \texttt{hgweb} (the value of the \texttt{hgweb} configuration item
-  above) and \texttt{webroot} (the path constructed using
-  \texttt{strip} above).
-\end{itemize}
-
-In addition, you can add a \rcitem{web}{baseurl} item to the
-\rcsection{web} section of your \hgrc.  The \hgext{bugzilla} hook will
-make this available when expanding a template, as the base string to
-use when constructing a URL that will let users browse from a Bugzilla
-comment to view a changeset.  Example:
-\begin{codesample2}
-  [web]
-  baseurl = http://hg.domain.com/
-\end{codesample2}
-
-Here is an example set of \hgext{bugzilla} hook config information.
-\begin{codesample2}
-  [bugzilla]
-  host = bugzilla.example.com
-  password = mypassword
-  version = 2.16
-  # server-side repos live in /home/hg/repos, so strip 4 leading
-  # separators
-  strip = 4
-  hgweb = http://hg.example.com/
-  usermap = /home/hg/repos/notify/bugzilla.conf
-  template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
-    repo, refers to this bug.\\nFor complete details, see 
-    \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
-    description:\\n\\t\{desc|tabindent\}
-\end{codesample2}
-
-\subsubsection{Testing and troubleshooting}
-
-The most common problems with configuring the \hgext{bugzilla} hook
-relate to running Bugzilla's \filename{processmail} script and mapping
-committer names to user names.
-
-Recall from section~\ref{sec:hook:bugzilla:config} above that the user
-that runs the Mercurial process on the server is also the one that
-will run the \filename{processmail} script.  The
-\filename{processmail} script sometimes causes Bugzilla to write to
-files in its configuration directory, and Bugzilla's configuration
-files are usually owned by the user that your web server runs under.
-
-You can cause \filename{processmail} to be run with the suitable
-user's identity using the \command{sudo} command.  Here is an example
-entry for a \filename{sudoers} file.
-\begin{codesample2}
-  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
-\end{codesample2}
-This allows the \texttt{hg\_user} user to run a
-\filename{processmail-wrapper} program under the identity of
-\texttt{httpd\_user}.
-
-This indirection through a wrapper script is necessary, because
-\filename{processmail} expects to be run with its current directory
-set to wherever you installed Bugzilla; you can't specify that kind of
-constraint in a \filename{sudoers} file.  The contents of the wrapper
-script are simple:
-\begin{codesample2}
-  #!/bin/sh
-  cd `dirname $0` && ./processmail "$1" nobody@example.com
-\end{codesample2}
-It doesn't seem to matter what email address you pass to
-\filename{processmail}.
-
-If your \rcsection{usermap} is not set up correctly, users will see an
-error message from the \hgext{bugzilla} hook when they push changes
-to the server.  The error message will look like this:
-\begin{codesample2}
-  cannot find bugzilla user id for john.q.public@example.com
-\end{codesample2}
-What this means is that the committer's address,
-\texttt{john.q.public@example.com}, is not a valid Bugzilla user name,
-nor does it have an entry in your \rcsection{usermap} that maps it to
-a valid Bugzilla user name.
-
-\subsection{\hgext{notify}---send email notifications}
-
-Although Mercurial's built-in web server provides RSS feeds of changes
-in every repository, many people prefer to receive change
-notifications via email.  The \hgext{notify} hook lets you send out
-notifications to a set of email addresses whenever changesets arrive
-that those subscribers are interested in.
-
-As with the \hgext{bugzilla} hook, the \hgext{notify} hook is
-template-driven, so you can customise the contents of the notification
-messages that it sends.
-
-By default, the \hgext{notify} hook includes a diff of every changeset
-that it sends out; you can limit the size of the diff, or turn this
-feature off entirely.  It is useful for letting subscribers review
-changes immediately, rather than clicking to follow a URL.
-
-\subsubsection{Configuring the \hgext{notify} hook}
-
-You can set up the \hgext{notify} hook to send one email message per
-incoming changeset, or one per incoming group of changesets (all those
-that arrived in a single pull or push).
-\begin{codesample2}
-  [hooks]
-  # send one email per group of changes
-  changegroup.notify = python:hgext.notify.hook
-  # send one email per change
-  incoming.notify = python:hgext.notify.hook
-\end{codesample2}
-
-Configuration information for this hook lives in the
-\rcsection{notify} section of a \hgrc\ file.
-\begin{itemize}
-\item[\rcitem{notify}{test}] By default, this hook does not send out
-  email at all; instead, it prints the message that it \emph{would}
-  send.  Set this item to \texttt{false} to allow email to be sent.
-  The reason that sending of email is turned off by default is that it
-  takes several tries to configure this extension exactly as you would
-  like, and it would be bad form to spam subscribers with a number of
-  ``broken'' notifications while you debug your configuration.
-\item[\rcitem{notify}{config}] The path to a configuration file that
-  contains subscription information.  This is kept separate from the
-  main \hgrc\ so that you can maintain it in a repository of its own.
-  People can then clone that repository, update their subscriptions,
-  and push the changes back to your server.
-\item[\rcitem{notify}{strip}] The number of leading path separator
-  characters to strip from a repository's path, when deciding whether
-  a repository has subscribers.  For example, if the repositories on
-  your server live in \dirname{/home/hg/repos}, and \hgext{notify} is
-  considering a repository named \dirname{/home/hg/repos/shared/test},
-  setting \rcitem{notify}{strip} to \texttt{4} will cause
-  \hgext{notify} to trim the path it considers down to
-  \dirname{shared/test}, and it will match subscribers against that.
-\item[\rcitem{notify}{template}] The template text to use when sending
-  messages.  This specifies both the contents of the message header
-  and its body.
-\item[\rcitem{notify}{maxdiff}] The maximum number of lines of diff
-  data to append to the end of a message.  If a diff is longer than
-  this, it is truncated.  By default, this is set to 300.  Set this to
-  \texttt{0} to omit diffs from notification emails.
-\item[\rcitem{notify}{sources}] A list of sources of changesets to
-  consider.  This lets you limit \hgext{notify} to only sending out
-  email about changes that remote users pushed into this repository
-  via a server, for example.  See section~\ref{sec:hook:sources} for
-  the sources you can specify here.
-\end{itemize}
-
-If you set the \rcitem{web}{baseurl} item in the \rcsection{web}
-section, you can use it in a template; it will be available as
-\texttt{webroot}.
-
-Here is an example set of \hgext{notify} configuration information.
-\begin{codesample2}
-  [notify]
-  # really send email
-  test = false
-  # subscriber data lives in the notify repo
-  config = /home/hg/repos/notify/notify.conf
-  # repos live in /home/hg/repos on server, so strip 4 "/" chars
-  strip = 4
-  template = X-Hg-Repo: \{webroot\}
-    Subject: \{webroot\}: \{desc|firstline|strip\}
-    From: \{author\}
-
-    changeset \{node|short\} in \{root\}
-    details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
-    description:
-      \{desc|tabindent|strip\}
-
-  [web]
-  baseurl = http://hg.example.com/
-\end{codesample2}
-
-This will produce a message that looks like the following:
-\begin{codesample2}
-  X-Hg-Repo: tests/slave
-  Subject: tests/slave: Handle error case when slave has no buffers
-  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
-
-  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
-  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
-  description:
-          Handle error case when slave has no buffers
-  diffs (54 lines):
-
-  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
-  --- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
-  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
-  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
-  [...snip...]
-\end{codesample2}
-
-\subsubsection{Testing and troubleshooting}
-
-Do not forget that by default, the \hgext{notify} extension \emph{will
-  not send any mail} until you explicitly configure it to do so, by
-setting \rcitem{notify}{test} to \texttt{false}.  Until you do that,
-it simply prints the message it \emph{would} send.
-
-\section{Information for writers of hooks}
-\label{sec:hook:ref}
-
-\subsection{In-process hook execution}
-
-An in-process hook is called with arguments of the following form:
-\begin{codesample2}
-  def myhook(ui, repo, **kwargs):
-      pass
-\end{codesample2}
-The \texttt{ui} parameter is a \pymodclass{mercurial.ui}{ui} object.
-The \texttt{repo} parameter is a
-\pymodclass{mercurial.localrepo}{localrepository} object.  The
-names and values of the \texttt{**kwargs} parameters depend on the
-hook being invoked, with the following common features:
-\begin{itemize}
-\item If a parameter is named \texttt{node} or
-  \texttt{parent\emph{N}}, it will contain a hexadecimal changeset ID.
-  The empty string is used to represent ``null changeset ID'' instead
-  of a string of zeroes.
-\item If a parameter is named \texttt{url}, it will contain the URL of
-  a remote repository, if that can be determined.
-\item Boolean-valued parameters are represented as Python
-  \texttt{bool} objects.
-\end{itemize}
-
-An in-process hook is called without a change to the process's working
-directory (unlike external hooks, which are run in the root of the
-repository).  It must not change the process's working directory, or
-it will cause any calls it makes into the Mercurial API to fail.
-
-If a hook returns a boolean ``false'' value, it is considered to have
-succeeded.  If it returns a boolean ``true'' value or raises an
-exception, it is considered to have failed.  A useful way to think of
-the calling convention is ``tell me if you fail''.
-
-Note that changeset IDs are passed into Python hooks as hexadecimal
-strings, not the binary hashes that Mercurial's APIs normally use.  To
-convert a hash from hex to binary, use the
-\pymodfunc{mercurial.node}{bin} function.
-
-\subsection{External hook execution}
-
-An external hook is passed to the shell of the user running Mercurial.
-Features of that shell, such as variable substitution and command
-redirection, are available.  The hook is run in the root directory of
-the repository (unlike in-process hooks, which are run in the same
-directory that Mercurial was run in).
-
-Hook parameters are passed to the hook as environment variables.  Each
-environment variable's name is converted in upper case and prefixed
-with the string ``\texttt{HG\_}''.  For example, if the name of a
-parameter is ``\texttt{node}'', the name of the environment variable
-representing that parameter will be ``\texttt{HG\_NODE}''.
-
-A boolean parameter is represented as the string ``\texttt{1}'' for
-``true'', ``\texttt{0}'' for ``false''.  If an environment variable is
-named \envar{HG\_NODE}, \envar{HG\_PARENT1} or \envar{HG\_PARENT2}, it
-contains a changeset ID represented as a hexadecimal string.  The
-empty string is used to represent ``null changeset ID'' instead of a
-string of zeroes.  If an environment variable is named
-\envar{HG\_URL}, it will contain the URL of a remote repository, if
-that can be determined.
-
-If a hook exits with a status of zero, it is considered to have
-succeeded.  If it exits with a non-zero status, it is considered to
-have failed.
-
-\subsection{Finding out where changesets come from}
-
-A hook that involves the transfer of changesets between a local
-repository and another may be able to find out information about the
-``far side''.  Mercurial knows \emph{how} changes are being
-transferred, and in many cases \emph{where} they are being transferred
-to or from.
-
-\subsubsection{Sources of changesets}
-\label{sec:hook:sources}
-
-Mercurial will tell a hook what means are, or were, used to transfer
-changesets between repositories.  This is provided by Mercurial in a
-Python parameter named \texttt{source}, or an environment variable named
-\envar{HG\_SOURCE}.
-
-\begin{itemize}
-\item[\texttt{serve}] Changesets are transferred to or from a remote
-  repository over http or ssh.
-\item[\texttt{pull}] Changesets are being transferred via a pull from
-  one repository into another.
-\item[\texttt{push}] Changesets are being transferred via a push from
-  one repository into another.
-\item[\texttt{bundle}] Changesets are being transferred to or from a
-  bundle.
-\end{itemize}
-
-\subsubsection{Where changes are going---remote repository URLs}
-\label{sec:hook:url}
-
-When possible, Mercurial will tell a hook the location of the ``far
-side'' of an activity that transfers changeset data between
-repositories.  This is provided by Mercurial in a Python parameter
-named \texttt{url}, or an environment variable named \envar{HG\_URL}.
-
-This information is not always known.  If a hook is invoked in a
-repository that is being served via http or ssh, Mercurial cannot tell
-where the remote repository is, but it may know where the client is
-connecting from.  In such cases, the URL will take one of the
-following forms:
-\begin{itemize}
-\item \texttt{remote:ssh:\emph{ip-address}}---remote ssh client, at
-  the given IP address.
-\item \texttt{remote:http:\emph{ip-address}}---remote http client, at
-  the given IP address.  If the client is using SSL, this will be of
-  the form \texttt{remote:https:\emph{ip-address}}.
-\item Empty---no information could be discovered about the remote
-  client.
-\end{itemize}
-
-\section{Hook reference}
-
-\subsection{\hook{changegroup}---after remote changesets added}
-\label{sec:hook:changegroup}
-
-This hook is run after a group of pre-existing changesets has been
-added to the repository, for example via a \hgcmd{pull} or
-\hgcmd{unbundle}.  This hook is run once per operation that added one
-or more changesets.  This is in contrast to the \hook{incoming} hook,
-which is run once per changeset, regardless of whether the changesets
-arrive in a group.
-
-Some possible uses for this hook include kicking off an automated
-build or test of the added changesets, updating a bug database, or
-notifying subscribers that a repository contains new changes.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The changeset ID of the first
-  changeset in the group that was added.  All changesets between this
-  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
-  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
-\item[\texttt{source}] A string.  The source of these changes.  See
-  section~\ref{sec:hook:sources} for details.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{incoming} (section~\ref{sec:hook:incoming}),
-\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}),
-\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
-
-\subsection{\hook{commit}---after a new changeset is created}
-\label{sec:hook:commit}
-
-This hook is run after a new changeset has been created.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
-  committed changeset.
-\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
-  parent of the newly committed changeset.
-\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
-  parent of the newly committed changeset.
-\end{itemize}
-
-See also: \hook{precommit} (section~\ref{sec:hook:precommit}),
-\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
-
-\subsection{\hook{incoming}---after one remote changeset is added}
-\label{sec:hook:incoming}
-
-This hook is run after a pre-existing changeset has been added to the
-repository, for example via a \hgcmd{push}.  If a group of changesets
-was added in a single operation, this hook is called once for each
-added changeset.
-
-You can use this hook for the same purposes as the \hook{changegroup}
-hook (section~\ref{sec:hook:changegroup}); it's simply more convenient
-sometimes to run a hook once per group of changesets, while other
-times it's handier once per changeset.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The ID of the newly added
-  changeset.
-\item[\texttt{source}] A string.  The source of these changes.  See
-  section~\ref{sec:hook:sources} for details.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}) \hook{prechangegroup} (section~\ref{sec:hook:prechangegroup}), \hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
-
-\subsection{\hook{outgoing}---after changesets are propagated}
-\label{sec:hook:outgoing}
-
-This hook is run after a group of changesets has been propagated out
-of this repository, for example by a \hgcmd{push} or \hgcmd{bundle}
-command.
-
-One possible use for this hook is to notify administrators that
-changes have been pulled.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The changeset ID of the first
-  changeset of the group that was sent.
-\item[\texttt{source}] A string.  The source of the of the operation
-  (see section~\ref{sec:hook:sources}).  If a remote client pulled
-  changes from this repository, \texttt{source} will be
-  \texttt{serve}.  If the client that obtained changes from this
-  repository was local, \texttt{source} will be \texttt{bundle},
-  \texttt{pull}, or \texttt{push}, depending on the operation the
-  client performed.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{preoutgoing} (section~\ref{sec:hook:preoutgoing})
-
-\subsection{\hook{prechangegroup}---before starting to add remote changesets}
-\label{sec:hook:prechangegroup}
-
-This controlling hook is run before Mercurial begins to add a group of
-changesets from another repository.
-
-This hook does not have any information about the changesets to be
-added, because it is run before transmission of those changesets is
-allowed to begin.  If this hook fails, the changesets will not be
-transmitted.
-
-One use for this hook is to prevent external changes from being added
-to a repository.  For example, you could use this to ``freeze'' a
-server-hosted branch temporarily or permanently so that users cannot
-push to it, while still allowing a local administrator to modify the
-repository.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{source}] A string.  The source of these changes.  See
-  section~\ref{sec:hook:sources} for details.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
-\hook{incoming} (section~\ref{sec:hook:incoming}), ,
-\hook{pretxnchangegroup} (section~\ref{sec:hook:pretxnchangegroup})
-
-\subsection{\hook{precommit}---before starting to commit a changeset}
-\label{sec:hook:precommit}
-
-This hook is run before Mercurial begins to commit a new changeset.
-It is run before Mercurial has any of the metadata for the commit,
-such as the files to be committed, the commit message, or the commit
-date.
-
-One use for this hook is to disable the ability to commit new
-changesets, while still allowing incoming changesets.  Another is to
-run a build or test, and only allow the commit to begin if the build
-or test succeeds.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
-  parent of the working directory.
-\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
-  parent of the working directory.
-\end{itemize}
-If the commit proceeds, the parents of the working directory will
-become the parents of the new changeset.
-
-See also: \hook{commit} (section~\ref{sec:hook:commit}),
-\hook{pretxncommit} (section~\ref{sec:hook:pretxncommit})
-
-\subsection{\hook{preoutgoing}---before starting to propagate changesets}
-\label{sec:hook:preoutgoing}
-
-This hook is invoked before Mercurial knows the identities of the
-changesets to be transmitted.
-
-One use for this hook is to prevent changes from being transmitted to
-another repository.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{source}] A string.  The source of the operation that is
-  attempting to obtain changes from this repository (see
-  section~\ref{sec:hook:sources}).  See the documentation for the
-  \texttt{source} parameter to the \hook{outgoing} hook, in
-  section~\ref{sec:hook:outgoing}, for possible values of this
-  parameter.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{outgoing} (section~\ref{sec:hook:outgoing})
-
-\subsection{\hook{pretag}---before tagging a changeset}
-\label{sec:hook:pretag}
-
-This controlling hook is run before a tag is created.  If the hook
-succeeds, creation of the tag proceeds.  If the hook fails, the tag is
-not created.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{local}] A boolean.  Whether the tag is local to this
-  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
-  managed by Mercurial (stored in \sfilename{.hgtags}).
-\item[\texttt{node}] A changeset ID.  The ID of the changeset to be tagged.
-\item[\texttt{tag}] A string.  The name of the tag to be created.
-\end{itemize}
-
-If the tag to be created is revision-controlled, the \hook{precommit}
-and \hook{pretxncommit} hooks (sections~\ref{sec:hook:commit}
-and~\ref{sec:hook:pretxncommit}) will also be run.
-
-See also: \hook{tag} (section~\ref{sec:hook:tag})
-
-\subsection{\hook{pretxnchangegroup}---before completing addition of
-  remote changesets}
-\label{sec:hook:pretxnchangegroup}
-
-This controlling hook is run before a transaction---that manages the
-addition of a group of new changesets from outside the
-repository---completes.  If the hook succeeds, the transaction
-completes, and all of the changesets become permanent within this
-repository.  If the hook fails, the transaction is rolled back, and
-the data for the changesets is erased.
-
-This hook can access the metadata associated with the almost-added
-changesets, but it should not do anything permanent with this data.
-It must also not modify the working directory.
-
-While this hook is running, if other Mercurial processes access this
-repository, they will be able to see the almost-added changesets as if
-they are permanent.  This may lead to race conditions if you do not
-take steps to avoid them.
-
-This hook can be used to automatically vet a group of changesets.  If
-the hook fails, all of the changesets are ``rejected'' when the
-transaction rolls back.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The changeset ID of the first
-  changeset in the group that was added.  All changesets between this
-  and \index{tags!\texttt{tip}}\texttt{tip}, inclusive, were added by
-  a single \hgcmd{pull}, \hgcmd{push} or \hgcmd{unbundle}.
-\item[\texttt{source}] A string.  The source of these changes.  See
-  section~\ref{sec:hook:sources} for details.
-\item[\texttt{url}] A URL.  The location of the remote repository, if
-  known.  See section~\ref{sec:hook:url} for more information.
-\end{itemize}
-
-See also: \hook{changegroup} (section~\ref{sec:hook:changegroup}),
-\hook{incoming} (section~\ref{sec:hook:incoming}),
-\hook{prechangegroup} (section~\ref{sec:hook:prechangegroup})
-
-\subsection{\hook{pretxncommit}---before completing commit of new changeset}
-\label{sec:hook:pretxncommit}
-
-This controlling hook is run before a transaction---that manages a new
-commit---completes.  If the hook succeeds, the transaction completes
-and the changeset becomes permanent within this repository.  If the
-hook fails, the transaction is rolled back, and the commit data is
-erased.
-
-This hook can access the metadata associated with the almost-new
-changeset, but it should not do anything permanent with this data.  It
-must also not modify the working directory.
-
-While this hook is running, if other Mercurial processes access this
-repository, they will be able to see the almost-new changeset as if it
-is permanent.  This may lead to race conditions if you do not take
-steps to avoid them.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{node}] A changeset ID.  The changeset ID of the newly
-  committed changeset.
-\item[\texttt{parent1}] A changeset ID.  The changeset ID of the first
-  parent of the newly committed changeset.
-\item[\texttt{parent2}] A changeset ID.  The changeset ID of the second
-  parent of the newly committed changeset.
-\end{itemize}
-
-See also: \hook{precommit} (section~\ref{sec:hook:precommit})
-
-\subsection{\hook{preupdate}---before updating or merging working directory}
-\label{sec:hook:preupdate}
-
-This controlling hook is run before an update or merge of the working
-directory begins.  It is run only if Mercurial's normal pre-update
-checks determine that the update or merge can proceed.  If the hook
-succeeds, the update or merge may proceed; if it fails, the update or
-merge does not start.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
-  working directory is to be updated to.  If the working directory is
-  being merged, it will not change this parent.
-\item[\texttt{parent2}] A changeset ID.  Only set if the working
-  directory is being merged.  The ID of the revision that the working
-  directory is being merged with.
-\end{itemize}
-
-See also: \hook{update} (section~\ref{sec:hook:update})
-
-\subsection{\hook{tag}---after tagging a changeset}
-\label{sec:hook:tag}
-
-This hook is run after a tag has been created.
-
-Parameters to this hook:
-\begin{itemize}
-\item[\texttt{local}] A boolean.  Whether the new tag is local to this
-  repository instance (i.e.~stored in \sfilename{.hg/localtags}) or
-  managed by Mercurial (stored in \sfilename{.hgtags}).
-\item[\texttt{node}] A changeset ID.  The ID of the changeset that was
-  tagged.
-\item[\texttt{tag}] A string.  The name of the tag that was created.
-\end{itemize}
-
-If the created tag is revision-controlled, the \hook{commit} hook
-(section~\ref{sec:hook:commit}) is run before this hook.
-
-See also: \hook{pretag} (section~\ref{sec:hook:pretag})
-
-\subsection{\hook{update}---after updating or merging working directory}
-\label{sec:hook:update}
-
-This hook is run after an update or merge of the working directory
-completes.  Since a merge can fail (if the external \command{hgmerge}
-command fails to resolve conflicts in a file), this hook communicates
-whether the update or merge completed cleanly.
-
-\begin{itemize}
-\item[\texttt{error}] A boolean.  Indicates whether the update or
-  merge completed successfully.
-\item[\texttt{parent1}] A changeset ID.  The ID of the parent that the
-  working directory was updated to.  If the working directory was
-  merged, it will not have changed this parent.
-\item[\texttt{parent2}] A changeset ID.  Only set if the working
-  directory was merged.  The ID of the revision that the working
-  directory was merged with.
-\end{itemize}
-
-See also: \hook{preupdate} (section~\ref{sec:hook:preupdate})
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/htlatex.book	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# This script is horrible.  It's essentially a hacked copy of
-# /usr/bin/htlatex from Fedora Core 6.  I apologise for any lasting
-# pain reading it causes.
-
-latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
-(cd $4 && bibtex hgbook)
-(cd $4 && makeindex hgbook)
-latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
-latex $5 '\makeatletter\def\HCode{\futurelet\HCode\HChar}\def\HChar{\ifx"\HCode\def\HCode"##1"{\Link##1}\expandafter\HCode\else\expandafter\Link\fi}\def\Link#1.a.b.c.{\g@addto@macro\@documentclasshook{\RequirePackage[#1,html]{tex4ht}}\let\HCode\documentstyle\def\documentstyle{\let\documentstyle\HCode\expandafter\def\csname tex4ht\endcsname{#1,html}\def\HCode####1{\documentstyle[tex4ht,}\@ifnextchar[{\HCode}{\documentstyle[tex4ht]}}}\makeatother\HCode '$2'.a.b.c.\input ' $1
-echo status $$
--- a/en/intro.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,567 +0,0 @@
-\chapter{Introduction}
-\label{chap:intro}
-
-\section{About revision control}
-
-Revision control is the process of managing multiple versions of a
-piece of information.  In its simplest form, this is something that
-many people do by hand: every time you modify a file, save it under a
-new name that contains a number, each one higher than the number of
-the preceding version.
-
-Manually managing multiple versions of even a single file is an
-error-prone task, though, so software tools to help automate this
-process have long been available.  The earliest automated revision
-control tools were intended to help a single user to manage revisions
-of a single file.  Over the past few decades, the scope of revision
-control tools has expanded greatly; they now manage multiple files,
-and help multiple people to work together.  The best modern revision
-control tools have no problem coping with thousands of people working
-together on projects that consist of hundreds of thousands of files.
-
-\subsection{Why use revision control?}
-
-There are a number of reasons why you or your team might want to use
-an automated revision control tool for a project.
-\begin{itemize}
-\item It will track the history and evolution of your project, so you
-  don't have to.  For every change, you'll have a log of \emph{who}
-  made it; \emph{why} they made it; \emph{when} they made it; and
-  \emph{what} the change was.
-\item When you're working with other people, revision control software
-  makes it easier for you to collaborate.  For example, when people
-  more or less simultaneously make potentially incompatible changes,
-  the software will help you to identify and resolve those conflicts.
-\item It can help you to recover from mistakes.  If you make a change
-  that later turns out to be in error, you can revert to an earlier
-  version of one or more files.  In fact, a \emph{really} good
-  revision control tool will even help you to efficiently figure out
-  exactly when a problem was introduced (see
-  section~\ref{sec:undo:bisect} for details).
-\item It will help you to work simultaneously on, and manage the drift
-  between, multiple versions of your project.
-\end{itemize}
-Most of these reasons are equally valid---at least in theory---whether
-you're working on a project by yourself, or with a hundred other
-people.
-
-A key question about the practicality of revision control at these two
-different scales (``lone hacker'' and ``huge team'') is how its
-\emph{benefits} compare to its \emph{costs}.  A revision control tool
-that's difficult to understand or use is going to impose a high cost.
-
-A five-hundred-person project is likely to collapse under its own
-weight almost immediately without a revision control tool and process.
-In this case, the cost of using revision control might hardly seem
-worth considering, since \emph{without} it, failure is almost
-guaranteed.
-
-On the other hand, a one-person ``quick hack'' might seem like a poor
-place to use a revision control tool, because surely the cost of using
-one must be close to the overall cost of the project.  Right?
-
-Mercurial uniquely supports \emph{both} of these scales of
-development.  You can learn the basics in just a few minutes, and due
-to its low overhead, you can apply revision control to the smallest of
-projects with ease.  Its simplicity means you won't have a lot of
-abstruse concepts or command sequences competing for mental space with
-whatever you're \emph{really} trying to do.  At the same time,
-Mercurial's high performance and peer-to-peer nature let you scale
-painlessly to handle large projects.
-
-No revision control tool can rescue a poorly run project, but a good
-choice of tools can make a huge difference to the fluidity with which
-you can work on a project.
-
-\subsection{The many names of revision control}
-
-Revision control is a diverse field, so much so that it doesn't
-actually have a single name or acronym.  Here are a few of the more
-common names and acronyms you'll encounter:
-\begin{itemize}
-\item Revision control (RCS)
-\item Software configuration management (SCM), or configuration management
-\item Source code management
-\item Source code control, or source control
-\item Version control (VCS)
-\end{itemize}
-Some people claim that these terms actually have different meanings,
-but in practice they overlap so much that there's no agreed or even
-useful way to tease them apart.
-
-\section{A short history of revision control}
-
-The best known of the old-time revision control tools is SCCS (Source
-Code Control System), which Marc Rochkind wrote at Bell Labs, in the
-early 1970s.  SCCS operated on individual files, and required every
-person working on a project to have access to a shared workspace on a
-single system.  Only one person could modify a file at any time;
-arbitration for access to files was via locks.  It was common for
-people to lock files, and later forget to unlock them, preventing
-anyone else from modifying those files without the help of an
-administrator.  
-
-Walter Tichy developed a free alternative to SCCS in the early 1980s;
-he called his program RCS (Revison Control System).  Like SCCS, RCS
-required developers to work in a single shared workspace, and to lock
-files to prevent multiple people from modifying them simultaneously.
-
-Later in the 1980s, Dick Grune used RCS as a building block for a set
-of shell scripts he initially called cmt, but then renamed to CVS
-(Concurrent Versions System).  The big innovation of CVS was that it
-let developers work simultaneously and somewhat independently in their
-own personal workspaces.  The personal workspaces prevented developers
-from stepping on each other's toes all the time, as was common with
-SCCS and RCS.  Each developer had a copy of every project file, and
-could modify their copies independently.  They had to merge their
-edits prior to committing changes to the central repository.
-
-Brian Berliner took Grune's original scripts and rewrote them in~C,
-releasing in 1989 the code that has since developed into the modern
-version of CVS.  CVS subsequently acquired the ability to operate over
-a network connection, giving it a client/server architecture.  CVS's
-architecture is centralised; only the server has a copy of the history
-of the project.  Client workspaces just contain copies of recent
-versions of the project's files, and a little metadata to tell them
-where the server is.  CVS has been enormously successful; it is
-probably the world's most widely used revision control system.
-
-In the early 1990s, Sun Microsystems developed an early distributed
-revision control system, called TeamWare.  A TeamWare workspace
-contains a complete copy of the project's history.  TeamWare has no
-notion of a central repository.  (CVS relied upon RCS for its history
-storage; TeamWare used SCCS.)
-
-As the 1990s progressed, awareness grew of a number of problems with
-CVS.  It records simultaneous changes to multiple files individually,
-instead of grouping them together as a single logically atomic
-operation.  It does not manage its file hierarchy well; it is easy to
-make a mess of a repository by renaming files and directories.  Worse,
-its source code is difficult to read and maintain, which made the
-``pain level'' of fixing these architectural problems prohibitive.
-
-In 2001, Jim Blandy and Karl Fogel, two developers who had worked on
-CVS, started a project to replace it with a tool that would have a
-better architecture and cleaner code.  The result, Subversion, does
-not stray from CVS's centralised client/server model, but it adds
-multi-file atomic commits, better namespace management, and a number
-of other features that make it a generally better tool than CVS.
-Since its initial release, it has rapidly grown in popularity.
-
-More or less simultaneously, Graydon Hoare began working on an
-ambitious distributed revision control system that he named Monotone.
-While Monotone addresses many of CVS's design flaws and has a
-peer-to-peer architecture, it goes beyond earlier (and subsequent)
-revision control tools in a number of innovative ways.  It uses
-cryptographic hashes as identifiers, and has an integral notion of
-``trust'' for code from different sources.
-
-Mercurial began life in 2005.  While a few aspects of its design are
-influenced by Monotone, Mercurial focuses on ease of use, high
-performance, and scalability to very large projects.
-
-\section{Trends in revision control}
-
-There has been an unmistakable trend in the development and use of
-revision control tools over the past four decades, as people have
-become familiar with the capabilities of their tools and constrained
-by their limitations.
-
-The first generation began by managing single files on individual
-computers.  Although these tools represented a huge advance over
-ad-hoc manual revision control, their locking model and reliance on a
-single computer limited them to small, tightly-knit teams.
-
-The second generation loosened these constraints by moving to
-network-centered architectures, and managing entire projects at a
-time.  As projects grew larger, they ran into new problems.  With
-clients needing to talk to servers very frequently, server scaling
-became an issue for large projects.  An unreliable network connection
-could prevent remote users from being able to talk to the server at
-all.  As open source projects started making read-only access
-available anonymously to anyone, people without commit privileges
-found that they could not use the tools to interact with a project in
-a natural way, as they could not record their changes.
-
-The current generation of revision control tools is peer-to-peer in
-nature.  All of these systems have dropped the dependency on a single
-central server, and allow people to distribute their revision control
-data to where it's actually needed.  Collaboration over the Internet
-has moved from constrained by technology to a matter of choice and
-consensus.  Modern tools can operate offline indefinitely and
-autonomously, with a network connection only needed when syncing
-changes with another repository.
-
-\section{A few of the advantages of distributed revision control}
-
-Even though distributed revision control tools have for several years
-been as robust and usable as their previous-generation counterparts,
-people using older tools have not yet necessarily woken up to their
-advantages.  There are a number of ways in which distributed tools
-shine relative to centralised ones.
-
-For an individual developer, distributed tools are almost always much
-faster than centralised tools.  This is for a simple reason: a
-centralised tool needs to talk over the network for many common
-operations, because most metadata is stored in a single copy on the
-central server.  A distributed tool stores all of its metadata
-locally.  All else being equal, talking over the network adds overhead
-to a centralised tool.  Don't underestimate the value of a snappy,
-responsive tool: you're going to spend a lot of time interacting with
-your revision control software.
-
-Distributed tools are indifferent to the vagaries of your server
-infrastructure, again because they replicate metadata to so many
-locations.  If you use a centralised system and your server catches
-fire, you'd better hope that your backup media are reliable, and that
-your last backup was recent and actually worked.  With a distributed
-tool, you have many backups available on every contributor's computer.
-
-The reliability of your network will affect distributed tools far less
-than it will centralised tools.  You can't even use a centralised tool
-without a network connection, except for a few highly constrained
-commands.  With a distributed tool, if your network connection goes
-down while you're working, you may not even notice.  The only thing
-you won't be able to do is talk to repositories on other computers,
-something that is relatively rare compared with local operations.  If
-you have a far-flung team of collaborators, this may be significant.
-
-\subsection{Advantages for open source projects}
-
-If you take a shine to an open source project and decide that you
-would like to start hacking on it, and that project uses a distributed
-revision control tool, you are at once a peer with the people who
-consider themselves the ``core'' of that project.  If they publish
-their repositories, you can immediately copy their project history,
-start making changes, and record your work, using the same tools in
-the same ways as insiders.  By contrast, with a centralised tool, you
-must use the software in a ``read only'' mode unless someone grants
-you permission to commit changes to their central server.  Until then,
-you won't be able to record changes, and your local modifications will
-be at risk of corruption any time you try to update your client's view
-of the repository.
-
-\subsubsection{The forking non-problem}
-
-It has been suggested that distributed revision control tools pose
-some sort of risk to open source projects because they make it easy to
-``fork'' the development of a project.  A fork happens when there are
-differences in opinion or attitude between groups of developers that
-cause them to decide that they can't work together any longer.  Each
-side takes a more or less complete copy of the project's source code,
-and goes off in its own direction.
-
-Sometimes the camps in a fork decide to reconcile their differences.
-With a centralised revision control system, the \emph{technical}
-process of reconciliation is painful, and has to be performed largely
-by hand.  You have to decide whose revision history is going to
-``win'', and graft the other team's changes into the tree somehow.
-This usually loses some or all of one side's revision history.
-
-What distributed tools do with respect to forking is they make forking
-the \emph{only} way to develop a project.  Every single change that
-you make is potentially a fork point.  The great strength of this
-approach is that a distributed revision control tool has to be really
-good at \emph{merging} forks, because forks are absolutely
-fundamental: they happen all the time.  
-
-If every piece of work that everybody does, all the time, is framed in
-terms of forking and merging, then what the open source world refers
-to as a ``fork'' becomes \emph{purely} a social issue.  If anything,
-distributed tools \emph{lower} the likelihood of a fork:
-\begin{itemize}
-\item They eliminate the social distinction that centralised tools
-  impose: that between insiders (people with commit access) and
-  outsiders (people without).
-\item They make it easier to reconcile after a social fork, because
-  all that's involved from the perspective of the revision control
-  software is just another merge.
-\end{itemize}
-
-Some people resist distributed tools because they want to retain tight
-control over their projects, and they believe that centralised tools
-give them this control.  However, if you're of this belief, and you
-publish your CVS or Subversion repositories publically, there are
-plenty of tools available that can pull out your entire project's
-history (albeit slowly) and recreate it somewhere that you don't
-control.  So while your control in this case is illusory, you are
-forgoing the ability to fluidly collaborate with whatever people feel
-compelled to mirror and fork your history.
-
-\subsection{Advantages for commercial projects}
-
-Many commercial projects are undertaken by teams that are scattered
-across the globe.  Contributors who are far from a central server will
-see slower command execution and perhaps less reliability.  Commercial
-revision control systems attempt to ameliorate these problems with
-remote-site replication add-ons that are typically expensive to buy
-and cantankerous to administer.  A distributed system doesn't suffer
-from these problems in the first place.  Better yet, you can easily
-set up multiple authoritative servers, say one per site, so that
-there's no redundant communication between repositories over expensive
-long-haul network links.
-
-Centralised revision control systems tend to have relatively low
-scalability.  It's not unusual for an expensive centralised system to
-fall over under the combined load of just a few dozen concurrent
-users.  Once again, the typical response tends to be an expensive and
-clunky replication facility.  Since the load on a central server---if
-you have one at all---is many times lower with a distributed
-tool (because all of the data is replicated everywhere), a single
-cheap server can handle the needs of a much larger team, and
-replication to balance load becomes a simple matter of scripting.
-
-If you have an employee in the field, troubleshooting a problem at a
-customer's site, they'll benefit from distributed revision control.
-The tool will let them generate custom builds, try different fixes in
-isolation from each other, and search efficiently through history for
-the sources of bugs and regressions in the customer's environment, all
-without needing to connect to your company's network.
-
-\section{Why choose Mercurial?}
-
-Mercurial has a unique set of properties that make it a particularly
-good choice as a revision control system.
-\begin{itemize}
-\item It is easy to learn and use.
-\item It is lightweight.
-\item It scales excellently.
-\item It is easy to customise.
-\end{itemize}
-
-If you are at all familiar with revision control systems, you should
-be able to get up and running with Mercurial in less than five
-minutes.  Even if not, it will take no more than a few minutes
-longer.  Mercurial's command and feature sets are generally uniform
-and consistent, so you can keep track of a few general rules instead
-of a host of exceptions.
-
-On a small project, you can start working with Mercurial in moments.
-Creating new changes and branches; transferring changes around
-(whether locally or over a network); and history and status operations
-are all fast.  Mercurial attempts to stay nimble and largely out of
-your way by combining low cognitive overhead with blazingly fast
-operations.
-
-The usefulness of Mercurial is not limited to small projects: it is
-used by projects with hundreds to thousands of contributors, each
-containing tens of thousands of files and hundreds of megabytes of
-source code.
-
-If the core functionality of Mercurial is not enough for you, it's
-easy to build on.  Mercurial is well suited to scripting tasks, and
-its clean internals and implementation in Python make it easy to add
-features in the form of extensions.  There are a number of popular and
-useful extensions already available, ranging from helping to identify
-bugs to improving performance.
-
-\section{Mercurial compared with other tools}
-
-Before you read on, please understand that this section necessarily
-reflects my own experiences, interests, and (dare I say it) biases.  I
-have used every one of the revision control tools listed below, in
-most cases for several years at a time.
-
-
-\subsection{Subversion}
-
-Subversion is a popular revision control tool, developed to replace
-CVS.  It has a centralised client/server architecture.
-
-Subversion and Mercurial have similarly named commands for performing
-the same operations, so if you're familiar with one, it is easy to
-learn to use the other.  Both tools are portable to all popular
-operating systems.
-
-Subversion lacks a history-aware merge capability, forcing its users
-to manually track exactly which revisions have been merged between
-branches.  If users fail to do this, or make mistakes, they face the
-prospect of manually resolving merges with unnecessary conflicts.
-Subversion also fails to merge changes when files or directories are
-renamed.  Subversion's poor merge support is its single biggest
-weakness.
-
-Mercurial has a substantial performance advantage over Subversion on
-every revision control operation I have benchmarked.  I have measured
-its advantage as ranging from a factor of two to a factor of six when
-compared with Subversion~1.4.3's \emph{ra\_local} file store, which is
-the fastest access method available).  In more realistic deployments
-involving a network-based store, Subversion will be at a substantially
-larger disadvantage.  Because many Subversion commands must talk to
-the server and Subversion does not have useful replication facilities,
-server capacity and network bandwidth become bottlenecks for modestly
-large projects.
-
-Additionally, Subversion incurs substantial storage overhead to avoid
-network transactions for a few common operations, such as finding
-modified files (\texttt{status}) and displaying modifications against
-the current revision (\texttt{diff}).  As a result, a Subversion
-working copy is often the same size as, or larger than, a Mercurial
-repository and working directory, even though the Mercurial repository
-contains a complete history of the project.
-
-Subversion is widely supported by third party tools.  Mercurial
-currently lags considerably in this area.  This gap is closing,
-however, and indeed some of Mercurial's GUI tools now outshine their
-Subversion equivalents.  Like Mercurial, Subversion has an excellent
-user manual.
-
-Because Subversion doesn't store revision history on the client, it is
-well suited to managing projects that deal with lots of large, opaque
-binary files.  If you check in fifty revisions to an incompressible
-10MB file, Subversion's client-side space usage stays constant The
-space used by any distributed SCM will grow rapidly in proportion to
-the number of revisions, because the differences between each revision
-are large.
-
-In addition, it's often difficult or, more usually, impossible to
-merge different versions of a binary file.  Subversion's ability to
-let a user lock a file, so that they temporarily have the exclusive
-right to commit changes to it, can be a significant advantage to a
-project where binary files are widely used.
-
-Mercurial can import revision history from a Subversion repository.
-It can also export revision history to a Subversion repository.  This
-makes it easy to ``test the waters'' and use Mercurial and Subversion
-in parallel before deciding to switch.  History conversion is
-incremental, so you can perform an initial conversion, then small
-additional conversions afterwards to bring in new changes.
-
-
-\subsection{Git}
-
-Git is a distributed revision control tool that was developed for
-managing the Linux kernel source tree.  Like Mercurial, its early
-design was somewhat influenced by Monotone.
-
-Git has a very large command set, with version~1.5.0 providing~139
-individual commands.  It has something of a reputation for being
-difficult to learn.  Compared to Git, Mercurial has a strong focus on
-simplicity.
-
-In terms of performance, Git is extremely fast.  In several cases, it
-is faster than Mercurial, at least on Linux, while Mercurial performs
-better on other operations.  However, on Windows, the performance and
-general level of support that Git provides is, at the time of writing,
-far behind that of Mercurial.
-
-While a Mercurial repository needs no maintenance, a Git repository
-requires frequent manual ``repacks'' of its metadata.  Without these,
-performance degrades, while space usage grows rapidly.  A server that
-contains many Git repositories that are not rigorously and frequently
-repacked will become heavily disk-bound during backups, and there have
-been instances of daily backups taking far longer than~24 hours as a
-result.  A freshly packed Git repository is slightly smaller than a
-Mercurial repository, but an unpacked repository is several orders of
-magnitude larger.
-
-The core of Git is written in C.  Many Git commands are implemented as
-shell or Perl scripts, and the quality of these scripts varies widely.
-I have encountered several instances where scripts charged along
-blindly in the presence of errors that should have been fatal.
-
-Mercurial can import revision history from a Git repository.
-
-
-\subsection{CVS}
-
-CVS is probably the most widely used revision control tool in the
-world.  Due to its age and internal untidiness, it has been only
-lightly maintained for many years.
-
-It has a centralised client/server architecture.  It does not group
-related file changes into atomic commits, making it easy for people to
-``break the build'': one person can successfully commit part of a
-change and then be blocked by the need for a merge, causing other
-people to see only a portion of the work they intended to do.  This
-also affects how you work with project history.  If you want to see
-all of the modifications someone made as part of a task, you will need
-to manually inspect the descriptions and timestamps of the changes
-made to each file involved (if you even know what those files were).
-
-CVS has a muddled notion of tags and branches that I will not attempt
-to even describe.  It does not support renaming of files or
-directories well, making it easy to corrupt a repository.  It has
-almost no internal consistency checking capabilities, so it is usually
-not even possible to tell whether or how a repository is corrupt.  I
-would not recommend CVS for any project, existing or new.
-
-Mercurial can import CVS revision history.  However, there are a few
-caveats that apply; these are true of every other revision control
-tool's CVS importer, too.  Due to CVS's lack of atomic changes and
-unversioned filesystem hierarchy, it is not possible to reconstruct
-CVS history completely accurately; some guesswork is involved, and
-renames will usually not show up.  Because a lot of advanced CVS
-administration has to be done by hand and is hence error-prone, it's
-common for CVS importers to run into multiple problems with corrupted
-repositories (completely bogus revision timestamps and files that have
-remained locked for over a decade are just two of the less interesting
-problems I can recall from personal experience).
-
-Mercurial can import revision history from a CVS repository.
-
-
-\subsection{Commercial tools}
-
-Perforce has a centralised client/server architecture, with no
-client-side caching of any data.  Unlike modern revision control
-tools, Perforce requires that a user run a command to inform the
-server about every file they intend to edit.
-
-The performance of Perforce is quite good for small teams, but it
-falls off rapidly as the number of users grows beyond a few dozen.
-Modestly large Perforce installations require the deployment of
-proxies to cope with the load their users generate.
-
-
-\subsection{Choosing a revision control tool}
-
-With the exception of CVS, all of the tools listed above have unique
-strengths that suit them to particular styles of work.  There is no
-single revision control tool that is best in all situations.
-
-As an example, Subversion is a good choice for working with frequently
-edited binary files, due to its centralised nature and support for
-file locking.  If you're averse to the command line, it currently has
-better GUI support than other free revision control tools.  However,
-its poor merging is a substantial liability for busy projects with
-overlapping development.
-
-I personally find Mercurial's properties of simplicity, performance,
-and good merge support to be a compelling combination that has served
-me well for several years.
-
-
-\section{Switching from another tool to Mercurial}
-
-Mercurial is bundled with an extension named \hgext{convert}, which
-can incrementally import revision history from several other revision
-control tools.  By ``incremental'', I mean that you can convert all of
-a project's history to date in one go, then rerun the conversion later
-to obtain new changes that happened after the initial conversion.
-
-The revision control tools supported by \hgext{convert} are as
-follows:
-\begin{itemize}
-\item Subversion
-\item CVS
-\item Git
-\item Darcs
-\end{itemize}
-
-In addition, \hgext{convert} can export changes from Mercurial to
-Subversion.  This makes it possible to try Subversion and Mercurial in
-parallel before committing to a switchover, without risking the loss
-of any work.
-
-The \hgxcmd{conver}{convert} command is easy to use.  Simply point it
-at the path or URL of the source repository, optionally give it the
-name of the destination repository, and it will start working.  After
-the initial conversion, just run the same command again to import new
-changes.
-
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
Binary file en/kdiff3.png has changed
--- a/en/license.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-\chapter{Open Publication License}
-\label{cha:opl}
-
-Version 1.0, 8 June 1999
-
-\section{Requirements on both unmodified and modified versions}
-
-The Open Publication works may be reproduced and distributed in whole
-or in part, in any medium physical or electronic, provided that the
-terms of this license are adhered to, and that this license or an
-incorporation of it by reference (with any options elected by the
-author(s) and/or publisher) is displayed in the reproduction.
-
-Proper form for an incorporation by reference is as follows:
-
-\begin{quote}
-  Copyright (c) \emph{year} by \emph{author's name or designee}. This
-  material may be distributed only subject to the terms and conditions
-  set forth in the Open Publication License, v\emph{x.y} or later (the
-  latest version is presently available at
-  \url{http://www.opencontent.org/openpub/}).
-\end{quote}
-
-The reference must be immediately followed with any options elected by
-the author(s) and/or publisher of the document (see
-section~\ref{sec:opl:options}).
-
-Commercial redistribution of Open Publication-licensed material is
-permitted.
-
-Any publication in standard (paper) book form shall require the
-citation of the original publisher and author. The publisher and
-author's names shall appear on all outer surfaces of the book. On all
-outer surfaces of the book the original publisher's name shall be as
-large as the title of the work and cited as possessive with respect to
-the title.
-
-\section{Copyright}
-
-The copyright to each Open Publication is owned by its author(s) or
-designee.
-
-\section{Scope of license}
-
-The following license terms apply to all Open Publication works,
-unless otherwise explicitly stated in the document.
-
-Mere aggregation of Open Publication works or a portion of an Open
-Publication work with other works or programs on the same media shall
-not cause this license to apply to those other works. The aggregate
-work shall contain a notice specifying the inclusion of the Open
-Publication material and appropriate copyright notice.
-
-\textbf{Severability}. If any part of this license is found to be
-unenforceable in any jurisdiction, the remaining portions of the
-license remain in force.
-
-\textbf{No warranty}. Open Publication works are licensed and provided
-``as is'' without warranty of any kind, express or implied, including,
-but not limited to, the implied warranties of merchantability and
-fitness for a particular purpose or a warranty of non-infringement.
-
-\section{Requirements on modified works}
-
-All modified versions of documents covered by this license, including
-translations, anthologies, compilations and partial documents, must
-meet the following requirements:
-
-\begin{enumerate}
-\item The modified version must be labeled as such.
-\item The person making the modifications must be identified and the
-  modifications dated.
-\item Acknowledgement of the original author and publisher if
-  applicable must be retained according to normal academic citation
-  practices.
-\item The location of the original unmodified document must be
-  identified.
-\item The original author's (or authors') name(s) may not be used to
-  assert or imply endorsement of the resulting document without the
-  original author's (or authors') permission.
-\end{enumerate}
-
-\section{Good-practice recommendations}
-
-In addition to the requirements of this license, it is requested from
-and strongly recommended of redistributors that:
-
-\begin{enumerate}
-\item If you are distributing Open Publication works on hardcopy or
-  CD-ROM, you provide email notification to the authors of your intent
-  to redistribute at least thirty days before your manuscript or media
-  freeze, to give the authors time to provide updated documents. This
-  notification should describe modifications, if any, made to the
-  document.
-\item All substantive modifications (including deletions) be either
-  clearly marked up in the document or else described in an attachment
-  to the document.
-\item Finally, while it is not mandatory under this license, it is
-  considered good form to offer a free copy of any hardcopy and CD-ROM
-  expression of an Open Publication-licensed work to its author(s).
-\end{enumerate}
-
-\section{License options}
-\label{sec:opl:options}
-
-The author(s) and/or publisher of an Open Publication-licensed
-document may elect certain options by appending language to the
-reference to or copy of the license. These options are considered part
-of the license instance and must be included with the license (or its
-incorporation by reference) in derived works.
-
-\begin{enumerate}[A]
-\item To prohibit distribution of substantively modified versions
-  without the explicit permission of the author(s). ``Substantive
-  modification'' is defined as a change to the semantic content of the
-  document, and excludes mere changes in format or typographical
-  corrections.
-
-  To accomplish this, add the phrase ``Distribution of substantively
-  modified versions of this document is prohibited without the
-  explicit permission of the copyright holder.'' to the license
-  reference or copy.
-
-\item To prohibit any publication of this work or derivative works in
-  whole or in part in standard (paper) book form for commercial
-  purposes is prohibited unless prior permission is obtained from the
-  copyright holder.
-
-  To accomplish this, add the phrase ``Distribution of the work or
-  derivative of the work in any standard (paper) book form is
-  prohibited unless prior permission is obtained from the copyright
-  holder.'' to the license reference or copy.
-\end{enumerate}
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/metadata.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="metadata.svg"
-   sodipodi:docbase="/home/bos/hg/hgbook/en">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path2944"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="232.14286"
-     inkscape:cy="490.68696"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="181"
-     inkscape:window-y="58" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 326.94646,467.18359 L 326.94646,510.98123"
-       id="path1910"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2962"
-       inkscape:connection-start="#rect2764" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 326.94646,531.98123 L 326.94646,591.77887"
-       id="path1912"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2962"
-       inkscape:connection-end="#rect3000" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 316.1622,531.98123 L 192.30212,652.57648"
-       id="path1916"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect3038"
-       inkscape:connection-start="#rect2962" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 254.23217,467.18359 L 254.23216,510.98123"
-       id="path3088"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect1872"
-       inkscape:connection-end="#rect2960" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 254.23215,531.98123 L 254.23215,591.77887"
-       id="path3090"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2960"
-       inkscape:connection-end="#rect2998" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 248.84002,531.98123 L 186.90999,652.57648"
-       id="path3092"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2960"
-       inkscape:connection-end="#rect3038" />
-    <rect
-       style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect1872"
-       width="51.42857"
-       height="20"
-       x="228.51788"
-       y="446.68359" />
-    <rect
-       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2764"
-       width="51.42857"
-       height="20"
-       x="301.23218"
-       y="446.68359" />
-    <rect
-       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2766"
-       width="51.42857"
-       height="20"
-       x="155.80359"
-       y="446.68359" />
-    <rect
-       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2768"
-       width="51.42857"
-       height="20"
-       x="83.089294"
-       y="446.68359" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 135.01786,456.68359 L 155.30359,456.68359"
-       id="path2770"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2768"
-       inkscape:connection-end="#rect2766" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 207.73216,456.68359 L 228.01788,456.68359"
-       id="path2772"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2766"
-       inkscape:connection-end="#rect1872" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 280.44645,456.68359 L 300.73218,456.68359"
-       id="path2774"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect1872"
-       inkscape:connection-end="#rect2764" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 62.303571,456.68359 L 82.589294,456.68359"
-       id="path2778"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2768" />
-    <rect
-       style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2960"
-       width="51.42857"
-       height="20"
-       x="228.51787"
-       y="511.48123" />
-    <rect
-       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2962"
-       width="51.42857"
-       height="20"
-       x="301.23218"
-       y="511.48123" />
-    <rect
-       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2964"
-       width="51.42857"
-       height="20"
-       x="155.80357"
-       y="511.48123" />
-    <rect
-       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2966"
-       width="51.42857"
-       height="20"
-       x="83.089287"
-       y="511.48123" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 135.01786,521.48121 L 155.30359,521.48121"
-       id="path2968"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 207.73216,521.48121 L 228.01788,521.48121"
-       id="path2970"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 280.44645,521.48121 L 300.73218,521.48121"
-       id="path2972"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 62.30358,521.48121 L 82.5893,521.48121"
-       id="path2974"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2998"
-       width="51.42857"
-       height="20"
-       x="228.51787"
-       y="592.27887" />
-    <rect
-       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3000"
-       width="51.42857"
-       height="20"
-       x="301.23218"
-       y="592.27887" />
-    <rect
-       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3002"
-       width="51.42857"
-       height="20"
-       x="155.80357"
-       y="592.27887" />
-    <rect
-       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3004"
-       width="51.42857"
-       height="20"
-       x="83.089287"
-       y="592.27887" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 135.01786,602.27884 L 155.30359,602.27884"
-       id="path3006"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 207.73216,602.27884 L 228.01788,602.27884"
-       id="path3008"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 280.44645,602.27884 L 300.73218,602.27884"
-       id="path3010"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 62.30358,602.27884 L 82.5893,602.27884"
-       id="path3012"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3034"
-       width="51.42857"
-       height="20"
-       x="228.51787"
-       y="653.07648" />
-    <rect
-       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3038"
-       width="51.42857"
-       height="20"
-       x="155.80357"
-       y="653.07648" />
-    <rect
-       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3040"
-       width="51.42857"
-       height="20"
-       x="83.089287"
-       y="653.07648" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 135.01786,663.07646 L 155.30359,663.07646"
-       id="path3042"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 207.73216,663.07646 L 228.01788,663.07646"
-       id="path3044"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 62.30358,663.07646 L 82.5893,663.07646"
-       id="path3048"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="82.072548"
-       y="432.64789"
-       id="text3094"><tspan
-         sodipodi:role="line"
-         id="tspan3096"
-         x="82.072548"
-         y="432.64789">Changelog</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="82.306923"
-       y="498.97327"
-       id="text3098"><tspan
-         sodipodi:role="line"
-         id="tspan3100"
-         x="82.306923"
-         y="498.97327">Manifest</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="82.14286"
-       y="580.08569"
-       id="text3102"><tspan
-         sodipodi:role="line"
-         id="tspan3104"
-         x="82.14286"
-         y="580.08569">Filelogs</tspan></text>
-  </g>
-</svg>
--- a/en/mq-collab.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,393 +0,0 @@
-\chapter{Advanced uses of Mercurial Queues}
-\label{chap:mq-collab}
-
-While it's easy to pick up straightforward uses of Mercurial Queues,
-use of a little discipline and some of MQ's less frequently used
-capabilities makes it possible to work in complicated development
-environments.
-
-In this chapter, I will use as an example a technique I have used to
-manage the development of an Infiniband device driver for the Linux
-kernel.  The driver in question is large (at least as drivers go),
-with 25,000 lines of code spread across 35 source files.  It is
-maintained by a small team of developers.
-
-While much of the material in this chapter is specific to Linux, the
-same principles apply to any code base for which you're not the
-primary owner, and upon which you need to do a lot of development.
-
-\section{The problem of many targets}
-
-The Linux kernel changes rapidly, and has never been internally
-stable; developers frequently make drastic changes between releases.
-This means that a version of the driver that works well with a
-particular released version of the kernel will not even \emph{compile}
-correctly against, typically, any other version.
-
-To maintain a driver, we have to keep a number of distinct versions of
-Linux in mind.
-\begin{itemize}
-\item One target is the main Linux kernel development tree.
-  Maintenance of the code is in this case partly shared by other
-  developers in the kernel community, who make ``drive-by''
-  modifications to the driver as they develop and refine kernel
-  subsystems.
-\item We also maintain a number of ``backports'' to older versions of
-  the Linux kernel, to support the needs of customers who are running
-  older Linux distributions that do not incorporate our drivers.  (To
-  \emph{backport} a piece of code is to modify it to work in an older
-  version of its target environment than the version it was developed
-  for.)
-\item Finally, we make software releases on a schedule that is
-  necessarily not aligned with those used by Linux distributors and
-  kernel developers, so that we can deliver new features to customers
-  without forcing them to upgrade their entire kernels or
-  distributions.
-\end{itemize}
-
-\subsection{Tempting approaches that don't work well}
-
-There are two ``standard'' ways to maintain a piece of software that
-has to target many different environments.
-
-The first is to maintain a number of branches, each intended for a
-single target.  The trouble with this approach is that you must
-maintain iron discipline in the flow of changes between repositories.
-A new feature or bug fix must start life in a ``pristine'' repository,
-then percolate out to every backport repository.  Backport changes are
-more limited in the branches they should propagate to; a backport
-change that is applied to a branch where it doesn't belong will
-probably stop the driver from compiling.
-
-The second is to maintain a single source tree filled with conditional
-statements that turn chunks of code on or off depending on the
-intended target.  Because these ``ifdefs'' are not allowed in the
-Linux kernel tree, a manual or automatic process must be followed to
-strip them out and yield a clean tree.  A code base maintained in this
-fashion rapidly becomes a rat's nest of conditional blocks that are
-difficult to understand and maintain.
-
-Neither of these approaches is well suited to a situation where you
-don't ``own'' the canonical copy of a source tree.  In the case of a
-Linux driver that is distributed with the standard kernel, Linus's
-tree contains the copy of the code that will be treated by the world
-as canonical.  The upstream version of ``my'' driver can be modified
-by people I don't know, without me even finding out about it until
-after the changes show up in Linus's tree.  
-
-These approaches have the added weakness of making it difficult to
-generate well-formed patches to submit upstream.
-
-In principle, Mercurial Queues seems like a good candidate to manage a
-development scenario such as the above.  While this is indeed the
-case, MQ contains a few added features that make the job more
-pleasant.
-
-\section{Conditionally applying patches with 
-  guards}
-
-Perhaps the best way to maintain sanity with so many targets is to be
-able to choose specific patches to apply for a given situation.  MQ
-provides a feature called ``guards'' (which originates with quilt's
-\texttt{guards} command) that does just this.  To start off, let's
-create a simple repository for experimenting in.
-\interaction{mq.guards.init}
-This gives us a tiny repository that contains two patches that don't
-have any dependencies on each other, because they touch different files.
-
-The idea behind conditional application is that you can ``tag'' a
-patch with a \emph{guard}, which is simply a text string of your
-choosing, then tell MQ to select specific guards to use when applying
-patches.  MQ will then either apply, or skip over, a guarded patch,
-depending on the guards that you have selected.
-
-A patch can have an arbitrary number of guards;
-each one is \emph{positive} (``apply this patch if this guard is
-selected'') or \emph{negative} (``skip this patch if this guard is
-selected'').  A patch with no guards is always applied.
-
-\section{Controlling the guards on a patch}
-
-The \hgxcmd{mq}{qguard} command lets you determine which guards should
-apply to a patch, or display the guards that are already in effect.
-Without any arguments, it displays the guards on the current topmost
-patch.
-\interaction{mq.guards.qguard}
-To set a positive guard on a patch, prefix the name of the guard with
-a ``\texttt{+}''.
-\interaction{mq.guards.qguard.pos}
-To set a negative guard on a patch, prefix the name of the guard with
-a ``\texttt{-}''.
-\interaction{mq.guards.qguard.neg}
-
-\begin{note}
-  The \hgxcmd{mq}{qguard} command \emph{sets} the guards on a patch; it
-  doesn't \emph{modify} them.  What this means is that if you run
-  \hgcmdargs{qguard}{+a +b} on a patch, then \hgcmdargs{qguard}{+c} on
-  the same patch, the \emph{only} guard that will be set on it
-  afterwards is \texttt{+c}.
-\end{note}
-
-Mercurial stores guards in the \sfilename{series} file; the form in
-which they are stored is easy both to understand and to edit by hand.
-(In other words, you don't have to use the \hgxcmd{mq}{qguard} command if
-you don't want to; it's okay to simply edit the \sfilename{series}
-file.)
-\interaction{mq.guards.series}
-
-\section{Selecting the guards to use}
-
-The \hgxcmd{mq}{qselect} command determines which guards are active at a
-given time.  The effect of this is to determine which patches MQ will
-apply the next time you run \hgxcmd{mq}{qpush}.  It has no other effect; in
-particular, it doesn't do anything to patches that are already
-applied.
-
-With no arguments, the \hgxcmd{mq}{qselect} command lists the guards
-currently in effect, one per line of output.  Each argument is treated
-as the name of a guard to apply.
-\interaction{mq.guards.qselect.foo}
-In case you're interested, the currently selected guards are stored in
-the \sfilename{guards} file.
-\interaction{mq.guards.qselect.cat}
-We can see the effect the selected guards have when we run
-\hgxcmd{mq}{qpush}.
-\interaction{mq.guards.qselect.qpush}
-
-A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
-character.  The name of a guard must not contain white space, but most
-othter characters are acceptable.  If you try to use a guard with an
-invalid name, MQ will complain:
-\interaction{mq.guards.qselect.error} 
-Changing the selected guards changes the patches that are applied.
-\interaction{mq.guards.qselect.quux} 
-You can see in the example below that negative guards take precedence
-over positive guards.
-\interaction{mq.guards.qselect.foobar}
-
-\section{MQ's rules for applying patches}
-
-The rules that MQ uses when deciding whether to apply a patch
-are as follows.
-\begin{itemize}
-\item A patch that has no guards is always applied.
-\item If the patch has any negative guard that matches any currently
-  selected guard, the patch is skipped.
-\item If the patch has any positive guard that matches any currently
-  selected guard, the patch is applied.
-\item If the patch has positive or negative guards, but none matches
-  any currently selected guard, the patch is skipped.
-\end{itemize}
-
-\section{Trimming the work environment}
-
-In working on the device driver I mentioned earlier, I don't apply the
-patches to a normal Linux kernel tree.  Instead, I use a repository
-that contains only a snapshot of the source files and headers that are
-relevant to Infiniband development.  This repository is~1\% the size
-of a kernel repository, so it's easier to work with.
-
-I then choose a ``base'' version on top of which the patches are
-applied.  This is a snapshot of the Linux kernel tree as of a revision
-of my choosing.  When I take the snapshot, I record the changeset ID
-from the kernel repository in the commit message.  Since the snapshot
-preserves the ``shape'' and content of the relevant parts of the
-kernel tree, I can apply my patches on top of either my tiny
-repository or a normal kernel tree.
-
-Normally, the base tree atop which the patches apply should be a
-snapshot of a very recent upstream tree.  This best facilitates the
-development of patches that can easily be submitted upstream with few
-or no modifications.
-
-\section{Dividing up the \sfilename{series} file}
-
-I categorise the patches in the \sfilename{series} file into a number
-of logical groups.  Each section of like patches begins with a block
-of comments that describes the purpose of the patches that follow.
-
-The sequence of patch groups that I maintain follows.  The ordering of
-these groups is important; I'll describe why after I introduce the
-groups.
-\begin{itemize}
-\item The ``accepted'' group.  Patches that the development team has
-  submitted to the maintainer of the Infiniband subsystem, and which
-  he has accepted, but which are not present in the snapshot that the
-  tiny repository is based on.  These are ``read only'' patches,
-  present only to transform the tree into a similar state as it is in
-  the upstream maintainer's repository.
-\item The ``rework'' group.  Patches that I have submitted, but that
-  the upstream maintainer has requested modifications to before he
-  will accept them.
-\item The ``pending'' group.  Patches that I have not yet submitted to
-  the upstream maintainer, but which we have finished working on.
-  These will be ``read only'' for a while.  If the upstream maintainer
-  accepts them upon submission, I'll move them to the end of the
-  ``accepted'' group.  If he requests that I modify any, I'll move
-  them to the beginning of the ``rework'' group.
-\item The ``in progress'' group.  Patches that are actively being
-  developed, and should not be submitted anywhere yet.
-\item The ``backport'' group.  Patches that adapt the source tree to
-  older versions of the kernel tree.
-\item The ``do not ship'' group.  Patches that for some reason should
-  never be submitted upstream.  For example, one such patch might
-  change embedded driver identification strings to make it easier to
-  distinguish, in the field, between an out-of-tree version of the
-  driver and a version shipped by a distribution vendor.
-\end{itemize}
-
-Now to return to the reasons for ordering groups of patches in this
-way.  We would like the lowest patches in the stack to be as stable as
-possible, so that we will not need to rework higher patches due to
-changes in context.  Putting patches that will never be changed first
-in the \sfilename{series} file serves this purpose.
-
-We would also like the patches that we know we'll need to modify to be
-applied on top of a source tree that resembles the upstream tree as
-closely as possible.  This is why we keep accepted patches around for
-a while.
-
-The ``backport'' and ``do not ship'' patches float at the end of the
-\sfilename{series} file.  The backport patches must be applied on top
-of all other patches, and the ``do not ship'' patches might as well
-stay out of harm's way.
-
-\section{Maintaining the patch series}
-
-In my work, I use a number of guards to control which patches are to
-be applied.
-
-\begin{itemize}
-\item ``Accepted'' patches are guarded with \texttt{accepted}.  I
-  enable this guard most of the time.  When I'm applying the patches
-  on top of a tree where the patches are already present, I can turn
-  this patch off, and the patches that follow it will apply cleanly.
-\item Patches that are ``finished'', but not yet submitted, have no
-  guards.  If I'm applying the patch stack to a copy of the upstream
-  tree, I don't need to enable any guards in order to get a reasonably
-  safe source tree.
-\item Those patches that need reworking before being resubmitted are
-  guarded with \texttt{rework}.
-\item For those patches that are still under development, I use
-  \texttt{devel}.
-\item A backport patch may have several guards, one for each version
-  of the kernel to which it applies.  For example, a patch that
-  backports a piece of code to~2.6.9 will have a~\texttt{2.6.9} guard.
-\end{itemize}
-This variety of guards gives me considerable flexibility in
-qdetermining what kind of source tree I want to end up with.  For most
-situations, the selection of appropriate guards is automated during
-the build process, but I can manually tune the guards to use for less
-common circumstances.
-
-\subsection{The art of writing backport patches}
-
-Using MQ, writing a backport patch is a simple process.  All such a
-patch has to do is modify a piece of code that uses a kernel feature
-not present in the older version of the kernel, so that the driver
-continues to work correctly under that older version.
-
-A useful goal when writing a good backport patch is to make your code
-look as if it was written for the older version of the kernel you're
-targeting.  The less obtrusive the patch, the easier it will be to
-understand and maintain.  If you're writing a collection of backport
-patches to avoid the ``rat's nest'' effect of lots of
-\texttt{\#ifdef}s (hunks of source code that are only used
-conditionally) in your code, don't introduce version-dependent
-\texttt{\#ifdef}s into the patches.  Instead, write several patches,
-each of which makes unconditional changes, and control their
-application using guards.
-
-There are two reasons to divide backport patches into a distinct
-group, away from the ``regular'' patches whose effects they modify.
-The first is that intermingling the two makes it more difficult to use
-a tool like the \hgext{patchbomb} extension to automate the process of
-submitting the patches to an upstream maintainer.  The second is that
-a backport patch could perturb the context in which a subsequent
-regular patch is applied, making it impossible to apply the regular
-patch cleanly \emph{without} the earlier backport patch already being
-applied.
-
-\section{Useful tips for developing with MQ}
-
-\subsection{Organising patches in directories}
-
-If you're working on a substantial project with MQ, it's not difficult
-to accumulate a large number of patches.  For example, I have one
-patch repository that contains over 250 patches.
-
-If you can group these patches into separate logical categories, you
-can if you like store them in different directories; MQ has no
-problems with patch names that contain path separators.
-
-\subsection{Viewing the history of a patch}
-\label{mq-collab:tips:interdiff}
-
-If you're developing a set of patches over a long time, it's a good
-idea to maintain them in a repository, as discussed in
-section~\ref{sec:mq:repo}.  If you do so, you'll quickly discover that
-using the \hgcmd{diff} command to look at the history of changes to a
-patch is unworkable.  This is in part because you're looking at the
-second derivative of the real code (a diff of a diff), but also
-because MQ adds noise to the process by modifying time stamps and
-directory names when it updates a patch.
-
-However, you can use the \hgext{extdiff} extension, which is bundled
-with Mercurial, to turn a diff of two versions of a patch into
-something readable.  To do this, you will need a third-party package
-called \package{patchutils}~\cite{web:patchutils}.  This provides a
-command named \command{interdiff}, which shows the differences between
-two diffs as a diff.  Used on two versions of the same diff, it
-generates a diff that represents the diff from the first to the second
-version.
-
-You can enable the \hgext{extdiff} extension in the usual way, by
-adding a line to the \rcsection{extensions} section of your \hgrc.
-\begin{codesample2}
-  [extensions]
-  extdiff =
-\end{codesample2}
-The \command{interdiff} command expects to be passed the names of two
-files, but the \hgext{extdiff} extension passes the program it runs a
-pair of directories, each of which can contain an arbitrary number of
-files.  We thus need a small program that will run \command{interdiff}
-on each pair of files in these two directories.  This program is
-available as \sfilename{hg-interdiff} in the \dirname{examples}
-directory of the source code repository that accompanies this book.
-\excode{hg-interdiff}
-
-With the \sfilename{hg-interdiff} program in your shell's search path,
-you can run it as follows, from inside an MQ patch directory:
-\begin{codesample2}
-  hg extdiff -p hg-interdiff -r A:B my-change.patch
-\end{codesample2}
-Since you'll probably want to use this long-winded command a lot, you
-can get \hgext{hgext} to make it available as a normal Mercurial
-command, again by editing your \hgrc.
-\begin{codesample2}
-  [extdiff]
-  cmd.interdiff = hg-interdiff
-\end{codesample2}
-This directs \hgext{hgext} to make an \texttt{interdiff} command
-available, so you can now shorten the previous invocation of
-\hgxcmd{extdiff}{extdiff} to something a little more wieldy.
-\begin{codesample2}
-  hg interdiff -r A:B my-change.patch
-\end{codesample2}
-
-\begin{note}
-  The \command{interdiff} command works well only if the underlying
-  files against which versions of a patch are generated remain the
-  same.  If you create a patch, modify the underlying files, and then
-  regenerate the patch, \command{interdiff} may not produce useful
-  output.
-\end{note}
-
-The \hgext{extdiff} extension is useful for more than merely improving
-the presentation of MQ~patches.  To read more about it, go to
-section~\ref{sec:hgext:extdiff}.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/mq-ref.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,349 +0,0 @@
-\chapter{Mercurial Queues reference}
-\label{chap:mqref}
-
-\section{MQ command reference}
-\label{sec:mqref:cmdref}
-
-For an overview of the commands provided by MQ, use the command
-\hgcmdargs{help}{mq}.
-
-\subsection{\hgxcmd{mq}{qapplied}---print applied patches}
-
-The \hgxcmd{mq}{qapplied} command prints the current stack of applied
-patches.  Patches are printed in oldest-to-newest order, so the last
-patch in the list is the ``top'' patch.
-
-\subsection{\hgxcmd{mq}{qcommit}---commit changes in the queue repository}
-
-The \hgxcmd{mq}{qcommit} command commits any outstanding changes in the
-\sdirname{.hg/patches} repository.  This command only works if the
-\sdirname{.hg/patches} directory is a repository, i.e.~you created the
-directory using \hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} or ran
-\hgcmd{init} in the directory after running \hgxcmd{mq}{qinit}.
-
-This command is shorthand for \hgcmdargs{commit}{--cwd .hg/patches}.
-
-\subsection{\hgxcmd{mq}{qdelete}---delete a patch from the
-  \sfilename{series} file}
-
-The \hgxcmd{mq}{qdelete} command removes the entry for a patch from the
-\sfilename{series} file in the \sdirname{.hg/patches} directory.  It
-does not pop the patch if the patch is already applied.  By default,
-it does not delete the patch file; use the \hgxopt{mq}{qdel}{-f} option to
-do that.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qdel}{-f}] Delete the patch file.
-\end{itemize}
-
-\subsection{\hgxcmd{mq}{qdiff}---print a diff of the topmost applied patch}
-
-The \hgxcmd{mq}{qdiff} command prints a diff of the topmost applied patch.
-It is equivalent to \hgcmdargs{diff}{-r-2:-1}.
-
-\subsection{\hgxcmd{mq}{qfold}---merge (``fold'') several patches into one}
-
-The \hgxcmd{mq}{qfold} command merges multiple patches into the topmost
-applied patch, so that the topmost applied patch makes the union of
-all of the changes in the patches in question.
-
-The patches to fold must not be applied; \hgxcmd{mq}{qfold} will exit with
-an error if any is.  The order in which patches are folded is
-significant; \hgcmdargs{qfold}{a b} means ``apply the current topmost
-patch, followed by \texttt{a}, followed by \texttt{b}''.
-
-The comments from the folded patches are appended to the comments of
-the destination patch, with each block of comments separated by three
-asterisk (``\texttt{*}'') characters.  Use the \hgxopt{mq}{qfold}{-e}
-option to edit the commit message for the combined patch/changeset
-after the folding has completed.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qfold}{-e}] Edit the commit message and patch description
-  for the newly folded patch.
-\item[\hgxopt{mq}{qfold}{-l}] Use the contents of the given file as the new
-  commit message and patch description for the folded patch.
-\item[\hgxopt{mq}{qfold}{-m}] Use the given text as the new commit message
-  and patch description for the folded patch.
-\end{itemize}
-
-\subsection{\hgxcmd{mq}{qheader}---display the header/description of a patch}
-
-The \hgxcmd{mq}{qheader} command prints the header, or description, of a
-patch.  By default, it prints the header of the topmost applied patch.
-Given an argument, it prints the header of the named patch.
-
-\subsection{\hgxcmd{mq}{qimport}---import a third-party patch into the queue}
-
-The \hgxcmd{mq}{qimport} command adds an entry for an external patch to the
-\sfilename{series} file, and copies the patch into the
-\sdirname{.hg/patches} directory.  It adds the entry immediately after
-the topmost applied patch, but does not push the patch.
-
-If the \sdirname{.hg/patches} directory is a repository,
-\hgxcmd{mq}{qimport} automatically does an \hgcmd{add} of the imported
-patch.
-
-\subsection{\hgxcmd{mq}{qinit}---prepare a repository to work with MQ}
-
-The \hgxcmd{mq}{qinit} command prepares a repository to work with MQ.  It
-creates a directory called \sdirname{.hg/patches}.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qinit}{-c}] Create \sdirname{.hg/patches} as a repository
-  in its own right.  Also creates a \sfilename{.hgignore} file that
-  will ignore the \sfilename{status} file.
-\end{itemize}
-
-When the \sdirname{.hg/patches} directory is a repository, the
-\hgxcmd{mq}{qimport} and \hgxcmd{mq}{qnew} commands automatically \hgcmd{add}
-new patches.
-
-\subsection{\hgxcmd{mq}{qnew}---create a new patch}
-
-The \hgxcmd{mq}{qnew} command creates a new patch.  It takes one mandatory
-argument, the name to use for the patch file.  The newly created patch
-is created empty by default.  It is added to the \sfilename{series}
-file after the current topmost applied patch, and is immediately
-pushed on top of that patch.
-
-If \hgxcmd{mq}{qnew} finds modified files in the working directory, it will
-refuse to create a new patch unless the \hgxopt{mq}{qnew}{-f} option is
-used (see below).  This behaviour allows you to \hgxcmd{mq}{qrefresh} your
-topmost applied patch before you apply a new patch on top of it.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qnew}{-f}] Create a new patch if the contents of the
-  working directory are modified.  Any outstanding modifications are
-  added to the newly created patch, so after this command completes,
-  the working directory will no longer be modified.
-\item[\hgxopt{mq}{qnew}{-m}] Use the given text as the commit message.
-  This text will be stored at the beginning of the patch file, before
-  the patch data.
-\end{itemize}
-
-\subsection{\hgxcmd{mq}{qnext}---print the name of the next patch}
-
-The \hgxcmd{mq}{qnext} command prints the name name of the next patch in
-the \sfilename{series} file after the topmost applied patch.  This
-patch will become the topmost applied patch if you run \hgxcmd{mq}{qpush}.
-
-\subsection{\hgxcmd{mq}{qpop}---pop patches off the stack}
-
-The \hgxcmd{mq}{qpop} command removes applied patches from the top of the
-stack of applied patches.  By default, it removes only one patch.
-
-This command removes the changesets that represent the popped patches
-from the repository, and updates the working directory to undo the
-effects of the patches.
-
-This command takes an optional argument, which it uses as the name or
-index of the patch to pop to.  If given a name, it will pop patches
-until the named patch is the topmost applied patch.  If given a
-number, \hgxcmd{mq}{qpop} treats the number as an index into the entries in
-the series file, counting from zero (empty lines and lines containing
-only comments do not count).  It pops patches until the patch
-identified by the given index is the topmost applied patch.
-
-The \hgxcmd{mq}{qpop} command does not read or write patches or the
-\sfilename{series} file.  It is thus safe to \hgxcmd{mq}{qpop} a patch that
-you have removed from the \sfilename{series} file, or a patch that you
-have renamed or deleted entirely.  In the latter two cases, use the
-name of the patch as it was when you applied it.
-
-By default, the \hgxcmd{mq}{qpop} command will not pop any patches if the
-working directory has been modified.  You can override this behaviour
-using the \hgxopt{mq}{qpop}{-f} option, which reverts all modifications in
-the working directory.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qpop}{-a}] Pop all applied patches.  This returns the
-  repository to its state before you applied any patches.
-\item[\hgxopt{mq}{qpop}{-f}] Forcibly revert any modifications to the
-  working directory when popping.
-\item[\hgxopt{mq}{qpop}{-n}] Pop a patch from the named queue.
-\end{itemize}
-
-The \hgxcmd{mq}{qpop} command removes one line from the end of the
-\sfilename{status} file for each patch that it pops.
-
-\subsection{\hgxcmd{mq}{qprev}---print the name of the previous patch}
-
-The \hgxcmd{mq}{qprev} command prints the name of the patch in the
-\sfilename{series} file that comes before the topmost applied patch.
-This will become the topmost applied patch if you run \hgxcmd{mq}{qpop}.
-
-\subsection{\hgxcmd{mq}{qpush}---push patches onto the stack}
-\label{sec:mqref:cmd:qpush}
-
-The \hgxcmd{mq}{qpush} command adds patches onto the applied stack.  By
-default, it adds only one patch.
-
-This command creates a new changeset to represent each applied patch,
-and updates the working directory to apply the effects of the patches.
-
-The default data used when creating a changeset are as follows:
-\begin{itemize}
-\item The commit date and time zone are the current date and time
-  zone.  Because these data are used to compute the identity of a
-  changeset, this means that if you \hgxcmd{mq}{qpop} a patch and
-  \hgxcmd{mq}{qpush} it again, the changeset that you push will have a
-  different identity than the changeset you popped.
-\item The author is the same as the default used by the \hgcmd{commit}
-  command.
-\item The commit message is any text from the patch file that comes
-  before the first diff header.  If there is no such text, a default
-  commit message is used that identifies the name of the patch.
-\end{itemize}
-If a patch contains a Mercurial patch header (XXX add link), the
-information in the patch header overrides these defaults.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qpush}{-a}] Push all unapplied patches from the
-  \sfilename{series} file until there are none left to push.
-\item[\hgxopt{mq}{qpush}{-l}] Add the name of the patch to the end
-  of the commit message.
-\item[\hgxopt{mq}{qpush}{-m}] If a patch fails to apply cleanly, use the
-  entry for the patch in another saved queue to compute the parameters
-  for a three-way merge, and perform a three-way merge using the
-  normal Mercurial merge machinery.  Use the resolution of the merge
-  as the new patch content.
-\item[\hgxopt{mq}{qpush}{-n}] Use the named queue if merging while pushing.
-\end{itemize}
-
-The \hgxcmd{mq}{qpush} command reads, but does not modify, the
-\sfilename{series} file.  It appends one line to the \hgcmd{status}
-file for each patch that it pushes.
-
-\subsection{\hgxcmd{mq}{qrefresh}---update the topmost applied patch}
-
-The \hgxcmd{mq}{qrefresh} command updates the topmost applied patch.  It
-modifies the patch, removes the old changeset that represented the
-patch, and creates a new changeset to represent the modified patch.
-
-The \hgxcmd{mq}{qrefresh} command looks for the following modifications:
-\begin{itemize}
-\item Changes to the commit message, i.e.~the text before the first
-  diff header in the patch file, are reflected in the new changeset
-  that represents the patch.
-\item Modifications to tracked files in the working directory are
-  added to the patch.
-\item Changes to the files tracked using \hgcmd{add}, \hgcmd{copy},
-  \hgcmd{remove}, or \hgcmd{rename}.  Added files and copy and rename
-  destinations are added to the patch, while removed files and rename
-  sources are removed.
-\end{itemize}
-
-Even if \hgxcmd{mq}{qrefresh} detects no changes, it still recreates the
-changeset that represents the patch.  This causes the identity of the
-changeset to differ from the previous changeset that identified the
-patch.
-
-Options:
-\begin{itemize}
-\item[\hgxopt{mq}{qrefresh}{-e}] Modify the commit and patch description,
-  using the preferred text editor.
-\item[\hgxopt{mq}{qrefresh}{-m}] Modify the commit message and patch
-  description, using the given text.
-\item[\hgxopt{mq}{qrefresh}{-l}] Modify the commit message and patch
-  description, using text from the given file.
-\end{itemize}
-
-\subsection{\hgxcmd{mq}{qrename}---rename a patch}
-
-The \hgxcmd{mq}{qrename} command renames a patch, and changes the entry for
-the patch in the \sfilename{series} file.
-
-With a single argument, \hgxcmd{mq}{qrename} renames the topmost applied
-patch.  With two arguments, it renames its first argument to its
-second.
-
-\subsection{\hgxcmd{mq}{qrestore}---restore saved queue state}
-
-XXX No idea what this does.
-
-\subsection{\hgxcmd{mq}{qsave}---save current queue state}
-
-XXX Likewise.
-
-\subsection{\hgxcmd{mq}{qseries}---print the entire patch series}
-
-The \hgxcmd{mq}{qseries} command prints the entire patch series from the
-\sfilename{series} file.  It prints only patch names, not empty lines
-or comments.  It prints in order from first to be applied to last.
-
-\subsection{\hgxcmd{mq}{qtop}---print the name of the current patch}
-
-The \hgxcmd{mq}{qtop} prints the name of the topmost currently applied
-patch.
-
-\subsection{\hgxcmd{mq}{qunapplied}---print patches not yet applied}
-
-The \hgxcmd{mq}{qunapplied} command prints the names of patches from the
-\sfilename{series} file that are not yet applied.  It prints them in
-order from the next patch that will be pushed to the last.
-
-\subsection{\hgcmd{strip}---remove a revision and descendants}
-
-The \hgcmd{strip} command removes a revision, and all of its
-descendants, from the repository.  It undoes the effects of the
-removed revisions from the repository, and updates the working
-directory to the first parent of the removed revision.
-
-The \hgcmd{strip} command saves a backup of the removed changesets in
-a bundle, so that they can be reapplied if removed in error.
-
-Options:
-\begin{itemize}
-\item[\hgopt{strip}{-b}] Save unrelated changesets that are intermixed
-  with the stripped changesets in the backup bundle.
-\item[\hgopt{strip}{-f}] If a branch has multiple heads, remove all
-  heads. XXX This should be renamed, and use \texttt{-f} to strip revs
-  when there are pending changes.
-\item[\hgopt{strip}{-n}] Do not save a backup bundle.
-\end{itemize}
-
-\section{MQ file reference}
-
-\subsection{The \sfilename{series} file}
-
-The \sfilename{series} file contains a list of the names of all
-patches that MQ can apply.  It is represented as a list of names, with
-one name saved per line.  Leading and trailing white space in each
-line are ignored.
-
-Lines may contain comments.  A comment begins with the ``\texttt{\#}''
-character, and extends to the end of the line.  Empty lines, and lines
-that contain only comments, are ignored.
-
-You will often need to edit the \sfilename{series} file by hand, hence
-the support for comments and empty lines noted above.  For example,
-you can comment out a patch temporarily, and \hgxcmd{mq}{qpush} will skip
-over that patch when applying patches.  You can also change the order
-in which patches are applied by reordering their entries in the
-\sfilename{series} file.
-
-Placing the \sfilename{series} file under revision control is also
-supported; it is a good idea to place all of the patches that it
-refers to under revision control, as well.  If you create a patch
-directory using the \hgxopt{mq}{qinit}{-c} option to \hgxcmd{mq}{qinit}, this
-will be done for you automatically.
-
-\subsection{The \sfilename{status} file}
-
-The \sfilename{status} file contains the names and changeset hashes of
-all patches that MQ currently has applied.  Unlike the
-\sfilename{series} file, this file is not intended for editing.  You
-should not place this file under revision control, or modify it in any
-way.  It is used by MQ strictly for internal book-keeping.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/mq-stack.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.43"
-   sodipodi:docname="mq-stack.svg"
-   sodipodi:docbase="/home/bos/hg/hgbook/en">
-  <defs
-     id="defs4" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4142136"
-     inkscape:cx="299.33323"
-     inkscape:cy="815.646"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="1014"
-     inkscape:window-height="689"
-     inkscape:window-x="0"
-     inkscape:window-y="25" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect1307"
-       width="202.93683"
-       height="24.243662"
-       x="230.01944"
-       y="221.70146" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="237.89606"
-       y="237.13383"
-       id="text1309"><tspan
-         sodipodi:role="line"
-         id="tspan1311"
-         x="237.89606"
-         y="237.13383">prevent-compiler-reorder.patch</tspan></text>
-    <rect
-       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect1320"
-       width="202.93683"
-       height="24.243662"
-       x="230.01936"
-       y="251.34325" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="237.89598"
-       y="266.77563"
-       id="text1322"><tspan
-         sodipodi:role="line"
-         id="tspan1324"
-         x="237.89598"
-         y="266.77563">namespace-cleanup.patch</tspan></text>
-    <rect
-       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect2217"
-       width="202.93683"
-       height="24.243662"
-       x="230.01936"
-       y="280.98505" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="237.89598"
-       y="296.41742"
-       id="text2219"><tspan
-         sodipodi:role="line"
-         id="tspan2221"
-         x="237.89598"
-         y="296.41742">powerpc-port-fixes.patch</tspan></text>
-    <rect
-       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect3114"
-       width="202.93683"
-       height="24.243662"
-       x="230.01936"
-       y="310.6268" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="237.89598"
-       y="326.05917"
-       id="text3116"><tspan
-         sodipodi:role="line"
-         id="tspan3118"
-         x="237.89598"
-         y="326.05917">report-devinfo-correctly.patch</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="200.01021"
-       y="191.68094"
-       id="text3170"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan3172"
-         x="200.01021"
-         y="191.68094"
-         style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="255.26627"
-       y="248.79449"
-       id="text3190"
-       sodipodi:linespacing="125%"
-       transform="scale(0.786716,1.271107)"><tspan
-         sodipodi:role="line"
-         id="tspan3192"
-         x="255.26627"
-         y="248.79449"
-         style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="195.86807"
-       y="173.17117"
-       id="text4085"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan4087"
-         x="195.86807"
-         y="173.17117"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">present in series,</tspan><tspan
-         sodipodi:role="line"
-         x="195.86807"
-         y="188.17117"
-         id="tspan4089"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">but not applied</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="195.0712"
-       y="288.91745"
-       id="text4091"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan4093"
-         x="195.0712"
-         y="288.91745"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">patches applied,</tspan><tspan
-         sodipodi:role="line"
-         x="195.0712"
-         y="303.91745"
-         id="tspan4111"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">changesets present</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="195.0712"
-       y="229.28813"
-       id="text4095"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan4097"
-         x="195.0712"
-         y="229.28813"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">topmost</tspan><tspan
-         sodipodi:role="line"
-         x="195.0712"
-         y="244.28813"
-         id="tspan4109"
-         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">applied patch</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="450.4975"
-       y="238.29692"
-       id="text4137"><tspan
-         sodipodi:role="line"
-         id="tspan4139"
-         x="450.4975"
-         y="238.29692">201ad3209902</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="450.05804"
-       y="267.93872"
-       id="text4141"><tspan
-         sodipodi:role="line"
-         id="tspan4143"
-         x="450.05804"
-         y="267.93872">126b84e593ae</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="450.6557"
-       y="297.58051"
-       id="text4145"><tspan
-         sodipodi:role="line"
-         id="tspan4147"
-         x="450.6557"
-         y="297.58051">a655daf15409</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="450.71429"
-       y="327.22226"
-       id="text4149"><tspan
-         sodipodi:role="line"
-         id="tspan4151"
-         x="450.71429"
-         y="327.22226">e50d59aaea3a</tspan></text>
-    <rect
-       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect3106"
-       width="202.93683"
-       height="24.243662"
-       x="230.01936"
-       y="150.41792" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="237.89598"
-       y="165.8503"
-       id="text3108"><tspan
-         sodipodi:role="line"
-         id="tspan3110"
-         x="237.89598"
-         y="165.8503">forbid-illegal-params.patch</tspan></text>
-    <rect
-       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       id="rect2241"
-       width="202.93683"
-       height="24.243662"
-       x="230.16466"
-       y="180.05968" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="238.04128"
-       y="195.49205"
-       id="text2243"><tspan
-         sodipodi:role="line"
-         id="tspan2245"
-         x="238.04128"
-         y="195.49205">fix-memory-leak.patch</tspan></text>
-  </g>
-</svg>
--- a/en/mq.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1043 +0,0 @@
-\chapter{Managing change with Mercurial Queues}
-\label{chap:mq}
-
-\section{The patch management problem}
-\label{sec:mq:patch-mgmt}
-
-Here is a common scenario: you need to install a software package from
-source, but you find a bug that you must fix in the source before you
-can start using the package.  You make your changes, forget about the
-package for a while, and a few months later you need to upgrade to a
-newer version of the package.  If the newer version of the package
-still has the bug, you must extract your fix from the older source
-tree and apply it against the newer version.  This is a tedious task,
-and it's easy to make mistakes.
-
-This is a simple case of the ``patch management'' problem.  You have
-an ``upstream'' source tree that you can't change; you need to make
-some local changes on top of the upstream tree; and you'd like to be
-able to keep those changes separate, so that you can apply them to
-newer versions of the upstream source.
-
-The patch management problem arises in many situations.  Probably the
-most visible is that a user of an open source software project will
-contribute a bug fix or new feature to the project's maintainers in the
-form of a patch.
-
-Distributors of operating systems that include open source software
-often need to make changes to the packages they distribute so that
-they will build properly in their environments.
-
-When you have few changes to maintain, it is easy to manage a single
-patch using the standard \command{diff} and \command{patch} programs
-(see section~\ref{sec:mq:patch} for a discussion of these tools).
-Once the number of changes grows, it starts to make sense to maintain
-patches as discrete ``chunks of work,'' so that for example a single
-patch will contain only one bug fix (the patch might modify several
-files, but it's doing ``only one thing''), and you may have a number
-of such patches for different bugs you need fixed and local changes
-you require.  In this situation, if you submit a bug fix patch to the
-upstream maintainers of a package and they include your fix in a
-subsequent release, you can simply drop that single patch when you're
-updating to the newer release.
-
-Maintaining a single patch against an upstream tree is a little
-tedious and error-prone, but not difficult.  However, the complexity
-of the problem grows rapidly as the number of patches you have to
-maintain increases.  With more than a tiny number of patches in hand,
-understanding which ones you have applied and maintaining them moves
-from messy to overwhelming.
-
-Fortunately, Mercurial includes a powerful extension, Mercurial Queues
-(or simply ``MQ''), that massively simplifies the patch management
-problem.
-
-\section{The prehistory of Mercurial Queues}
-\label{sec:mq:history}
-
-During the late 1990s, several Linux kernel developers started to
-maintain ``patch series'' that modified the behaviour of the Linux
-kernel.  Some of these series were focused on stability, some on
-feature coverage, and others were more speculative.
-
-The sizes of these patch series grew rapidly.  In 2002, Andrew Morton
-published some shell scripts he had been using to automate the task of
-managing his patch queues.  Andrew was successfully using these
-scripts to manage hundreds (sometimes thousands) of patches on top of
-the Linux kernel.
-
-\subsection{A patchwork quilt}
-\label{sec:mq:quilt}
-
-In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the
-approach of Andrew's scripts and published a tool called ``patchwork
-quilt''~\cite{web:quilt}, or simply ``quilt''
-(see~\cite{gruenbacher:2005} for a paper describing it).  Because
-quilt substantially automated patch management, it rapidly gained a
-large following among open source software developers.
-
-Quilt manages a \emph{stack of patches} on top of a directory tree.
-To begin, you tell quilt to manage a directory tree, and tell it which
-files you want to manage; it stores away the names and contents of
-those files.  To fix a bug, you create a new patch (using a single
-command), edit the files you need to fix, then ``refresh'' the patch.
-
-The refresh step causes quilt to scan the directory tree; it updates
-the patch with all of the changes you have made.  You can create
-another patch on top of the first, which will track the changes
-required to modify the tree from ``tree with one patch applied'' to
-``tree with two patches applied''.
-
-You can \emph{change} which patches are applied to the tree.  If you
-``pop'' a patch, the changes made by that patch will vanish from the
-directory tree.  Quilt remembers which patches you have popped,
-though, so you can ``push'' a popped patch again, and the directory
-tree will be restored to contain the modifications in the patch.  Most
-importantly, you can run the ``refresh'' command at any time, and the
-topmost applied patch will be updated.  This means that you can, at
-any time, change both which patches are applied and what
-modifications those patches make.
-
-Quilt knows nothing about revision control tools, so it works equally
-well on top of an unpacked tarball or a Subversion working copy.
-
-\subsection{From patchwork quilt to Mercurial Queues}
-\label{sec:mq:quilt-mq}
-
-In mid-2005, Chris Mason took the features of quilt and wrote an
-extension that he called Mercurial Queues, which added quilt-like
-behaviour to Mercurial.
-
-The key difference between quilt and MQ is that quilt knows nothing
-about revision control systems, while MQ is \emph{integrated} into
-Mercurial.  Each patch that you push is represented as a Mercurial
-changeset.  Pop a patch, and the changeset goes away.
-
-Because quilt does not care about revision control tools, it is still
-a tremendously useful piece of software to know about for situations
-where you cannot use Mercurial and MQ.
-
-\section{The huge advantage of MQ}
-
-I cannot overstate the value that MQ offers through the unification of
-patches and revision control.
-
-A major reason that patches have persisted in the free software and
-open source world---in spite of the availability of increasingly
-capable revision control tools over the years---is the \emph{agility}
-they offer.  
-
-Traditional revision control tools make a permanent, irreversible
-record of everything that you do.  While this has great value, it's
-also somewhat stifling.  If you want to perform a wild-eyed
-experiment, you have to be careful in how you go about it, or you risk
-leaving unneeded---or worse, misleading or destabilising---traces of
-your missteps and errors in the permanent revision record.
-
-By contrast, MQ's marriage of distributed revision control with
-patches makes it much easier to isolate your work.  Your patches live
-on top of normal revision history, and you can make them disappear or
-reappear at will.  If you don't like a patch, you can drop it.  If a
-patch isn't quite as you want it to be, simply fix it---as many times
-as you need to, until you have refined it into the form you desire.
-
-As an example, the integration of patches with revision control makes
-understanding patches and debugging their effects---and their
-interplay with the code they're based on---\emph{enormously} easier.
-Since every applied patch has an associated changeset, you can use
-\hgcmdargs{log}{\emph{filename}} to see which changesets and patches
-affected a file.  You can use the \hgext{bisect} command to
-binary-search through all changesets and applied patches to see where
-a bug got introduced or fixed.  You can use the \hgcmd{annotate}
-command to see which changeset or patch modified a particular line of
-a source file.  And so on.
-
-\section{Understanding patches}
-\label{sec:mq:patch}
-
-Because MQ doesn't hide its patch-oriented nature, it is helpful to
-understand what patches are, and a little about the tools that work
-with them.
-
-The traditional Unix \command{diff} command compares two files, and
-prints a list of differences between them. The \command{patch} command
-understands these differences as \emph{modifications} to make to a
-file.  Take a look at figure~\ref{ex:mq:diff} for a simple example of
-these commands in action.
-
-\begin{figure}[ht]
-  \interaction{mq.dodiff.diff}
-  \caption{Simple uses of the \command{diff} and \command{patch} commands}
-  \label{ex:mq:diff}
-\end{figure}
-
-The type of file that \command{diff} generates (and \command{patch}
-takes as input) is called a ``patch'' or a ``diff''; there is no
-difference between a patch and a diff.  (We'll use the term ``patch'',
-since it's more commonly used.)
-
-A patch file can start with arbitrary text; the \command{patch}
-command ignores this text, but MQ uses it as the commit message when
-creating changesets.  To find the beginning of the patch content,
-\command{patch} searches for the first line that starts with the
-string ``\texttt{diff~-}''.
-
-MQ works with \emph{unified} diffs (\command{patch} can accept several
-other diff formats, but MQ doesn't).  A unified diff contains two
-kinds of header.  The \emph{file header} describes the file being
-modified; it contains the name of the file to modify.  When
-\command{patch} sees a new file header, it looks for a file with that
-name to start modifying.
-
-After the file header comes a series of \emph{hunks}.  Each hunk
-starts with a header; this identifies the range of line numbers within
-the file that the hunk should modify.  Following the header, a hunk
-starts and ends with a few (usually three) lines of text from the
-unmodified file; these are called the \emph{context} for the hunk.  If
-there's only a small amount of context between successive hunks,
-\command{diff} doesn't print a new hunk header; it just runs the hunks
-together, with a few lines of context between modifications.
-
-Each line of context begins with a space character.  Within the hunk,
-a line that begins with ``\texttt{-}'' means ``remove this line,''
-while a line that begins with ``\texttt{+}'' means ``insert this
-line.''  For example, a line that is modified is represented by one
-deletion and one insertion.
-
-We will return to some of the more subtle aspects of patches later (in
-section~\ref{sec:mq:adv-patch}), but you should have enough information
-now to use MQ.
-
-\section{Getting started with Mercurial Queues}
-\label{sec:mq:start}
-
-Because MQ is implemented as an extension, you must explicitly enable
-before you can use it.  (You don't need to download anything; MQ ships
-with the standard Mercurial distribution.)  To enable MQ, edit your
-\tildefile{.hgrc} file, and add the lines in figure~\ref{ex:mq:config}.
-
-\begin{figure}[ht]
-  \begin{codesample4}
-    [extensions]
-    hgext.mq =
-  \end{codesample4}
-  \label{ex:mq:config}
-  \caption{Contents to add to \tildefile{.hgrc} to enable the MQ extension}
-\end{figure}
-
-Once the extension is enabled, it will make a number of new commands
-available.  To verify that the extension is working, you can use
-\hgcmd{help} to see if the \hgxcmd{mq}{qinit} command is now available; see
-the example in figure~\ref{ex:mq:enabled}.
-
-\begin{figure}[ht]
-  \interaction{mq.qinit-help.help}
-  \caption{How to verify that MQ is enabled}
-  \label{ex:mq:enabled}
-\end{figure}
-
-You can use MQ with \emph{any} Mercurial repository, and its commands
-only operate within that repository.  To get started, simply prepare
-the repository using the \hgxcmd{mq}{qinit} command (see
-figure~\ref{ex:mq:qinit}).  This command creates an empty directory
-called \sdirname{.hg/patches}, where MQ will keep its metadata.  As
-with many Mercurial commands, the \hgxcmd{mq}{qinit} command prints nothing
-if it succeeds.
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qinit}
-  \caption{Preparing a repository for use with MQ}
-  \label{ex:mq:qinit}
-\end{figure}
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qnew}
-  \caption{Creating a new patch}
-  \label{ex:mq:qnew}
-\end{figure}
-
-\subsection{Creating a new patch}
-
-To begin work on a new patch, use the \hgxcmd{mq}{qnew} command.  This
-command takes one argument, the name of the patch to create.  MQ will
-use this as the name of an actual file in the \sdirname{.hg/patches}
-directory, as you can see in figure~\ref{ex:mq:qnew}.
-
-Also newly present in the \sdirname{.hg/patches} directory are two
-other files, \sfilename{series} and \sfilename{status}.  The
-\sfilename{series} file lists all of the patches that MQ knows about
-for this repository, with one patch per line.  Mercurial uses the
-\sfilename{status} file for internal book-keeping; it tracks all of the
-patches that MQ has \emph{applied} in this repository.
-
-\begin{note}
-  You may sometimes want to edit the \sfilename{series} file by hand;
-  for example, to change the sequence in which some patches are
-  applied.  However, manually editing the \sfilename{status} file is
-  almost always a bad idea, as it's easy to corrupt MQ's idea of what
-  is happening.
-\end{note}
-
-Once you have created your new patch, you can edit files in the
-working directory as you usually would.  All of the normal Mercurial
-commands, such as \hgcmd{diff} and \hgcmd{annotate}, work exactly as
-they did before.
-
-\subsection{Refreshing a patch}
-
-When you reach a point where you want to save your work, use the
-\hgxcmd{mq}{qrefresh} command (figure~\ref{ex:mq:qnew}) to update the patch
-you are working on.  This command folds the changes you have made in
-the working directory into your patch, and updates its corresponding
-changeset to contain those changes.
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qrefresh}
-  \caption{Refreshing a patch}
-  \label{ex:mq:qrefresh}
-\end{figure}
-
-You can run \hgxcmd{mq}{qrefresh} as often as you like, so it's a good way
-to ``checkpoint'' your work.  Refresh your patch at an opportune
-time; try an experiment; and if the experiment doesn't work out,
-\hgcmd{revert} your modifications back to the last time you refreshed.
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qrefresh2}
-  \caption{Refresh a patch many times to accumulate changes}
-  \label{ex:mq:qrefresh2}
-\end{figure}
-
-\subsection{Stacking and tracking patches}
-
-Once you have finished working on a patch, or need to work on another,
-you can use the \hgxcmd{mq}{qnew} command again to create a new patch.
-Mercurial will apply this patch on top of your existing patch.  See
-figure~\ref{ex:mq:qnew2} for an example.  Notice that the patch
-contains the changes in our prior patch as part of its context (you
-can see this more clearly in the output of \hgcmd{annotate}).
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qnew2}
-  \caption{Stacking a second patch on top of the first}
-  \label{ex:mq:qnew2}
-\end{figure}
-
-So far, with the exception of \hgxcmd{mq}{qnew} and \hgxcmd{mq}{qrefresh}, we've
-been careful to only use regular Mercurial commands.  However, MQ
-provides many commands that are easier to use when you are thinking
-about patches, as illustrated in figure~\ref{ex:mq:qseries}:
-
-\begin{itemize}
-\item The \hgxcmd{mq}{qseries} command lists every patch that MQ knows
-  about in this repository, from oldest to newest (most recently
-  \emph{created}).
-\item The \hgxcmd{mq}{qapplied} command lists every patch that MQ has
-  \emph{applied} in this repository, again from oldest to newest (most
-  recently applied).
-\end{itemize}
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qseries}
-  \caption{Understanding the patch stack with \hgxcmd{mq}{qseries} and
-    \hgxcmd{mq}{qapplied}}
-  \label{ex:mq:qseries}
-\end{figure}
-
-\subsection{Manipulating the patch stack}
-
-The previous discussion implied that there must be a difference
-between ``known'' and ``applied'' patches, and there is.  MQ can
-manage a patch without it being applied in the repository.
-
-An \emph{applied} patch has a corresponding changeset in the
-repository, and the effects of the patch and changeset are visible in
-the working directory.  You can undo the application of a patch using
-the \hgxcmd{mq}{qpop} command.  MQ still \emph{knows about}, or manages, a
-popped patch, but the patch no longer has a corresponding changeset in
-the repository, and the working directory does not contain the changes
-made by the patch.  Figure~\ref{fig:mq:stack} illustrates the
-difference between applied and tracked patches.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{mq-stack}
-  \caption{Applied and unapplied patches in the MQ patch stack}
-  \label{fig:mq:stack}
-\end{figure}
-
-You can reapply an unapplied, or popped, patch using the \hgxcmd{mq}{qpush}
-command.  This creates a new changeset to correspond to the patch, and
-the patch's changes once again become present in the working
-directory.  See figure~\ref{ex:mq:qpop} for examples of \hgxcmd{mq}{qpop}
-and \hgxcmd{mq}{qpush} in action.  Notice that once we have popped a patch
-or two patches, the output of \hgxcmd{mq}{qseries} remains the same, while
-that of \hgxcmd{mq}{qapplied} has changed.
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qpop}
-  \caption{Modifying the stack of applied patches}
-  \label{ex:mq:qpop}
-\end{figure}
-
-\subsection{Pushing and popping many patches}
-
-While \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} each operate on a single patch at
-a time by default, you can push and pop many patches in one go.  The
-\hgxopt{mq}{qpush}{-a} option to \hgxcmd{mq}{qpush} causes it to push all
-unapplied patches, while the \hgxopt{mq}{qpop}{-a} option to \hgxcmd{mq}{qpop}
-causes it to pop all applied patches.  (For some more ways to push and
-pop many patches, see section~\ref{sec:mq:perf} below.)
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.qpush-a}
-  \caption{Pushing all unapplied patches}
-  \label{ex:mq:qpush-a}
-\end{figure}
-
-\subsection{Safety checks, and overriding them}
-
-Several MQ commands check the working directory before they do
-anything, and fail if they find any modifications.  They do this to
-ensure that you won't lose any changes that you have made, but not yet
-incorporated into a patch.  Figure~\ref{ex:mq:add} illustrates this;
-the \hgxcmd{mq}{qnew} command will not create a new patch if there are
-outstanding changes, caused in this case by the \hgcmd{add} of
-\filename{file3}.
-
-\begin{figure}[ht]
-  \interaction{mq.tutorial.add}
-  \caption{Forcibly creating a patch}
-  \label{ex:mq:add}
-\end{figure}
-
-Commands that check the working directory all take an ``I know what
-I'm doing'' option, which is always named \option{-f}.  The exact
-meaning of \option{-f} depends on the command.  For example,
-\hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}} will incorporate any outstanding
-changes into the new patch it creates, but
-\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} will revert modifications to any
-files affected by the patch that it is popping.  Be sure to read the
-documentation for a command's \option{-f} option before you use it!
-
-\subsection{Working on several patches at once}
-
-The \hgxcmd{mq}{qrefresh} command always refreshes the \emph{topmost}
-applied patch.  This means that you can suspend work on one patch (by
-refreshing it), pop or push to make a different patch the top, and
-work on \emph{that} patch for a while.
-
-Here's an example that illustrates how you can use this ability.
-Let's say you're developing a new feature as two patches.  The first
-is a change to the core of your software, and the second---layered on
-top of the first---changes the user interface to use the code you just
-added to the core.  If you notice a bug in the core while you're
-working on the UI patch, it's easy to fix the core.  Simply
-\hgxcmd{mq}{qrefresh} the UI patch to save your in-progress changes, and
-\hgxcmd{mq}{qpop} down to the core patch.  Fix the core bug,
-\hgxcmd{mq}{qrefresh} the core patch, and \hgxcmd{mq}{qpush} back to the UI
-patch to continue where you left off.
-
-\section{More about patches}
-\label{sec:mq:adv-patch}
-
-MQ uses the GNU \command{patch} command to apply patches, so it's
-helpful to know a few more detailed aspects of how \command{patch}
-works, and about patches themselves.
-
-\subsection{The strip count}
-
-If you look at the file headers in a patch, you will notice that the
-pathnames usually have an extra component on the front that isn't
-present in the actual path name.  This is a holdover from the way that
-people used to generate patches (people still do this, but it's
-somewhat rare with modern revision control tools).  
-
-Alice would unpack a tarball, edit her files, then decide that she
-wanted to create a patch.  So she'd rename her working directory,
-unpack the tarball again (hence the need for the rename), and use the
-\cmdopt{diff}{-r} and \cmdopt{diff}{-N} options to \command{diff} to
-recursively generate a patch between the unmodified directory and the
-modified one.  The result would be that the name of the unmodified
-directory would be at the front of the left-hand path in every file
-header, and the name of the modified directory would be at the front
-of the right-hand path.
-
-Since someone receiving a patch from the Alices of the net would be
-unlikely to have unmodified and modified directories with exactly the
-same names, the \command{patch} command has a \cmdopt{patch}{-p}
-option that indicates the number of leading path name components to
-strip when trying to apply a patch.  This number is called the
-\emph{strip count}.
-
-An option of ``\texttt{-p1}'' means ``use a strip count of one''.  If
-\command{patch} sees a file name \filename{foo/bar/baz} in a file
-header, it will strip \filename{foo} and try to patch a file named
-\filename{bar/baz}.  (Strictly speaking, the strip count refers to the
-number of \emph{path separators} (and the components that go with them
-) to strip.  A strip count of one will turn \filename{foo/bar} into
-\filename{bar}, but \filename{/foo/bar} (notice the extra leading
-slash) into \filename{foo/bar}.)
-
-The ``standard'' strip count for patches is one; almost all patches
-contain one leading path name component that needs to be stripped.
-Mercurial's \hgcmd{diff} command generates path names in this form,
-and the \hgcmd{import} command and MQ expect patches to have a strip
-count of one.
-
-If you receive a patch from someone that you want to add to your patch
-queue, and the patch needs a strip count other than one, you cannot
-just \hgxcmd{mq}{qimport} the patch, because \hgxcmd{mq}{qimport} does not yet
-have a \texttt{-p} option (see~\bug{311}).  Your best bet is to
-\hgxcmd{mq}{qnew} a patch of your own, then use \cmdargs{patch}{-p\emph{N}}
-to apply their patch, followed by \hgcmd{addremove} to pick up any
-files added or removed by the patch, followed by \hgxcmd{mq}{qrefresh}.
-This complexity may become unnecessary; see~\bug{311} for details.
-\subsection{Strategies for applying a patch}
-
-When \command{patch} applies a hunk, it tries a handful of
-successively less accurate strategies to try to make the hunk apply.
-This falling-back technique often makes it possible to take a patch
-that was generated against an old version of a file, and apply it
-against a newer version of that file.
-
-First, \command{patch} tries an exact match, where the line numbers,
-the context, and the text to be modified must apply exactly.  If it
-cannot make an exact match, it tries to find an exact match for the
-context, without honouring the line numbering information.  If this
-succeeds, it prints a line of output saying that the hunk was applied,
-but at some \emph{offset} from the original line number.
-
-If a context-only match fails, \command{patch} removes the first and
-last lines of the context, and tries a \emph{reduced} context-only
-match.  If the hunk with reduced context succeeds, it prints a message
-saying that it applied the hunk with a \emph{fuzz factor} (the number
-after the fuzz factor indicates how many lines of context
-\command{patch} had to trim before the patch applied).
-
-When neither of these techniques works, \command{patch} prints a
-message saying that the hunk in question was rejected.  It saves
-rejected hunks (also simply called ``rejects'') to a file with the
-same name, and an added \sfilename{.rej} extension.  It also saves an
-unmodified copy of the file with a \sfilename{.orig} extension; the
-copy of the file without any extensions will contain any changes made
-by hunks that \emph{did} apply cleanly.  If you have a patch that
-modifies \filename{foo} with six hunks, and one of them fails to
-apply, you will have: an unmodified \filename{foo.orig}, a
-\filename{foo.rej} containing one hunk, and \filename{foo}, containing
-the changes made by the five successful five hunks.
-
-\subsection{Some quirks of patch representation}
-
-There are a few useful things to know about how \command{patch} works
-with files.
-\begin{itemize}
-\item This should already be obvious, but \command{patch} cannot
-  handle binary files.
-\item Neither does it care about the executable bit; it creates new
-  files as readable, but not executable.
-\item \command{patch} treats the removal of a file as a diff between
-  the file to be removed and the empty file.  So your idea of ``I
-  deleted this file'' looks like ``every line of this file was
-  deleted'' in a patch.
-\item It treats the addition of a file as a diff between the empty
-  file and the file to be added.  So in a patch, your idea of ``I
-  added this file'' looks like ``every line of this file was added''.
-\item It treats a renamed file as the removal of the old name, and the
-  addition of the new name.  This means that renamed files have a big
-  footprint in patches.  (Note also that Mercurial does not currently
-  try to infer when files have been renamed or copied in a patch.)
-\item \command{patch} cannot represent empty files, so you cannot use
-  a patch to represent the notion ``I added this empty file to the
-  tree''.
-\end{itemize}
-\subsection{Beware the fuzz}
-
-While applying a hunk at an offset, or with a fuzz factor, will often
-be completely successful, these inexact techniques naturally leave
-open the possibility of corrupting the patched file.  The most common
-cases typically involve applying a patch twice, or at an incorrect
-location in the file.  If \command{patch} or \hgxcmd{mq}{qpush} ever
-mentions an offset or fuzz factor, you should make sure that the
-modified files are correct afterwards.  
-
-It's often a good idea to refresh a patch that has applied with an
-offset or fuzz factor; refreshing the patch generates new context
-information that will make it apply cleanly.  I say ``often,'' not
-``always,'' because sometimes refreshing a patch will make it fail to
-apply against a different revision of the underlying files.  In some
-cases, such as when you're maintaining a patch that must sit on top of
-multiple versions of a source tree, it's acceptable to have a patch
-apply with some fuzz, provided you've verified the results of the
-patching process in such cases.
-
-\subsection{Handling rejection}
-
-If \hgxcmd{mq}{qpush} fails to apply a patch, it will print an error
-message and exit.  If it has left \sfilename{.rej} files behind, it is
-usually best to fix up the rejected hunks before you push more patches
-or do any further work.
-
-If your patch \emph{used to} apply cleanly, and no longer does because
-you've changed the underlying code that your patches are based on,
-Mercurial Queues can help; see section~\ref{sec:mq:merge} for details.
-
-Unfortunately, there aren't any great techniques for dealing with
-rejected hunks.  Most often, you'll need to view the \sfilename{.rej}
-file and edit the target file, applying the rejected hunks by hand.
-
-If you're feeling adventurous, Neil Brown, a Linux kernel hacker,
-wrote a tool called \command{wiggle}~\cite{web:wiggle}, which is more
-vigorous than \command{patch} in its attempts to make a patch apply.
-
-Another Linux kernel hacker, Chris Mason (the author of Mercurial
-Queues), wrote a similar tool called
-\command{mpatch}~\cite{web:mpatch}, which takes a simple approach to
-automating the application of hunks rejected by \command{patch}.  The
-\command{mpatch} command can help with four common reasons that a hunk
-may be rejected:
-
-\begin{itemize}
-\item The context in the middle of a hunk has changed.
-\item A hunk is missing some context at the beginning or end.
-\item A large hunk might apply better---either entirely or in
-  part---if it was broken up into smaller hunks.
-\item A hunk removes lines with slightly different content than those
-  currently present in the file.
-\end{itemize}
-
-If you use \command{wiggle} or \command{mpatch}, you should be doubly
-careful to check your results when you're done.  In fact,
-\command{mpatch} enforces this method of double-checking the tool's
-output, by automatically dropping you into a merge program when it has
-done its job, so that you can verify its work and finish off any
-remaining merges.
-
-\section{Getting the best performance out of MQ}
-\label{sec:mq:perf}
-
-MQ is very efficient at handling a large number of patches.  I ran
-some performance experiments in mid-2006 for a talk that I gave at the
-2006 EuroPython conference~\cite{web:europython}.  I used as my data
-set the Linux 2.6.17-mm1 patch series, which consists of 1,738
-patches.  I applied these on top of a Linux kernel repository
-containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux
-2.6.17.
-
-On my old, slow laptop, I was able to
-\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} all 1,738 patches in 3.5 minutes,
-and \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} them all in 30 seconds.  (On a
-newer laptop, the time to push all patches dropped to two minutes.)  I
-could \hgxcmd{mq}{qrefresh} one of the biggest patches (which made 22,779
-lines of changes to 287 files) in 6.6 seconds.
-
-Clearly, MQ is well suited to working in large trees, but there are a
-few tricks you can use to get the best performance of it.
-
-First of all, try to ``batch'' operations together.  Every time you
-run \hgxcmd{mq}{qpush} or \hgxcmd{mq}{qpop}, these commands scan the working
-directory once to make sure you haven't made some changes and then
-forgotten to run \hgxcmd{mq}{qrefresh}.  On a small tree, the time that
-this scan takes is unnoticeable.  However, on a medium-sized tree
-(containing tens of thousands of files), it can take a second or more.
-
-The \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} commands allow you to push and pop
-multiple patches at a time.  You can identify the ``destination
-patch'' that you want to end up at.  When you \hgxcmd{mq}{qpush} with a
-destination specified, it will push patches until that patch is at the
-top of the applied stack.  When you \hgxcmd{mq}{qpop} to a destination, MQ
-will pop patches until the destination patch is at the top.
-
-You can identify a destination patch using either the name of the
-patch, or by number.  If you use numeric addressing, patches are
-counted from zero; this means that the first patch is zero, the second
-is one, and so on.
-
-\section{Updating your patches when the underlying code changes}
-\label{sec:mq:merge}
-
-It's common to have a stack of patches on top of an underlying
-repository that you don't modify directly.  If you're working on
-changes to third-party code, or on a feature that is taking longer to
-develop than the rate of change of the code beneath, you will often
-need to sync up with the underlying code, and fix up any hunks in your
-patches that no longer apply.  This is called \emph{rebasing} your
-patch series.
-
-The simplest way to do this is to \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}}
-your patches, then \hgcmd{pull} changes into the underlying
-repository, and finally \hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} your
-patches again.  MQ will stop pushing any time it runs across a patch
-that fails to apply during conflicts, allowing you to fix your
-conflicts, \hgxcmd{mq}{qrefresh} the affected patch, and continue pushing
-until you have fixed your entire stack.
-
-This approach is easy to use and works well if you don't expect
-changes to the underlying code to affect how well your patches apply.
-If your patch stack touches code that is modified frequently or
-invasively in the underlying repository, however, fixing up rejected
-hunks by hand quickly becomes tiresome.
-
-It's possible to partially automate the rebasing process.  If your
-patches apply cleanly against some revision of the underlying repo, MQ
-can use this information to help you to resolve conflicts between your
-patches and a different revision.
-
-The process is a little involved.
-\begin{enumerate}
-\item To begin, \hgcmdargs{qpush}{-a} all of your patches on top of
-  the revision where you know that they apply cleanly.
-\item Save a backup copy of your patch directory using
-  \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}.  This prints
-  the name of the directory that it has saved the patches in.  It will
-  save the patches to a directory called
-  \sdirname{.hg/patches.\emph{N}}, where \texttt{\emph{N}} is a small
-  integer.  It also commits a ``save changeset'' on top of your
-  applied patches; this is for internal book-keeping, and records the
-  states of the \sfilename{series} and \sfilename{status} files.
-\item Use \hgcmd{pull} to bring new changes into the underlying
-  repository.  (Don't run \hgcmdargs{pull}{-u}; see below for why.)
-\item Update to the new tip revision, using
-  \hgcmdargs{update}{\hgopt{update}{-C}} to override the patches you
-  have pushed.
-\item Merge all patches using \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}
-    \hgxopt{mq}{qpush}{-a}}.  The \hgxopt{mq}{qpush}{-m} option to \hgxcmd{mq}{qpush}
-  tells MQ to perform a three-way merge if the patch fails to apply.
-\end{enumerate}
-
-During the \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, each patch in the
-\sfilename{series} file is applied normally.  If a patch applies with
-fuzz or rejects, MQ looks at the queue you \hgxcmd{mq}{qsave}d, and
-performs a three-way merge with the corresponding changeset.  This
-merge uses Mercurial's normal merge machinery, so it may pop up a GUI
-merge tool to help you to resolve problems.
-
-When you finish resolving the effects of a patch, MQ refreshes your
-patch based on the result of the merge.
-
-At the end of this process, your repository will have one extra head
-from the old patch queue, and a copy of the old patch queue will be in
-\sdirname{.hg/patches.\emph{N}}. You can remove the extra head using
-\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}}
-or \hgcmd{strip}.  You can delete \sdirname{.hg/patches.\emph{N}} once
-you are sure that you no longer need it as a backup.
-
-\section{Identifying patches}
-
-MQ commands that work with patches let you refer to a patch either by
-using its name or by a number.  By name is obvious enough; pass the
-name \filename{foo.patch} to \hgxcmd{mq}{qpush}, for example, and it will
-push patches until \filename{foo.patch} is applied.  
-
-As a shortcut, you can refer to a patch using both a name and a
-numeric offset; \texttt{foo.patch-2} means ``two patches before
-\texttt{foo.patch}'', while \texttt{bar.patch+4} means ``four patches
-after \texttt{bar.patch}''.
-
-Referring to a patch by index isn't much different.  The first patch
-printed in the output of \hgxcmd{mq}{qseries} is patch zero (yes, it's one
-of those start-at-zero counting systems); the second is patch one; and
-so on
-
-MQ also makes it easy to work with patches when you are using normal
-Mercurial commands.  Every command that accepts a changeset ID will
-also accept the name of an applied patch.  MQ augments the tags
-normally in the repository with an eponymous one for each applied
-patch.  In addition, the special tags \index{tags!special tag
-  names!\texttt{qbase}}\texttt{qbase} and \index{tags!special tag
-  names!\texttt{qtip}}\texttt{qtip} identify the ``bottom-most'' and
-topmost applied patches, respectively.
-
-These additions to Mercurial's normal tagging capabilities make
-dealing with patches even more of a breeze.
-\begin{itemize}
-\item Want to patchbomb a mailing list with your latest series of
-  changes?
-  \begin{codesample4}
-    hg email qbase:qtip
-  \end{codesample4}
-  (Don't know what ``patchbombing'' is?  See
-  section~\ref{sec:hgext:patchbomb}.)
-\item Need to see all of the patches since \texttt{foo.patch} that
-  have touched files in a subdirectory of your tree?
-  \begin{codesample4}
-    hg log -r foo.patch:qtip \emph{subdir}
-  \end{codesample4}
-\end{itemize}
-
-Because MQ makes the names of patches available to the rest of
-Mercurial through its normal internal tag machinery, you don't need to
-type in the entire name of a patch when you want to identify it by
-name.
-
-\begin{figure}[ht]
-  \interaction{mq.id.output}
-  \caption{Using MQ's tag features to work with patches}
-  \label{ex:mq:id}
-\end{figure}
-
-Another nice consequence of representing patch names as tags is that
-when you run the \hgcmd{log} command, it will display a patch's name
-as a tag, simply as part of its normal output.  This makes it easy to
-visually distinguish applied patches from underlying ``normal''
-revisions.  Figure~\ref{ex:mq:id} shows a few normal Mercurial
-commands in use with applied patches.
-
-\section{Useful things to know about}
-
-There are a number of aspects of MQ usage that don't fit tidily into
-sections of their own, but that are good to know.  Here they are, in
-one place.
-
-\begin{itemize}
-\item Normally, when you \hgxcmd{mq}{qpop} a patch and \hgxcmd{mq}{qpush} it
-  again, the changeset that represents the patch after the pop/push
-  will have a \emph{different identity} than the changeset that
-  represented the hash beforehand.  See
-  section~\ref{sec:mqref:cmd:qpush} for information as to why this is.
-\item It's not a good idea to \hgcmd{merge} changes from another
-  branch with a patch changeset, at least if you want to maintain the
-  ``patchiness'' of that changeset and changesets below it on the
-  patch stack.  If you try to do this, it will appear to succeed, but
-  MQ will become confused.
-\end{itemize}
-
-\section{Managing patches in a repository}
-\label{sec:mq:repo}
-
-Because MQ's \sdirname{.hg/patches} directory resides outside a
-Mercurial repository's working directory, the ``underlying'' Mercurial
-repository knows nothing about the management or presence of patches.
-
-This presents the interesting possibility of managing the contents of
-the patch directory as a Mercurial repository in its own right.  This
-can be a useful way to work.  For example, you can work on a patch for
-a while, \hgxcmd{mq}{qrefresh} it, then \hgcmd{commit} the current state of
-the patch.  This lets you ``roll back'' to that version of the patch
-later on.
-
-You can then share different versions of the same patch stack among
-multiple underlying repositories.  I use this when I am developing a
-Linux kernel feature.  I have a pristine copy of my kernel sources for
-each of several CPU architectures, and a cloned repository under each
-that contains the patches I am working on.  When I want to test a
-change on a different architecture, I push my current patches to the
-patch repository associated with that kernel tree, pop and push all of
-my patches, and build and test that kernel.
-
-Managing patches in a repository makes it possible for multiple
-developers to work on the same patch series without colliding with
-each other, all on top of an underlying source base that they may or
-may not control.
-
-\subsection{MQ support for patch repositories}
-
-MQ helps you to work with the \sdirname{.hg/patches} directory as a
-repository; when you prepare a repository for working with patches
-using \hgxcmd{mq}{qinit}, you can pass the \hgxopt{mq}{qinit}{-c} option to
-create the \sdirname{.hg/patches} directory as a Mercurial repository.
-
-\begin{note}
-  If you forget to use the \hgxopt{mq}{qinit}{-c} option, you can simply go
-  into the \sdirname{.hg/patches} directory at any time and run
-  \hgcmd{init}.  Don't forget to add an entry for the
-  \sfilename{status} file to the \sfilename{.hgignore} file, though
-
-  (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} does this for you
-  automatically); you \emph{really} don't want to manage the
-  \sfilename{status} file.
-\end{note}
-
-As a convenience, if MQ notices that the \dirname{.hg/patches}
-directory is a repository, it will automatically \hgcmd{add} every
-patch that you create and import.
-
-MQ provides a shortcut command, \hgxcmd{mq}{qcommit}, that runs
-\hgcmd{commit} in the \sdirname{.hg/patches} directory.  This saves
-some bothersome typing.
-
-Finally, as a convenience to manage the patch directory, you can
-define the alias \command{mq} on Unix systems. For example, on Linux
-systems using the \command{bash} shell, you can include the following
-snippet in your \tildefile{.bashrc}.
-
-\begin{codesample2}
-  alias mq=`hg -R \$(hg root)/.hg/patches'
-\end{codesample2}
-
-You can then issue commands of the form \cmdargs{mq}{pull} from
-the main repository.
-
-\subsection{A few things to watch out for}
-
-MQ's support for working with a repository full of patches is limited
-in a few small respects.
-
-MQ cannot automatically detect changes that you make to the patch
-directory.  If you \hgcmd{pull}, manually edit, or \hgcmd{update}
-changes to patches or the \sfilename{series} file, you will have to
-\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} and then
-\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} in the underlying repository to
-see those changes show up there.  If you forget to do this, you can
-confuse MQ's idea of which patches are applied.
-
-\section{Third party tools for working with patches}
-\label{sec:mq:tools}
-
-Once you've been working with patches for a while, you'll find
-yourself hungry for tools that will help you to understand and
-manipulate the patches you're dealing with.
-
-The \command{diffstat} command~\cite{web:diffstat} generates a
-histogram of the modifications made to each file in a patch.  It
-provides a good way to ``get a sense of'' a patch---which files it
-affects, and how much change it introduces to each file and as a
-whole.  (I find that it's a good idea to use \command{diffstat}'s
-\cmdopt{diffstat}{-p} option as a matter of course, as otherwise it
-will try to do clever things with prefixes of file names that
-inevitably confuse at least me.)
-
-\begin{figure}[ht]
-  \interaction{mq.tools.tools}
-  \caption{The \command{diffstat}, \command{filterdiff}, and \command{lsdiff} commands}
-  \label{ex:mq:tools}
-\end{figure}
-
-The \package{patchutils} package~\cite{web:patchutils} is invaluable.
-It provides a set of small utilities that follow the ``Unix
-philosophy;'' each does one useful thing with a patch.  The
-\package{patchutils} command I use most is \command{filterdiff}, which
-extracts subsets from a patch file.  For example, given a patch that
-modifies hundreds of files across dozens of directories, a single
-invocation of \command{filterdiff} can generate a smaller patch that
-only touches files whose names match a particular glob pattern.  See
-section~\ref{mq-collab:tips:interdiff} for another example.
-
-\section{Good ways to work with patches}
-
-Whether you are working on a patch series to submit to a free software
-or open source project, or a series that you intend to treat as a
-sequence of regular changesets when you're done, you can use some
-simple techniques to keep your work well organised.
-
-Give your patches descriptive names.  A good name for a patch might be
-\filename{rework-device-alloc.patch}, because it will immediately give
-you a hint what the purpose of the patch is.  Long names shouldn't be
-a problem; you won't be typing the names often, but you \emph{will} be
-running commands like \hgxcmd{mq}{qapplied} and \hgxcmd{mq}{qtop} over and over.
-Good naming becomes especially important when you have a number of
-patches to work with, or if you are juggling a number of different
-tasks and your patches only get a fraction of your attention.
-
-Be aware of what patch you're working on.  Use the \hgxcmd{mq}{qtop}
-command and skim over the text of your patches frequently---for
-example, using \hgcmdargs{tip}{\hgopt{tip}{-p}})---to be sure of where
-you stand.  I have several times worked on and \hgxcmd{mq}{qrefresh}ed a
-patch other than the one I intended, and it's often tricky to migrate
-changes into the right patch after making them in the wrong one.
-
-For this reason, it is very much worth investing a little time to
-learn how to use some of the third-party tools I described in
-section~\ref{sec:mq:tools}, particularly \command{diffstat} and
-\command{filterdiff}.  The former will give you a quick idea of what
-changes your patch is making, while the latter makes it easy to splice
-hunks selectively out of one patch and into another.
-
-\section{MQ cookbook}
-
-\subsection{Manage ``trivial'' patches}
-
-Because the overhead of dropping files into a new Mercurial repository
-is so low, it makes a lot of sense to manage patches this way even if
-you simply want to make a few changes to a source tarball that you
-downloaded.
-
-Begin by downloading and unpacking the source tarball,
-and turning it into a Mercurial repository.
-\interaction{mq.tarball.download}
-
-Continue by creating a patch stack and making your changes.
-\interaction{mq.tarball.qinit}
-
-Let's say a few weeks or months pass, and your package author releases
-a new version.  First, bring their changes into the repository.
-\interaction{mq.tarball.newsource}
-The pipeline starting with \hgcmd{locate} above deletes all files in
-the working directory, so that \hgcmd{commit}'s
-\hgopt{commit}{--addremove} option can actually tell which files have
-really been removed in the newer version of the source.
-
-Finally, you can apply your patches on top of the new tree.
-\interaction{mq.tarball.repush}
-
-\subsection{Combining entire patches}
-\label{sec:mq:combine}
-
-MQ provides a command, \hgxcmd{mq}{qfold} that lets you combine entire
-patches.  This ``folds'' the patches you name, in the order you name
-them, into the topmost applied patch, and concatenates their
-descriptions onto the end of its description.  The patches that you
-fold must be unapplied before you fold them.
-
-The order in which you fold patches matters.  If your topmost applied
-patch is \texttt{foo}, and you \hgxcmd{mq}{qfold} \texttt{bar} and
-\texttt{quux} into it, you will end up with a patch that has the same
-effect as if you applied first \texttt{foo}, then \texttt{bar},
-followed by \texttt{quux}.
-
-\subsection{Merging part of one patch into another}
-
-Merging \emph{part} of one patch into another is more difficult than
-combining entire patches.
-
-If you want to move changes to entire files, you can use
-\command{filterdiff}'s \cmdopt{filterdiff}{-i} and
-\cmdopt{filterdiff}{-x} options to choose the modifications to snip
-out of one patch, concatenating its output onto the end of the patch
-you want to merge into.  You usually won't need to modify the patch
-you've merged the changes from.  Instead, MQ will report some rejected
-hunks when you \hgxcmd{mq}{qpush} it (from the hunks you moved into the
-other patch), and you can simply \hgxcmd{mq}{qrefresh} the patch to drop
-the duplicate hunks.
-
-If you have a patch that has multiple hunks modifying a file, and you
-only want to move a few of those hunks, the job becomes more messy,
-but you can still partly automate it.  Use \cmdargs{lsdiff}{-nvv} to
-print some metadata about the patch.
-\interaction{mq.tools.lsdiff}
-
-This command prints three different kinds of number:
-\begin{itemize}
-\item (in the first column) a \emph{file number} to identify each file
-  modified in the patch;
-\item (on the next line, indented) the line number within a modified
-  file where a hunk starts; and
-\item (on the same line) a \emph{hunk number} to identify that hunk.
-\end{itemize}
-
-You'll have to use some visual inspection, and reading of the patch,
-to identify the file and hunk numbers you'll want, but you can then
-pass them to to \command{filterdiff}'s \cmdopt{filterdiff}{--files}
-and \cmdopt{filterdiff}{--hunks} options, to select exactly the file
-and hunk you want to extract.
-
-Once you have this hunk, you can concatenate it onto the end of your
-destination patch and continue with the remainder of
-section~\ref{sec:mq:combine}.
-
-\section{Differences between quilt and MQ}
-
-If you are already familiar with quilt, MQ provides a similar command
-set.  There are a few differences in the way that it works.
-
-You will already have noticed that most quilt commands have MQ
-counterparts that simply begin with a ``\texttt{q}''.  The exceptions
-are quilt's \texttt{add} and \texttt{remove} commands, the
-counterparts for which are the normal Mercurial \hgcmd{add} and
-\hgcmd{remove} commands.  There is no MQ equivalent of the quilt
-\texttt{edit} command.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
Binary file en/note.png has changed
--- a/en/preface.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-\chapter*{Preface}
-\addcontentsline{toc}{chapter}{Preface}
-\label{chap:preface}
-
-Distributed revision control is a relatively new territory, and has
-thus far grown due to people's willingness to strike out into
-ill-charted territory.
-
-I am writing a book about distributed revision control because I
-believe that it is an important subject that deserves a field guide.
-I chose to write about Mercurial because it is the easiest tool to
-learn the terrain with, and yet it scales to the demands of real,
-challenging environments where many other revision control tools fail.
-
-\section{This book is a work in progress}
-
-I am releasing this book while I am still writing it, in the hope that
-it will prove useful to others.  I also hope that readers will
-contribute as they see fit.
-
-\section{About the examples in this book}
-
-This book takes an unusual approach to code samples.  Every example is
-``live''---each one is actually the result of a shell script that
-executes the Mercurial commands you see.  Every time an image of the
-book is built from its sources, all the example scripts are
-automatically run, and their current results compared against their
-expected results.
-
-The advantage of this approach is that the examples are always
-accurate; they describe \emph{exactly} the behaviour of the version of
-Mercurial that's mentioned at the front of the book.  If I update the
-version of Mercurial that I'm documenting, and the output of some
-command changes, the build fails.
-
-There is a small disadvantage to this approach, which is that the
-dates and times you'll see in examples tend to be ``squashed''
-together in a way that they wouldn't be if the same commands were
-being typed by a human.  Where a human can issue no more than one
-command every few seconds, with any resulting timestamps
-correspondingly spread out, my automated example scripts run many
-commands in one second.
-
-As an instance of this, several consecutive commits in an example can
-show up as having occurred during the same second.  You can see this
-occur in the \hgext{bisect} example in section~\ref{sec:undo:bisect},
-for instance.
-
-So when you're reading examples, don't place too much weight on the
-dates or times you see in the output of commands.  But \emph{do} be
-confident that the behaviour you're seeing is consistent and
-reproducible.
-
-\section{Colophon---this book is Free}
-
-This book is licensed under the Open Publication License, and is
-produced entirely using Free Software tools.  It is typeset with
-\LaTeX{}; illustrations are drawn and rendered with
-\href{http://www.inkscape.org/}{Inkscape}.
-
-The complete source code for this book is published as a Mercurial
-repository, at \url{http://hg.serpentine.com/mercurial/book}.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/revlog.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="revlog.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient3092">
-      <stop
-         style="stop-color:#44436f;stop-opacity:1;"
-         offset="0"
-         id="stop3094" />
-      <stop
-         style="stop-color:#abade5;stop-opacity:1;"
-         offset="1"
-         id="stop3096" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient3118"
-       gradientUnits="userSpaceOnUse"
-       x1="176.16635"
-       y1="405.21934"
-       x2="417.11935"
-       y2="405.21934" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient3120"
-       gradientUnits="userSpaceOnUse"
-       x1="176.16635"
-       y1="405.21934"
-       x2="417.11935"
-       y2="405.21934" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient3129"
-       gradientUnits="userSpaceOnUse"
-       x1="176.16635"
-       y1="405.21934"
-       x2="417.11935"
-       y2="405.21934"
-       gradientTransform="translate(-0.928574,-1.428574)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient3133"
-       gradientUnits="userSpaceOnUse"
-       x1="176.16635"
-       y1="405.21934"
-       x2="417.11935"
-       y2="405.21934"
-       gradientTransform="translate(-0.928574,-1.428574)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient3708"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5164"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5584"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5784"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5786"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5895"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3092"
-       id="linearGradient5958"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)"
-       x1="175.23776"
-       y1="509.98154"
-       x2="416.29077"
-       y2="297.49997" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.64"
-     inkscape:cx="566.02368"
-     inkscape:cy="688.16826"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="29"
-     inkscape:window-y="79"
-     inkscape:connector-spacing="11" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       y="168.74846"
-       x="211.58516"
-       height="89.506805"
-       width="101.60232"
-       id="rect3068"
-       style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g3215"
-       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)">
-      <rect
-         y="447.71451"
-         x="299.67859"
-         height="48.571426"
-         width="103.14286"
-         id="rect2899"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text2903"
-         y="464.8139"
-         x="308.89639"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="464.8139"
-           x="308.89639"
-           sodipodi:role="line"
-           id="tspan2905">Second parent</tspan></text>
-      <text
-         id="text2907"
-         y="485.50256"
-         x="308.20175"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="485.50256"
-           x="308.20175"
-           id="tspan2909"
-           sodipodi:role="line">32bf9a5f22c0</tspan></text>
-    </g>
-    <g
-       id="g3250"
-       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)">
-      <rect
-         y="311.28598"
-         x="188.6071"
-         height="48.571426"
-         width="103.14286"
-         id="rect2936"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text2940"
-         y="328.38538"
-         x="197.82495"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="328.38538"
-           x="197.82495"
-           sodipodi:role="line"
-           id="tspan2942">Revision hash</tspan></text>
-      <text
-         id="text2944"
-         y="349.07404"
-         x="197.13031"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="349.07404"
-           x="197.13031"
-           id="tspan2946"
-           sodipodi:role="line">34b8b7a15ea1</tspan></text>
-    </g>
-    <g
-       id="g3243"
-       transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)">
-      <rect
-         y="363.07654"
-         x="187.5"
-         height="75"
-         width="213.85715"
-         id="rect2950"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text2958"
-         y="400.86459"
-         x="196.02321"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="fill:black;fill-opacity:1;font-family:Courier"
-           y="400.86459"
-           x="196.02321"
-           id="tspan2960"
-           sodipodi:role="line">...</tspan></text>
-      <text
-         id="text2954"
-         y="380.17593"
-         x="196.71785"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="380.17593"
-           x="196.71785"
-           sodipodi:role="line"
-           id="tspan2956"
-           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
-    </g>
-    <g
-       id="g5529"
-       transform="translate(-6.710312,-8.165836e-6)">
-      <rect
-         style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect3509"
-         width="101.60232"
-         height="89.506805"
-         x="218.29547"
-         y="497.4801" />
-      <g
-         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
-         id="g3513">
-        <g
-           id="g3515">
-          <rect
-             y="447.72418"
-             x="188.6071"
-             height="48.571426"
-             width="103.14286"
-             id="rect3517"
-             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-          <text
-             id="text3519"
-             y="464.82358"
-             x="197.82495"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               y="464.82358"
-               x="197.82495"
-               sodipodi:role="line"
-               id="tspan3521">First parent</tspan></text>
-          <text
-             id="text3523"
-             y="485.51224"
-             x="197.13031"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               style="font-family:Courier"
-               y="485.51224"
-               x="197.13031"
-               id="tspan3525"
-               sodipodi:role="line">000000000000</tspan></text>
-        </g>
-        <g
-           id="g3527">
-          <rect
-             y="447.71451"
-             x="299.67859"
-             height="48.571426"
-             width="103.14286"
-             id="rect3529"
-             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-          <text
-             id="text3531"
-             y="464.8139"
-             x="308.89639"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               y="464.8139"
-               x="308.89639"
-               sodipodi:role="line"
-               id="tspan3533">Second parent</tspan></text>
-          <text
-             id="text3535"
-             y="485.50256"
-             x="308.20175"
-             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-             xml:space="preserve"><tspan
-               style="font-family:Courier"
-               y="485.50256"
-               x="308.20175"
-               id="tspan3537"
-               sodipodi:role="line">000000000000</tspan></text>
-        </g>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
-         id="g3539">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3541"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="311.28598" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="328.38538"
-           id="text3543"><tspan
-             id="tspan3545"
-             sodipodi:role="line"
-             x="197.82495"
-             y="328.38538">Revision hash</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="349.07404"
-           id="text3547"><tspan
-             sodipodi:role="line"
-             id="tspan3549"
-             x="197.13031"
-             y="349.07404"
-             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)"
-         id="g3551">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3553"
-           width="213.85715"
-           height="75"
-           x="187.5"
-           y="363.07654" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.02321"
-           y="400.86459"
-           id="text3555"><tspan
-             sodipodi:role="line"
-             id="tspan3557"
-             x="196.02321"
-             y="400.86459"
-             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.71785"
-           y="380.17593"
-           id="text3559"><tspan
-             style="fill:black;fill-opacity:1"
-             id="tspan3561"
-             sodipodi:role="line"
-             x="196.71785"
-             y="380.17593">Revision data (delta or snapshot)</tspan></text>
-      </g>
-    </g>
-    <g
-       id="g4868"
-       transform="translate(-1.676208,-2.342463e-5)">
-      <rect
-         style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect3567"
-         width="101.60232"
-         height="89.506805"
-         x="213.26137"
-         y="59.171272" />
-      <g
-         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
-         id="g3573">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3575"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="447.72418" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="464.82358"
-           id="text3577"><tspan
-             id="tspan3579"
-             sodipodi:role="line"
-             x="197.82495"
-             y="464.82358">First parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="485.51224"
-           id="text3581"><tspan
-             sodipodi:role="line"
-             id="tspan3583"
-             x="197.13031"
-             y="485.51224"
-             style="font-family:Courier">34b8b7a15ea1</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
-         id="g3585">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3587"
-           width="103.14286"
-           height="48.571426"
-           x="299.67859"
-           y="447.71451" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.89639"
-           y="464.8139"
-           id="text3589"><tspan
-             id="tspan3591"
-             sodipodi:role="line"
-             x="308.89639"
-             y="464.8139">Second parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.20175"
-           y="485.50256"
-           id="text3593"><tspan
-             sodipodi:role="line"
-             id="tspan3595"
-             x="308.20175"
-             y="485.50256"
-             style="font-family:Courier">000000000000</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)"
-         id="g3597">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3599"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="311.28598" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="328.38538"
-           id="text3601"><tspan
-             id="tspan3603"
-             sodipodi:role="line"
-             x="197.82495"
-             y="328.38538">Revision hash</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="349.07404"
-           id="text3605"><tspan
-             sodipodi:role="line"
-             id="tspan3607"
-             x="197.13031"
-             y="349.07404"
-             style="font-family:Courier">1b67dc96f27a</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)"
-         id="g3609">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3611"
-           width="213.85715"
-           height="75"
-           x="187.5"
-           y="363.07654" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.02321"
-           y="400.86459"
-           id="text3613"><tspan
-             sodipodi:role="line"
-             id="tspan3615"
-             x="196.02321"
-             y="400.86459"
-             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.71785"
-           y="380.17593"
-           id="text3617"><tspan
-             style="fill:black;fill-opacity:1"
-             id="tspan3619"
-             sodipodi:role="line"
-             x="196.71785"
-             y="380.17593">Revision data (delta or snapshot)</tspan></text>
-      </g>
-    </g>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)"
-       d="M 240.78255,143.08593 L 241.42595,171.75349"
-       id="path3801"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g3573"
-       inkscape:connection-end="#g3250" />
-    <g
-       id="g5677">
-      <rect
-         style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect3393"
-         width="101.60232"
-         height="89.506805"
-         x="150.76137"
-         y="278.32565" />
-      <g
-         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
-         id="g3399">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3401"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="447.72418" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="464.82358"
-           id="text3403"><tspan
-             id="tspan3405"
-             sodipodi:role="line"
-             x="197.82495"
-             y="464.82358">First parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="485.51224"
-           id="text3407"><tspan
-             sodipodi:role="line"
-             id="tspan3409"
-             x="197.13031"
-             y="485.51224"
-             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
-         id="g3411">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3413"
-           width="103.14286"
-           height="48.571426"
-           x="299.67859"
-           y="447.71451" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.89639"
-           y="464.8139"
-           id="text3415"><tspan
-             id="tspan3417"
-             sodipodi:role="line"
-             x="308.89639"
-             y="464.8139">Second parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.20175"
-           y="485.50256"
-           id="text3419"><tspan
-             sodipodi:role="line"
-             id="tspan3421"
-             x="308.20175"
-             y="485.50256"
-             style="font-family:Courier">000000000000</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
-         id="g3423">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3425"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="311.28598" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="328.38538"
-           id="text3427"><tspan
-             id="tspan3429"
-             sodipodi:role="line"
-             x="197.82495"
-             y="328.38538">Revision hash</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="349.07404"
-           id="text3431"><tspan
-             sodipodi:role="line"
-             id="tspan3433"
-             x="197.13031"
-             y="349.07404"
-             style="font-family:Courier">5b80c922ebdd</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)"
-         id="g3435">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3437"
-           width="213.85715"
-           height="75"
-           x="187.5"
-           y="363.07654" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.02321"
-           y="400.86459"
-           id="text3439"><tspan
-             sodipodi:role="line"
-             id="tspan3441"
-             x="196.02321"
-             y="400.86459"
-             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.71785"
-           y="380.17593"
-           id="text3443"><tspan
-             style="fill:black;fill-opacity:1"
-             id="tspan3445"
-             sodipodi:role="line"
-             x="196.71785"
-             y="380.17593">Revision data (delta or snapshot)</tspan></text>
-      </g>
-    </g>
-    <g
-       id="g5646"
-       transform="translate(-0.227432,0)">
-      <rect
-         style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect3451"
-         width="101.60232"
-         height="89.506805"
-         x="272.63638"
-         y="278.32565" />
-      <g
-         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
-         id="g3457">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3459"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="447.72418" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="464.82358"
-           id="text3461"><tspan
-             id="tspan3463"
-             sodipodi:role="line"
-             x="197.82495"
-             y="464.82358">First parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="485.51224"
-           id="text3465"><tspan
-             sodipodi:role="line"
-             id="tspan3467"
-             x="197.13031"
-             y="485.51224"
-             style="font-family:Courier">ecacb6b4c9fd</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
-         id="g3469">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3471"
-           width="103.14286"
-           height="48.571426"
-           x="299.67859"
-           y="447.71451" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.89639"
-           y="464.8139"
-           id="text3473"><tspan
-             id="tspan3475"
-             sodipodi:role="line"
-             x="308.89639"
-             y="464.8139">Second parent</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="308.20175"
-           y="485.50256"
-           id="text3477"><tspan
-             sodipodi:role="line"
-             id="tspan3479"
-             x="308.20175"
-             y="485.50256"
-             style="font-family:Courier">000000000000</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
-         id="g3481">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3483"
-           width="103.14286"
-           height="48.571426"
-           x="188.6071"
-           y="311.28598" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.82495"
-           y="328.38538"
-           id="text3485"><tspan
-             id="tspan3487"
-             sodipodi:role="line"
-             x="197.82495"
-             y="328.38538">Revision hash</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="197.13031"
-           y="349.07404"
-           id="text3489"><tspan
-             sodipodi:role="line"
-             id="tspan3491"
-             x="197.13031"
-             y="349.07404"
-             style="font-family:Courier">32bf9a5f22c0</tspan></text>
-      </g>
-      <g
-         transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)"
-         id="g3493">
-        <rect
-           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           id="rect3495"
-           width="213.85715"
-           height="75"
-           x="187.5"
-           y="363.07654" />
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.02321"
-           y="400.86459"
-           id="text3497"><tspan
-             sodipodi:role="line"
-             id="tspan3499"
-             x="196.02321"
-             y="400.86459"
-             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
-        <text
-           xml:space="preserve"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           x="196.71785"
-           y="380.17593"
-           id="text3501"><tspan
-             style="fill:black;fill-opacity:1"
-             id="tspan3503"
-             sodipodi:role="line"
-             x="196.71785"
-             y="380.17593">Revision data (delta or snapshot)</tspan></text>
-      </g>
-    </g>
-    <rect
-       y="387.90286"
-       x="272.40894"
-       height="89.506805"
-       width="101.60232"
-       id="rect5081"
-       style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g5087"
-       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
-      <rect
-         y="447.72418"
-         x="188.6071"
-         height="48.571426"
-         width="103.14286"
-         id="rect5089"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5091"
-         y="464.82358"
-         x="197.82495"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="464.82358"
-           x="197.82495"
-           sodipodi:role="line"
-           id="tspan5093">First parent</tspan></text>
-      <text
-         id="text5095"
-         y="485.51224"
-         x="197.13031"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="485.51224"
-           x="197.13031"
-           id="tspan5097"
-           sodipodi:role="line">ff9dc8bc2a8b</tspan></text>
-    </g>
-    <g
-       id="g5099"
-       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
-      <rect
-         y="447.71451"
-         x="299.67859"
-         height="48.571426"
-         width="103.14286"
-         id="rect5101"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5103"
-         y="464.8139"
-         x="308.89639"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="464.8139"
-           x="308.89639"
-           sodipodi:role="line"
-           id="tspan5105">Second parent</tspan></text>
-      <text
-         id="text5107"
-         y="485.50256"
-         x="308.20175"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="485.50256"
-           x="308.20175"
-           id="tspan5109"
-           sodipodi:role="line">000000000000</tspan></text>
-    </g>
-    <g
-       id="g5111"
-       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
-      <rect
-         y="311.28598"
-         x="188.6071"
-         height="48.571426"
-         width="103.14286"
-         id="rect5113"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5115"
-         y="328.38538"
-         x="197.82495"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="328.38538"
-           x="197.82495"
-           sodipodi:role="line"
-           id="tspan5117">Revision hash</tspan></text>
-      <text
-         id="text5119"
-         y="349.07404"
-         x="197.13031"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="349.07404"
-           x="197.13031"
-           id="tspan5121"
-           sodipodi:role="line">ecacb6b4c9fd</tspan></text>
-    </g>
-    <g
-       id="g5123"
-       transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)">
-      <rect
-         y="363.07654"
-         x="187.5"
-         height="75"
-         width="213.85715"
-         id="rect5125"
-         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5127"
-         y="400.86459"
-         x="196.02321"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="fill:black;fill-opacity:1;font-family:Courier"
-           y="400.86459"
-           x="196.02321"
-           id="tspan5129"
-           sodipodi:role="line">...</tspan></text>
-      <text
-         id="text5131"
-         y="380.17593"
-         x="196.71785"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="380.17593"
-           x="196.71785"
-           sodipodi:role="line"
-           id="tspan5133"
-           style="fill:black;fill-opacity:1">Revision data (delta or snapshot)</tspan></text>
-    </g>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 299.69935,362.24027 L 299.69931,393.49494"
-       id="path5203"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g3457"
-       inkscape:connection-end="#g5111" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 182.35357,362.22647 L 241.2842,503.07224"
-       id="path5271"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g3399"
-       inkscape:connection-end="#g3539" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 287.63109,471.81747 L 250.9438,503.07223"
-       id="path5285"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g5087"
-       inkscape:connection-end="#g3539" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 290.80419,250.07192 L 297.80065,283.90394"
-       id="path5077"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g3215"
-       inkscape:connection-end="#g3481" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 229.63373,250.07601 L 190.07484,283.90394"
-       id="path5075"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g3423" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="131.5625"
-       y="100.79968"
-       id="text5897"><tspan
-         sodipodi:role="line"
-         id="tspan5899"
-         x="131.5625"
-         y="100.79968"
-         style="text-align:end;text-anchor:end">Head revision</tspan><tspan
-         sodipodi:role="line"
-         x="131.5625"
-         y="115.79968"
-         id="tspan5901"
-         style="text-align:end;text-anchor:end">(no children)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="131.5625"
-       y="207.04968"
-       id="text5903"><tspan
-         sodipodi:role="line"
-         id="tspan5905"
-         x="131.5625"
-         y="207.04968"
-         style="text-align:end;text-anchor:end">Merge revision</tspan><tspan
-         sodipodi:role="line"
-         x="131.5625"
-         y="222.04968"
-         id="tspan5907"
-         style="text-align:end;text-anchor:end">(two parents)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="131.92578"
-       y="451.58093"
-       id="text5909"><tspan
-         sodipodi:role="line"
-         id="tspan5911"
-         x="131.92578"
-         y="451.58093"
-         style="text-align:end;text-anchor:end">Branches</tspan><tspan
-         sodipodi:role="line"
-         x="131.92578"
-         y="466.58093"
-         id="tspan5913"
-         style="text-align:end;text-anchor:end">(two revisions,</tspan><tspan
-         sodipodi:role="line"
-         x="131.92578"
-         y="481.58093"
-         id="tspan5915"
-         style="text-align:end;text-anchor:end">same parent)</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 111.71875,433.61218 L 154.7268,368.52294"
-       id="path5917"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 134.375,464.86218 L 277.86691,440.37816"
-       id="path5919"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g5123" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="131.5625"
-       y="536.73718"
-       id="text5927"><tspan
-         sodipodi:role="line"
-         id="tspan5929"
-         x="131.5625"
-         y="536.73718">First revision</tspan><tspan
-         sodipodi:role="line"
-         x="131.5625"
-         y="551.73718"
-         id="tspan5931">(both parents null)</tspan></text>
-    <rect
-       style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2830"
-       width="43.664806"
-       height="20.562374"
-       x="217.0432"
-       y="232.10075" />
-    <text
-       xml:space="preserve"
-       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="220.94551"
-       y="239.33966"
-       id="text2832"><tspan
-         id="tspan2836"
-         sodipodi:role="line"
-         x="220.94551"
-         y="239.33966">First parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="220.65144"
-       y="248.09805"
-       id="text2879"><tspan
-         sodipodi:role="line"
-         id="tspan2881"
-         x="220.65144"
-         y="248.09805"
-         style="font-family:Courier">5b80c922ebdd</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 139.84375,107.83093 L 210.15625,107.83093"
-       id="path5965"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 137.5,213.29968 L 210.49036,214.09055"
-       id="path5967"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 136.34375,544.54968 L 206.65625,544.54968"
-       id="path5969"
-       inkscape:connector-type="polyline"
-       inkscape:transform-center-y="-171.09375"
-       inkscape:transform-center-x="53.90625" />
-  </g>
-</svg>
--- a/en/snapshot.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2807"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="snapshots.svg">
-  <defs
-     id="defs2809" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="252.04111"
-     inkscape:cy="605.75448"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="721"
-     inkscape:window-x="0"
-     inkscape:window-y="25" />
-  <metadata
-     id="metadata2812">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect2817"
-       width="118.18347"
-       height="245.32632"
-       x="243.05112"
-       y="315.4133"
-       inkscape:transform-center-x="136.84403"
-       inkscape:transform-center-y="-66.529183" />
-    <rect
-       y="315.04153"
-       x="46.965065"
-       height="97.803009"
-       width="108.92702"
-       id="rect2815"
-       style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g3814">
-      <rect
-         y="348.94302"
-         x="59.285713"
-         height="30"
-         width="84.285713"
-         id="rect2819"
-         style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         ry="0" />
-      <text
-         id="text2821"
-         y="368.02701"
-         x="72.717636"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="368.02701"
-           x="72.717636"
-           id="tspan2823"
-           sodipodi:role="line">Index, rev 7</tspan></text>
-    </g>
-    <text
-       id="text3722"
-       y="301.29074"
-       x="46.187778"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       xml:space="preserve"><tspan
-         y="301.29074"
-         x="46.187778"
-         id="tspan3724"
-         sodipodi:role="line">Revlog index (.i file)</tspan></text>
-    <text
-       id="text3726"
-       y="301.29074"
-       x="241.90207"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       xml:space="preserve"><tspan
-         y="301.29074"
-         x="241.90207"
-         id="tspan3728"
-         sodipodi:role="line">Revlog data (.d file)</tspan></text>
-    <path
-       style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z "
-       id="path3839"
-       sodipodi:nodetypes="ccccc" />
-    <rect
-       style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3752"
-       width="92.720184"
-       height="67.005905"
-       x="255.42564"
-       y="368.64264" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="264.45859"
-       y="387.30099"
-       id="text3754"><tspan
-         sodipodi:role="line"
-         id="tspan3756"
-         x="264.45859"
-         y="387.30099">Snapshot, rev 4</tspan></text>
-    <rect
-       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3761"
-       width="93.49366"
-       height="29.922237"
-       x="255.03891"
-       y="442.04395" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="263.2662"
-       y="460.17206"
-       id="text3763"><tspan
-         sodipodi:role="line"
-         id="tspan3765"
-         x="263.2662"
-         y="460.17206">Delta, rev 4 to 5</tspan></text>
-    <rect
-       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3774"
-       width="93.49366"
-       height="29.922237"
-       x="255.03891"
-       y="477.97485" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="263.2662"
-       y="496.10297"
-       id="text3776"><tspan
-         sodipodi:role="line"
-         id="tspan3778"
-         x="263.2662"
-         y="496.10297">Delta, rev 5 to 6</tspan></text>
-    <rect
-       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3782"
-       width="93.49366"
-       height="29.922237"
-       x="255.03891"
-       y="513.90576" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="263.2662"
-       y="532.03387"
-       id="text3784"><tspan
-         sodipodi:role="line"
-         id="tspan3786"
-         x="263.2662"
-         y="532.03387">Delta, rev 6 to 7</tspan></text>
-    <rect
-       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect3889"
-       width="93.49366"
-       height="29.922237"
-       x="255.03891"
-       y="332.32489" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="263.2662"
-       y="350.453"
-       id="text3891"><tspan
-         sodipodi:role="line"
-         id="tspan3893"
-         x="263.2662"
-         y="350.453">Delta, rev 2 to 3</tspan></text>
-  </g>
-</svg>
--- a/en/srcinstall.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-\chapter{Installing Mercurial from source}
-\label{chap:srcinstall}
-
-\section{On a Unix-like system}
-\label{sec:srcinstall:unixlike}
-
-If you are using a Unix-like system that has a sufficiently recent
-version of Python (2.3~or newer) available, it is easy to install
-Mercurial from source.
-\begin{enumerate}
-\item Download a recent source tarball from
-  \url{http://www.selenic.com/mercurial/download}.
-\item Unpack the tarball:
-  \begin{codesample4}
-    gzip -dc mercurial-\emph{version}.tar.gz | tar xf -
-  \end{codesample4}
-\item Go into the source directory and run the installer script.  This
-  will build Mercurial and install it in your home directory.
-  \begin{codesample4}
-    cd mercurial-\emph{version}
-    python setup.py install --force --home=\$HOME
-  \end{codesample4}
-\end{enumerate}
-Once the install finishes, Mercurial will be in the \texttt{bin}
-subdirectory of your home directory.  Don't forget to make sure that
-this directory is present in your shell's search path.
-
-You will probably need to set the \envar{PYTHONPATH} environment
-variable so that the Mercurial executable can find the rest of the
-Mercurial packages.  For example, on my laptop, I have set it to
-\texttt{/home/bos/lib/python}.  The exact path that you will need to
-use depends on how Python was built for your system, but should be
-easy to figure out.  If you're uncertain, look through the output of
-the installer script above, and see where the contents of the
-\texttt{mercurial} directory were installed to.
-
-\section{On Windows}
-
-Building and installing Mercurial on Windows requires a variety of
-tools, a fair amount of technical knowledge, and considerable
-patience.  I very much \emph{do not recommend} this route if you are a
-``casual user''.  Unless you intend to hack on Mercurial, I strongly
-suggest that you use a binary package instead.
-
-If you are intent on building Mercurial from source on Windows, follow
-the ``hard way'' directions on the Mercurial wiki at
-\url{http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall},
-and expect the process to involve a lot of fiddly work.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/template.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,475 +0,0 @@
-\chapter{Customising the output of Mercurial}
-\label{chap:template}
-
-Mercurial provides a powerful mechanism to let you control how it
-displays information.  The mechanism is based on templates.  You can
-use templates to generate specific output for a single command, or to
-customise the entire appearance of the built-in web interface.
-
-\section{Using precanned output styles}
-\label{sec:style}
-
-Packaged with Mercurial are some output styles that you can use
-immediately.  A style is simply a precanned template that someone
-wrote and installed somewhere that Mercurial can find.
-
-Before we take a look at Mercurial's bundled styles, let's review its
-normal output.
-
-\interaction{template.simple.normal}
-
-This is somewhat informative, but it takes up a lot of space---five
-lines of output per changeset.  The \texttt{compact} style reduces
-this to three lines, presented in a sparse manner.
-
-\interaction{template.simple.compact}
-
-The \texttt{changelog} style hints at the expressive power of
-Mercurial's templating engine.  This style attempts to follow the GNU
-Project's changelog guidelines\cite{web:changelog}.
-
-\interaction{template.simple.changelog}
-
-You will not be shocked to learn that Mercurial's default output style
-is named \texttt{default}.
-
-\subsection{Setting a default style}
-
-You can modify the output style that Mercurial will use for every
-command by editing your \hgrc\ file, naming the style you would
-prefer to use.
-
-\begin{codesample2}
-  [ui]
-  style = compact
-\end{codesample2}
-
-If you write a style of your own, you can use it by either providing
-the path to your style file, or copying your style file into a
-location where Mercurial can find it (typically the \texttt{templates}
-subdirectory of your Mercurial install directory).
-
-\section{Commands that support styles and templates}
-
-All of Mercurial's ``\texttt{log}-like'' commands let you use styles
-and templates: \hgcmd{incoming}, \hgcmd{log}, \hgcmd{outgoing}, and
-\hgcmd{tip}.
-
-As I write this manual, these are so far the only commands that
-support styles and templates.  Since these are the most important
-commands that need customisable output, there has been little pressure
-from the Mercurial user community to add style and template support to
-other commands.
-
-\section{The basics of templating}
-
-At its simplest, a Mercurial template is a piece of text.  Some of the
-text never changes, while other parts are \emph{expanded}, or replaced
-with new text, when necessary.
-
-Before we continue, let's look again at a simple example of
-Mercurial's normal output.
-
-\interaction{template.simple.normal}
-
-Now, let's run the same command, but using a template to change its
-output.
-
-\interaction{template.simple.simplest}
-
-The example above illustrates the simplest possible template; it's
-just a piece of static text, printed once for each changeset.  The
-\hgopt{log}{--template} option to the \hgcmd{log} command tells
-Mercurial to use the given text as the template when printing each
-changeset.
-
-Notice that the template string above ends with the text
-``\Verb+\n+''.  This is an \emph{escape sequence}, telling Mercurial
-to print a newline at the end of each template item.  If you omit this
-newline, Mercurial will run each piece of output together.  See
-section~\ref{sec:template:escape} for more details of escape sequences.
-
-A template that prints a fixed string of text all the time isn't very
-useful; let's try something a bit more complex.
-
-\interaction{template.simple.simplesub}
-
-As you can see, the string ``\Verb+{desc}+'' in the template has been
-replaced in the output with the description of each changeset.  Every
-time Mercurial finds text enclosed in curly braces (``\texttt{\{}''
-and ``\texttt{\}}''), it will try to replace the braces and text with
-the expansion of whatever is inside.  To print a literal curly brace,
-you must escape it, as described in section~\ref{sec:template:escape}.
-
-\section{Common template keywords}
-\label{sec:template:keyword}
-
-You can start writing simple templates immediately using the keywords
-below.
-
-\begin{itemize}
-\item[\tplkword{author}] String.  The unmodified author of the changeset.
-\item[\tplkword{branches}] String.  The name of the branch on which
-  the changeset was committed.  Will be empty if the branch name was
-  \texttt{default}.
-\item[\tplkword{date}] Date information.  The date when the changeset
-  was committed.  This is \emph{not} human-readable; you must pass it
-  through a filter that will render it appropriately.  See
-  section~\ref{sec:template:filter} for more information on filters.
-  The date is expressed as a pair of numbers.  The first number is a
-  Unix UTC timestamp (seconds since January 1, 1970); the second is
-  the offset of the committer's timezone from UTC, in seconds.
-\item[\tplkword{desc}] String.  The text of the changeset description.
-\item[\tplkword{files}] List of strings.  All files modified, added, or
-  removed by this changeset.
-\item[\tplkword{file\_adds}] List of strings.  Files added by this
-  changeset.
-\item[\tplkword{file\_dels}] List of strings.  Files removed by this
-  changeset.
-\item[\tplkword{node}] String.  The changeset identification hash, as a
-  40-character hexadecimal string.
-\item[\tplkword{parents}] List of strings.  The parents of the
-  changeset.
-\item[\tplkword{rev}] Integer.  The repository-local changeset revision
-  number.
-\item[\tplkword{tags}] List of strings.  Any tags associated with the
-  changeset.
-\end{itemize}
-
-A few simple experiments will show us what to expect when we use these
-keywords; you can see the results in
-figure~\ref{fig:template:keywords}.
-
-\begin{figure}
-  \interaction{template.simple.keywords}
-  \caption{Template keywords in use}
-  \label{fig:template:keywords}
-\end{figure}
-
-As we noted above, the date keyword does not produce human-readable
-output, so we must treat it specially.  This involves using a
-\emph{filter}, about which more in section~\ref{sec:template:filter}.
-
-\interaction{template.simple.datekeyword}
-
-\section{Escape sequences}
-\label{sec:template:escape}
-
-Mercurial's templating engine recognises the most commonly used escape
-sequences in strings.  When it sees a backslash (``\Verb+\+'')
-character, it looks at the following character and substitutes the two
-characters with a single replacement, as described below.
-
-\begin{itemize}
-\item[\Verb+\textbackslash\textbackslash+] Backslash, ``\Verb+\+'',
-  ASCII~134.
-\item[\Verb+\textbackslash n+] Newline, ASCII~12.
-\item[\Verb+\textbackslash r+] Carriage return, ASCII~15.
-\item[\Verb+\textbackslash t+] Tab, ASCII~11.
-\item[\Verb+\textbackslash v+] Vertical tab, ASCII~13.
-\item[\Verb+\textbackslash \{+] Open curly brace, ``\Verb+{+'', ASCII~173.
-\item[\Verb+\textbackslash \}+] Close curly brace, ``\Verb+}+'', ASCII~175.
-\end{itemize}
-
-As indicated above, if you want the expansion of a template to contain
-a literal ``\Verb+\+'', ``\Verb+{+'', or ``\Verb+{+'' character, you
-must escape it.
-
-\section{Filtering keywords to change their results}
-\label{sec:template:filter}
-
-Some of the results of template expansion are not immediately easy to
-use.  Mercurial lets you specify an optional chain of \emph{filters}
-to modify the result of expanding a keyword.  You have already seen a
-common filter, \tplkwfilt{date}{isodate}, in action above, to make a
-date readable.
-
-Below is a list of the most commonly used filters that Mercurial
-supports.  While some filters can be applied to any text, others can
-only be used in specific circumstances.  The name of each filter is
-followed first by an indication of where it can be used, then a
-description of its effect.
-
-\begin{itemize}
-\item[\tplfilter{addbreaks}] Any text. Add an XHTML ``\Verb+<br/>+''
-  tag before the end of every line except the last.  For example,
-  ``\Verb+foo\nbar+'' becomes ``\Verb+foo<br/>\nbar+''.
-\item[\tplkwfilt{date}{age}] \tplkword{date} keyword.  Render the
-  age of the date, relative to the current time.  Yields a string like
-  ``\Verb+10 minutes+''.
-\item[\tplfilter{basename}] Any text, but most useful for the
-  \tplkword{files} keyword and its relatives.  Treat the text as a
-  path, and return the basename. For example, ``\Verb+foo/bar/baz+''
-  becomes ``\Verb+baz+''.
-\item[\tplkwfilt{date}{date}] \tplkword{date} keyword.  Render a date
-  in a similar format to the Unix \tplkword{date} command, but with
-  timezone included.  Yields a string like
-  ``\Verb+Mon Sep 04 15:13:13 2006 -0700+''.
-\item[\tplkwfilt{author}{domain}] Any text, but most useful for the
-  \tplkword{author} keyword.  Finds the first string that looks like
-  an email address, and extract just the domain component.  For
-  example, ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
-  ``\Verb+serpentine.com+''.
-\item[\tplkwfilt{author}{email}] Any text, but most useful for the
-  \tplkword{author} keyword.  Extract the first string that looks like
-  an email address.  For example,
-  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
-  ``\Verb+bos@serpentine.com+''.
-\item[\tplfilter{escape}] Any text.  Replace the special XML/XHTML
-  characters ``\Verb+&+'', ``\Verb+<+'' and ``\Verb+>+'' with
-  XML entities.
-\item[\tplfilter{fill68}] Any text.  Wrap the text to fit in 68
-  columns.  This is useful before you pass text through the
-  \tplfilter{tabindent} filter, and still want it to fit in an
-  80-column fixed-font window.
-\item[\tplfilter{fill76}] Any text.  Wrap the text to fit in 76
-  columns.
-\item[\tplfilter{firstline}] Any text.  Yield the first line of text,
-  without any trailing newlines.
-\item[\tplkwfilt{date}{hgdate}] \tplkword{date} keyword.  Render the
-  date as a pair of readable numbers.  Yields a string like
-  ``\Verb+1157407993 25200+''.
-\item[\tplkwfilt{date}{isodate}] \tplkword{date} keyword.  Render the
-  date as a text string in ISO~8601 format.  Yields a string like
-  ``\Verb+2006-09-04 15:13:13 -0700+''.
-\item[\tplfilter{obfuscate}] Any text, but most useful for the
-  \tplkword{author} keyword.  Yield the input text rendered as a
-  sequence of XML entities.  This helps to defeat some particularly
-  stupid screen-scraping email harvesting spambots.
-\item[\tplkwfilt{author}{person}] Any text, but most useful for the
-  \tplkword{author} keyword.  Yield the text before an email address.
-  For example, ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+''
-  becomes ``\Verb+Bryan O'Sullivan+''.
-\item[\tplkwfilt{date}{rfc822date}] \tplkword{date} keyword.  Render a
-  date using the same format used in email headers.  Yields a string
-  like ``\Verb+Mon, 04 Sep 2006 15:13:13 -0700+''.
-\item[\tplkwfilt{node}{short}] Changeset hash.  Yield the short form
-  of a changeset hash, i.e.~a 12-byte hexadecimal string.
-\item[\tplkwfilt{date}{shortdate}] \tplkword{date} keyword.  Render
-  the year, month, and day of the date.  Yields a string like
-  ``\Verb+2006-09-04+''.
-\item[\tplfilter{strip}] Any text.  Strip all leading and trailing
-  whitespace from the string.
-\item[\tplfilter{tabindent}] Any text.  Yield the text, with every line
-  except the first starting with a tab character.
-\item[\tplfilter{urlescape}] Any text.  Escape all characters that are
-  considered ``special'' by URL parsers.  For example, \Verb+foo bar+
-  becomes \Verb+foo%20bar+.
-\item[\tplkwfilt{author}{user}] Any text, but most useful for the
-  \tplkword{author} keyword.  Return the ``user'' portion of an email
-  address.  For example,
-  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' becomes
-  ``\Verb+bos+''.
-\end{itemize}
-
-\begin{figure}
-  \interaction{template.simple.manyfilters}
-  \caption{Template filters in action}
-  \label{fig:template:filters}
-\end{figure}
-
-\begin{note}
-  If you try to apply a filter to a piece of data that it cannot
-  process, Mercurial will fail and print a Python exception.  For
-  example, trying to run the output of the \tplkword{desc} keyword
-  into the \tplkwfilt{date}{isodate} filter is not a good idea.
-\end{note}
-
-\subsection{Combining filters}
-
-It is easy to combine filters to yield output in the form you would
-like.  The following chain of filters tidies up a description, then
-makes sure that it fits cleanly into 68 columns, then indents it by a
-further 8~characters (at least on Unix-like systems, where a tab is
-conventionally 8~characters wide).
-
-\interaction{template.simple.combine}
-
-Note the use of ``\Verb+\t+'' (a tab character) in the template to
-force the first line to be indented; this is necessary since
-\tplkword{tabindent} indents all lines \emph{except} the first.
-
-Keep in mind that the order of filters in a chain is significant.  The
-first filter is applied to the result of the keyword; the second to
-the result of the first filter; and so on.  For example, using
-\Verb+fill68|tabindent+ gives very different results from
-\Verb+tabindent|fill68+.
-
-
-\section{From templates to styles}
-
-A command line template provides a quick and simple way to format some
-output.  Templates can become verbose, though, and it's useful to be
-able to give a template a name.  A style file is a template with a
-name, stored in a file.
-
-More than that, using a style file unlocks the power of Mercurial's
-templating engine in ways that are not possible using the command line
-\hgopt{log}{--template} option.
-
-\subsection{The simplest of style files}
-
-Our simple style file contains just one line:
-
-\interaction{template.simple.rev}
-
-This tells Mercurial, ``if you're printing a changeset, use the text
-on the right as the template''.
-
-\subsection{Style file syntax}
-
-The syntax rules for a style file are simple.
-
-\begin{itemize}
-\item The file is processed one line at a time.
-
-\item Leading and trailing white space are ignored.
-
-\item Empty lines are skipped.
-
-\item If a line starts with either of the characters ``\texttt{\#}'' or
-  ``\texttt{;}'', the entire line is treated as a comment, and skipped
-  as if empty.
-
-\item A line starts with a keyword.  This must start with an
-  alphabetic character or underscore, and can subsequently contain any
-  alphanumeric character or underscore.  (In regexp notation, a
-  keyword must match \Verb+[A-Za-z_][A-Za-z0-9_]*+.)
-
-\item The next element must be an ``\texttt{=}'' character, which can
-  be preceded or followed by an arbitrary amount of white space.
-
-\item If the rest of the line starts and ends with matching quote
-  characters (either single or double quote), it is treated as a
-  template body.
-
-\item If the rest of the line \emph{does not} start with a quote
-  character, it is treated as the name of a file; the contents of this
-  file will be read and used as a template body.
-\end{itemize}
-
-\section{Style files by example}
-
-To illustrate how to write a style file, we will construct a few by
-example.  Rather than provide a complete style file and walk through
-it, we'll mirror the usual process of developing a style file by
-starting with something very simple, and walking through a series of
-successively more complete examples.
-
-\subsection{Identifying mistakes in style files}
-
-If Mercurial encounters a problem in a style file you are working on,
-it prints a terse error message that, once you figure out what it
-means, is actually quite useful.
-
-\interaction{template.svnstyle.syntax.input}
-
-Notice that \filename{broken.style} attempts to define a
-\texttt{changeset} keyword, but forgets to give any content for it.
-When instructed to use this style file, Mercurial promptly complains.
-
-\interaction{template.svnstyle.syntax.error}
-
-This error message looks intimidating, but it is not too hard to
-follow.
-
-\begin{itemize}
-\item The first component is simply Mercurial's way of saying ``I am
-  giving up''.
-  \begin{codesample4}
-    \textbf{abort:} broken.style:1: parse error
-  \end{codesample4}
-
-\item Next comes the name of the style file that contains the error.
-  \begin{codesample4}
-    abort: \textbf{broken.style}:1: parse error
-  \end{codesample4}
-
-\item Following the file name is the line number where the error was
-  encountered.
-  \begin{codesample4}
-    abort: broken.style:\textbf{1}: parse error
-  \end{codesample4}
-
-\item Finally, a description of what went wrong.
-  \begin{codesample4}
-    abort: broken.style:1: \textbf{parse error}
-  \end{codesample4}
-  The description of the problem is not always clear (as in this
-  case), but even when it is cryptic, it is almost always trivial to
-  visually inspect the offending line in the style file and see what
-  is wrong.
-\end{itemize}
-
-\subsection{Uniquely identifying a repository}
-
-If you would like to be able to identify a Mercurial repository
-``fairly uniquely'' using a short string as an identifier, you can
-use the first revision in the repository.
-\interaction{template.svnstyle.id} 
-This is not guaranteed to be unique, but it is nevertheless useful in
-many cases.
-\begin{itemize}
-\item It will not work in a completely empty repository, because such
-  a repository does not have a revision~zero.
-\item Neither will it work in the (extremely rare) case where a
-  repository is a merge of two or more formerly independent
-  repositories, and you still have those repositories around.
-\end{itemize}
-Here are some uses to which you could put this identifier:
-\begin{itemize}
-\item As a key into a table for a database that manages repositories
-  on a server.
-\item As half of a \{\emph{repository~ID}, \emph{revision~ID}\} tuple.
-  Save this information away when you run an automated build or other
-  activity, so that you can ``replay'' the build later if necessary.
-\end{itemize}
-
-\subsection{Mimicking Subversion's output}
-
-Let's try to emulate the default output format used by another
-revision control tool, Subversion.
-\interaction{template.svnstyle.short}
-
-Since Subversion's output style is fairly simple, it is easy to
-copy-and-paste a hunk of its output into a file, and replace the text
-produced above by Subversion with the template values we'd like to see
-expanded.
-\interaction{template.svnstyle.template}
-
-There are a few small ways in which this template deviates from the
-output produced by Subversion.
-\begin{itemize}
-\item Subversion prints a ``readable'' date (the ``\texttt{Wed, 27 Sep
-    2006}'' in the example output above) in parentheses.  Mercurial's
-  templating engine does not provide a way to display a date in this
-  format without also printing the time and time zone.
-\item We emulate Subversion's printing of ``separator'' lines full of
-  ``\texttt{-}'' characters by ending the template with such a line.
-  We use the templating engine's \tplkword{header} keyword to print a
-  separator line as the first line of output (see below), thus
-  achieving similar output to Subversion.
-\item Subversion's output includes a count in the header of the number
-  of lines in the commit message.  We cannot replicate this in
-  Mercurial; the templating engine does not currently provide a filter
-  that counts the number of items it is passed.
-\end{itemize}
-It took me no more than a minute or two of work to replace literal
-text from an example of Subversion's output with some keywords and
-filters to give the template above.  The style file simply refers to
-the template.
-\interaction{template.svnstyle.style}
-
-We could have included the text of the template file directly in the
-style file by enclosing it in quotes and replacing the newlines with
-``\texttt{\\n}'' sequences, but it would have made the style file too
-difficult to read.  Readability is a good guide when you're trying to
-decide whether some text belongs in a style file, or in a template
-file that the style file points to.  If the style file will look too
-big or cluttered if you insert a literal piece of text, drop it into a
-template instead.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/tour-basic.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-\chapter{A tour of Mercurial: the basics}
-\label{chap:tour-basic}
-
-\section{Installing Mercurial on your system}
-\label{sec:tour:install}
-
-Prebuilt binary packages of Mercurial are available for every popular
-operating system.  These make it easy to start using Mercurial on your
-computer immediately.
-
-\subsection{Linux}
-
-Because each Linux distribution has its own packaging tools, policies,
-and rate of development, it's difficult to give a comprehensive set of
-instructions on how to install Mercurial binaries.  The version of
-Mercurial that you will end up with can vary depending on how active
-the person is who maintains the package for your distribution.
-
-To keep things simple, I will focus on installing Mercurial from the
-command line under the most popular Linux distributions.  Most of
-these distributions provide graphical package managers that will let
-you install Mercurial with a single click; the package name to look
-for is \texttt{mercurial}.
-
-\begin{itemize}
-\item[Debian]
-  \begin{codesample4}
-    apt-get install mercurial
-  \end{codesample4}
-
-\item[Fedora Core]
-  \begin{codesample4}
-    yum install mercurial
-  \end{codesample4}
-
-\item[Gentoo]
-  \begin{codesample4}
-    emerge mercurial
-  \end{codesample4}
-
-\item[OpenSUSE]
-  \begin{codesample4}
-    yum install mercurial
-  \end{codesample4}
-
-\item[Ubuntu] Ubuntu's Mercurial package is based on Debian's.  To
-  install it, run the following command.
-  \begin{codesample4}
-    apt-get install mercurial
-  \end{codesample4}
-  The Ubuntu package for Mercurial tends to lag behind the Debian
-  version by a considerable time margin (at the time of writing, seven
-  months), which in some cases will mean that on Ubuntu, you may run
-  into problems that have since been fixed in the Debian package.
-\end{itemize}
-
-\subsection{Solaris}
-
-XXX.
-
-\subsection{Mac OS X}
-
-Lee Cantey publishes an installer of Mercurial for Mac OS~X at
-\url{http://mercurial.berkwood.com}.  This package works on both
-Intel-~and Power-based Macs.  Before you can use it, you must install
-a compatible version of Universal MacPython~\cite{web:macpython}.  This
-is easy to do; simply follow the instructions on Lee's site.
-
-\subsection{Windows}
-
-Lee Cantey also publishes an installer of Mercurial for Windows at
-\url{http://mercurial.berkwood.com}.  This package has no external
-dependencies; it ``just works''.
-
-\begin{note}
-  The Windows version of Mercurial does not automatically convert line
-  endings between Windows and Unix styles.  If you want to share work
-  with Unix users, you must do a little additional configuration
-  work. XXX Flesh this out.
-\end{note}
-
-\section{Getting started}
-
-To begin, we'll use the \hgcmd{version} command to find out whether
-Mercurial is actually installed properly.  The actual version
-information that it prints isn't so important; it's whether it prints
-anything at all that we care about.
-\interaction{tour.version}
-
-\subsection{Built-in help}
-
-Mercurial provides a built-in help system.  This is invaluable for those
-times when you find yourself stuck trying to remember how to run a
-command.  If you are completely stuck, simply run \hgcmd{help}; it
-will print a brief list of commands, along with a description of what
-each does.  If you ask for help on a specific command (as below), it
-prints more detailed information.
-\interaction{tour.help}
-For a more impressive level of detail (which you won't usually need)
-run \hgcmdargs{help}{\hggopt{-v}}.  The \hggopt{-v} option is short
-for \hggopt{--verbose}, and tells Mercurial to print more information
-than it usually would.
-
-\section{Working with a repository}
-
-In Mercurial, everything happens inside a \emph{repository}.  The
-repository for a project contains all of the files that ``belong to''
-that project, along with a historical record of the project's files.
-
-There's nothing particularly magical about a repository; it is simply
-a directory tree in your filesystem that Mercurial treats as special.
-You can rename or delete a repository any time you like, using either the
-command line or your file browser.
-
-\subsection{Making a local copy of a repository}
-
-\emph{Copying} a repository is just a little bit special.  While you
-could use a normal file copying command to make a copy of a
-repository, it's best to use a built-in command that Mercurial
-provides.  This command is called \hgcmd{clone}, because it creates an
-identical copy of an existing repository.
-\interaction{tour.clone}
-If our clone succeeded, we should now have a local directory called
-\dirname{hello}.  This directory will contain some files.
-\interaction{tour.ls}
-These files have the same contents and history in our repository as
-they do in the repository we cloned.
-
-Every Mercurial repository is complete, self-contained, and
-independent.  It contains its own private copy of a project's files
-and history.  A cloned repository remembers the location of the
-repository it was cloned from, but it does not communicate with that
-repository, or any other, unless you tell it to.
-
-What this means for now is that we're free to experiment with our
-repository, safe in the knowledge that it's a private ``sandbox'' that
-won't affect anyone else.
-
-\subsection{What's in a repository?}
-
-When we take a more detailed look inside a repository, we can see that
-it contains a directory named \dirname{.hg}.  This is where Mercurial
-keeps all of its metadata for the repository.
-\interaction{tour.ls-a}
-
-The contents of the \dirname{.hg} directory and its subdirectories are
-private to Mercurial.  Every other file and directory in the
-repository is yours to do with as you please.
-
-To introduce a little terminology, the \dirname{.hg} directory is the
-``real'' repository, and all of the files and directories that coexist
-with it are said to live in the \emph{working directory}.  An easy way
-to remember the distinction is that the \emph{repository} contains the
-\emph{history} of your project, while the \emph{working directory}
-contains a \emph{snapshot} of your project at a particular point in
-history.
-
-\section{A tour through history}
-
-One of the first things we might want to do with a new, unfamiliar
-repository is understand its history.  The \hgcmd{log} command gives
-us a view of history.
-\interaction{tour.log}
-By default, this command prints a brief paragraph of output for each
-change to the project that was recorded.  In Mercurial terminology, we
-call each of these recorded events a \emph{changeset}, because it can
-contain a record of changes to several files.
-
-The fields in a record of output from \hgcmd{log} are as follows.
-\begin{itemize}
-\item[\texttt{changeset}] This field has the format of a number,
-  followed by a colon, followed by a hexadecimal string.  These are
-  \emph{identifiers} for the changeset.  There are two identifiers
-  because the number is shorter and easier to type than the hex
-  string.
-\item[\texttt{user}] The identity of the person who created the
-  changeset.  This is a free-form field, but it most often contains a
-  person's name and email address.
-\item[\texttt{date}] The date and time on which the changeset was
-  created, and the timezone in which it was created.  (The date and
-  time are local to that timezone; they display what time and date it
-  was for the person who created the changeset.)
-\item[\texttt{summary}] The first line of the text message that the
-  creator of the changeset entered to describe the changeset.
-\end{itemize}
-The default output printed by \hgcmd{log} is purely a summary; it is
-missing a lot of detail.
-
-Figure~\ref{fig:tour-basic:history} provides a graphical representation of
-the history of the \dirname{hello} repository, to make it a little
-easier to see which direction history is ``flowing'' in.  We'll be
-returning to this figure several times in this chapter and the chapter
-that follows.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{tour-history}
-  \caption{Graphical history of the \dirname{hello} repository}
-  \label{fig:tour-basic:history}
-\end{figure}
-
-\subsection{Changesets, revisions, and talking to other 
-  people}
-
-As English is a notoriously sloppy language, and computer science has
-a hallowed history of terminological confusion (why use one term when
-four will do?), revision control has a variety of words and phrases
-that mean the same thing.  If you are talking about Mercurial history
-with other people, you will find that the word ``changeset'' is often
-compressed to ``change'' or (when written) ``cset'', and sometimes a
-changeset is referred to as a ``revision'' or a ``rev''.
-
-While it doesn't matter what \emph{word} you use to refer to the
-concept of ``a~changeset'', the \emph{identifier} that you use to
-refer to ``a~\emph{specific} changeset'' is of great importance.
-Recall that the \texttt{changeset} field in the output from
-\hgcmd{log} identifies a changeset using both a number and a
-hexadecimal string.
-\begin{itemize}
-\item The revision number is \emph{only valid in that repository},
-\item while the hex string is the \emph{permanent, unchanging
-    identifier} that will always identify that exact changeset in
-  \emph{every} copy of the repository.
-\end{itemize}
-This distinction is important.  If you send someone an email talking
-about ``revision~33'', there's a high likelihood that their
-revision~33 will \emph{not be the same} as yours.  The reason for this
-is that a revision number depends on the order in which changes
-arrived in a repository, and there is no guarantee that the same
-changes will happen in the same order in different repositories.
-Three changes $a,b,c$ can easily appear in one repository as $0,1,2$,
-while in another as $1,0,2$.
-
-Mercurial uses revision numbers purely as a convenient shorthand.  If
-you need to discuss a changeset with someone, or make a record of a
-changeset for some other reason (for example, in a bug report), use
-the hexadecimal identifier.
-
-\subsection{Viewing specific revisions}
-
-To narrow the output of \hgcmd{log} down to a single revision, use the
-\hgopt{log}{-r} (or \hgopt{log}{--rev}) option.  You can use either a
-revision number or a long-form changeset identifier, and you can
-provide as many revisions as you want.  \interaction{tour.log-r}
-
-If you want to see the history of several revisions without having to
-list each one, you can use \emph{range notation}; this lets you
-express the idea ``I want all revisions between $a$ and $b$,
-inclusive''.
-\interaction{tour.log.range}
-Mercurial also honours the order in which you specify revisions, so
-\hgcmdargs{log}{-r 2:4} prints $2,3,4$ while \hgcmdargs{log}{-r 4:2}
-prints $4,3,2$.
-
-\subsection{More detailed information}
-
-While the summary information printed by \hgcmd{log} is useful if you
-already know what you're looking for, you may need to see a complete
-description of the change, or a list of the files changed, if you're
-trying to decide whether a changeset is the one you're looking for.
-The \hgcmd{log} command's \hggopt{-v} (or \hggopt{--verbose})
-option gives you this extra detail.
-\interaction{tour.log-v}
-
-If you want to see both the description and content of a change, add
-the \hgopt{log}{-p} (or \hgopt{log}{--patch}) option.  This displays
-the content of a change as a \emph{unified diff} (if you've never seen
-a unified diff before, see section~\ref{sec:mq:patch} for an overview).
-\interaction{tour.log-vp}
-
-\section{All about command options}
-
-Let's take a brief break from exploring Mercurial commands to discuss
-a pattern in the way that they work; you may find this useful to keep
-in mind as we continue our tour.
-
-Mercurial has a consistent and straightforward approach to dealing
-with the options that you can pass to commands.  It follows the
-conventions for options that are common to modern Linux and Unix
-systems.
-\begin{itemize}
-\item Every option has a long name.  For example, as we've already
-  seen, the \hgcmd{log} command accepts a \hgopt{log}{--rev} option.
-\item Most options have short names, too.  Instead of
-  \hgopt{log}{--rev}, we can use \hgopt{log}{-r}.  (The reason that
-  some options don't have short names is that the options in question
-  are rarely used.)
-\item Long options start with two dashes (e.g.~\hgopt{log}{--rev}),
-  while short options start with one (e.g.~\hgopt{log}{-r}).
-\item Option naming and usage is consistent across commands.  For
-  example, every command that lets you specify a changeset~ID or
-  revision number accepts both \hgopt{log}{-r} and \hgopt{log}{--rev}
-  arguments.
-\end{itemize}
-In the examples throughout this book, I use short options instead of
-long.  This just reflects my own preference, so don't read anything
-significant into it.
-
-Most commands that print output of some kind will print more output
-when passed a \hggopt{-v} (or \hggopt{--verbose}) option, and less
-when passed \hggopt{-q} (or \hggopt{--quiet}).
-
-\section{Making and reviewing changes}
-
-Now that we have a grasp of viewing history in Mercurial, let's take a
-look at making some changes and examining them.
-
-The first thing we'll do is isolate our experiment in a repository of
-its own.  We use the \hgcmd{clone} command, but we don't need to
-clone a copy of the remote repository.  Since we already have a copy
-of it locally, we can just clone that instead.  This is much faster
-than cloning over the network, and cloning a local repository uses
-less disk space in most cases, too.
-\interaction{tour.reclone}
-As an aside, it's often good practice to keep a ``pristine'' copy of a
-remote repository around, which you can then make temporary clones of
-to create sandboxes for each task you want to work on.  This lets you
-work on multiple tasks in parallel, each isolated from the others
-until it's complete and you're ready to integrate it back.  Because
-local clones are so cheap, there's almost no overhead to cloning and
-destroying repositories whenever you want.
-
-In our \dirname{my-hello} repository, we have a file
-\filename{hello.c} that contains the classic ``hello, world'' program.
-Let's use the ancient and venerable \command{sed} command to edit this
-file so that it prints a second line of output.  (I'm only using
-\command{sed} to do this because it's easy to write a scripted example
-this way.  Since you're not under the same constraint, you probably
-won't want to use \command{sed}; simply use your preferred text editor to
-do the same thing.)
-\interaction{tour.sed}
-
-Mercurial's \hgcmd{status} command will tell us what Mercurial knows
-about the files in the repository.
-\interaction{tour.status}
-The \hgcmd{status} command prints no output for some files, but a line
-starting with ``\texttt{M}'' for \filename{hello.c}.  Unless you tell
-it to, \hgcmd{status} will not print any output for files that have
-not been modified.  
-
-The ``\texttt{M}'' indicates that Mercurial has noticed that we
-modified \filename{hello.c}.  We didn't need to \emph{inform}
-Mercurial that we were going to modify the file before we started, or
-that we had modified the file after we were done; it was able to
-figure this out itself.
-
-It's a little bit helpful to know that we've modified
-\filename{hello.c}, but we might prefer to know exactly \emph{what}
-changes we've made to it.  To do this, we use the \hgcmd{diff}
-command.
-\interaction{tour.diff}
-
-\section{Recording changes in a new changeset}
-
-We can modify files, build and test our changes, and use
-\hgcmd{status} and \hgcmd{diff} to review our changes, until we're
-satisfied with what we've done and arrive at a natural stopping point
-where we want to record our work in a new changeset.
-
-The \hgcmd{commit} command lets us create a new changeset; we'll
-usually refer to this as ``making a commit'' or ``committing''.  
-
-\subsection{Setting up a username}
-
-When you try to run \hgcmd{commit} for the first time, it is not
-guaranteed to succeed.  Mercurial records your name and address with
-each change that you commit, so that you and others will later be able
-to tell who made each change.  Mercurial tries to automatically figure
-out a sensible username to commit the change with.  It will attempt
-each of the following methods, in order:
-\begin{enumerate}
-\item If you specify a \hgopt{commit}{-u} option to the \hgcmd{commit}
-  command on the command line, followed by a username, this is always
-  given the highest precedence.
-\item If you have set the \envar{HGUSER} environment variable, this is
-  checked next.
-\item If you create a file in your home directory called
-  \sfilename{.hgrc}, with a \rcitem{ui}{username} entry, that will be
-  used next.  To see what the contents of this file should look like,
-  refer to section~\ref{sec:tour-basic:username} below.
-\item If you have set the \envar{EMAIL} environment variable, this
-  will be used next.
-\item Mercurial will query your system to find out your local user
-  name and host name, and construct a username from these components.
-  Since this often results in a username that is not very useful, it
-  will print a warning if it has to do this.
-\end{enumerate}
-If all of these mechanisms fail, Mercurial will fail, printing an
-error message.  In this case, it will not let you commit until you set
-up a username.
-
-You should think of the \envar{HGUSER} environment variable and the
-\hgopt{commit}{-u} option to the \hgcmd{commit} command as ways to
-\emph{override} Mercurial's default selection of username.  For normal
-use, the simplest and most robust way to set a username for yourself
-is by creating a \sfilename{.hgrc} file; see below for details.
-
-\subsubsection{Creating a Mercurial configuration file}
-\label{sec:tour-basic:username}
-
-To set a user name, use your favourite editor to create a file called
-\sfilename{.hgrc} in your home directory.  Mercurial will use this
-file to look up your personalised configuration settings.  The initial
-contents of your \sfilename{.hgrc} should look like this.
-\begin{codesample2}
-  # This is a Mercurial configuration file.
-  [ui]
-  username = Firstname Lastname <email.address@domain.net>
-\end{codesample2}
-The ``\texttt{[ui]}'' line begins a \emph{section} of the config file,
-so you can read the ``\texttt{username = ...}'' line as meaning ``set
-the value of the \texttt{username} item in the \texttt{ui} section''.
-A section continues until a new section begins, or the end of the
-file.  Mercurial ignores empty lines and treats any text from
-``\texttt{\#}'' to the end of a line as a comment.
-
-\subsubsection{Choosing a user name}
-
-You can use any text you like as the value of the \texttt{username}
-config item, since this information is for reading by other people,
-but for interpreting by Mercurial.  The convention that most people
-follow is to use their name and email address, as in the example
-above.
-
-\begin{note}
-  Mercurial's built-in web server obfuscates email addresses, to make
-  it more difficult for the email harvesting tools that spammers use.
-  This reduces the likelihood that you'll start receiving more junk
-  email if you publish a Mercurial repository on the web.
-\end{note}
-
-\subsection{Writing a commit message}
-
-When we commit a change, Mercurial drops us into a text editor, to
-enter a message that will describe the modifications we've made in
-this changeset.  This is called the \emph{commit message}.  It will be
-a record for readers of what we did and why, and it will be printed by
-\hgcmd{log} after we've finished committing.
-\interaction{tour.commit}
-
-The editor that the \hgcmd{commit} command drops us into will contain
-an empty line, followed by a number of lines starting with
-``\texttt{HG:}''.
-\begin{codesample2}
-  \emph{empty line}
-  HG: changed hello.c
-\end{codesample2}
-Mercurial ignores the lines that start with ``\texttt{HG:}''; it uses
-them only to tell us which files it's recording changes to.  Modifying
-or deleting these lines has no effect.
-
-\subsection{Writing a good commit message}
-
-Since \hgcmd{log} only prints the first line of a commit message by
-default, it's best to write a commit message whose first line stands
-alone.  Here's a real example of a commit message that \emph{doesn't}
-follow this guideline, and hence has a summary that is not readable.
-\begin{codesample2}
-  changeset:   73:584af0e231be
-  user:        Censored Person <censored.person@example.org>
-  date:        Tue Sep 26 21:37:07 2006 -0700
-  summary:     include buildmeister/commondefs.   Add an exports and install
-\end{codesample2}
-
-As far as the remainder of the contents of the commit message are
-concerned, there are no hard-and-fast rules.  Mercurial itself doesn't
-interpret or care about the contents of the commit message, though
-your project may have policies that dictate a certain kind of
-formatting.
-
-My personal preference is for short, but informative, commit messages
-that tell me something that I can't figure out with a quick glance at
-the output of \hgcmdargs{log}{--patch}.
-
-\subsection{Aborting a commit}
-
-If you decide that you don't want to commit while in the middle of
-editing a commit message, simply exit from your editor without saving
-the file that it's editing.  This will cause nothing to happen to
-either the repository or the working directory.
-
-If we run the \hgcmd{commit} command without any arguments, it records
-all of the changes we've made, as reported by \hgcmd{status} and
-\hgcmd{diff}.
-
-\subsection{Admiring our new handiwork}
-
-Once we've finished the commit, we can use the \hgcmd{tip} command to
-display the changeset we just created.  This command produces output
-that is identical to \hgcmd{log}, but it only displays the newest
-revision in the repository.
-\interaction{tour.tip}
-We refer to the newest revision in the repository as the tip revision,
-or simply the tip.
-
-\section{Sharing changes}
-
-We mentioned earlier that repositories in Mercurial are
-self-contained.  This means that the changeset we just created exists
-only in our \dirname{my-hello} repository.  Let's look at a few ways
-that we can propagate this change into other repositories.
-
-\subsection{Pulling changes from another repository}
-\label{sec:tour:pull}
-
-To get started, let's clone our original \dirname{hello} repository,
-which does not contain the change we just committed.  We'll call our
-temporary repository \dirname{hello-pull}.
-\interaction{tour.clone-pull}
-
-We'll use the \hgcmd{pull} command to bring changes from
-\dirname{my-hello} into \dirname{hello-pull}.  However, blindly
-pulling unknown changes into a repository is a somewhat scary
-prospect.  Mercurial provides the \hgcmd{incoming} command to tell us
-what changes the \hgcmd{pull} command \emph{would} pull into the
-repository, without actually pulling the changes in.
-\interaction{tour.incoming}
-(Of course, someone could cause more changesets to appear in the
-repository that we ran \hgcmd{incoming} in, before we get a chance to
-\hgcmd{pull} the changes, so that we could end up pulling changes that we
-didn't expect.)
-
-Bringing changes into a repository is a simple matter of running the
-\hgcmd{pull} command, and telling it which repository to pull from.
-\interaction{tour.pull}
-As you can see from the before-and-after output of \hgcmd{tip}, we
-have successfully pulled changes into our repository.  There remains
-one step before we can see these changes in the working directory.
-
-\subsection{Updating the working directory}
-
-We have so far glossed over the relationship between a repository and
-its working directory.  The \hgcmd{pull} command that we ran in
-section~\ref{sec:tour:pull} brought changes into the repository, but
-if we check, there's no sign of those changes in the working
-directory.  This is because \hgcmd{pull} does not (by default) touch
-the working directory.  Instead, we use the \hgcmd{update} command to
-do this.
-\interaction{tour.update}
-
-It might seem a bit strange that \hgcmd{pull} doesn't update the
-working directory automatically.  There's actually a good reason for
-this: you can use \hgcmd{update} to update the working directory to
-the state it was in at \emph{any revision} in the history of the
-repository.  If you had the working directory updated to an old
-revision---to hunt down the origin of a bug, say---and ran a
-\hgcmd{pull} which automatically updated the working directory to a
-new revision, you might not be terribly happy.
-
-However, since pull-then-update is such a common thing to do,
-Mercurial lets you combine the two by passing the \hgopt{pull}{-u}
-option to \hgcmd{pull}.
-\begin{codesample2}
-  hg pull -u
-\end{codesample2}
-If you look back at the output of \hgcmd{pull} in
-section~\ref{sec:tour:pull} when we ran it without \hgopt{pull}{-u},
-you can see that it printed a helpful reminder that we'd have to take
-an explicit step to update the working directory:
-\begin{codesample2}
-  (run 'hg update' to get a working copy)
-\end{codesample2}
-
-To find out what revision the working directory is at, use the
-\hgcmd{parents} command.
-\interaction{tour.parents}
-If you look back at figure~\ref{fig:tour-basic:history}, you'll see
-arrows connecting each changeset.  The node that the arrow leads
-\emph{from} in each case is a parent, and the node that the arrow
-leads \emph{to} is its child.  The working directory has a parent in
-just the same way; this is the changeset that the working directory
-currently contains.
-
-To update the working directory to a particular revision, give a
-revision number or changeset~ID to the \hgcmd{update} command.
-\interaction{tour.older}
-If you omit an explicit revision, \hgcmd{update} will update to the
-tip revision, as shown by the second call to \hgcmd{update} in the
-example above.
-
-\subsection{Pushing changes to another repository}
-
-Mercurial lets us push changes to another repository, from the
-repository we're currently visiting.  As with the example of
-\hgcmd{pull} above, we'll create a temporary repository to push our
-changes into.
-\interaction{tour.clone-push}
-The \hgcmd{outgoing} command tells us what changes would be pushed
-into another repository.
-\interaction{tour.outgoing}
-And the \hgcmd{push} command does the actual push.
-\interaction{tour.push}
-As with \hgcmd{pull}, the \hgcmd{push} command does not update the
-working directory in the repository that it's pushing changes into.
-(Unlike \hgcmd{pull}, \hgcmd{push} does not provide a \texttt{-u}
-option that updates the other repository's working directory.)
-
-What happens if we try to pull or push changes and the receiving
-repository already has those changes?  Nothing too exciting.
-\interaction{tour.push.nothing}
-
-\subsection{Sharing changes over a network}
-
-The commands we have covered in the previous few sections are not
-limited to working with local repositories.  Each works in exactly the
-same fashion over a network connection; simply pass in a URL instead
-of a local path.
-\interaction{tour.outgoing.net}
-In this example, we can see what changes we could push to the remote
-repository, but the repository is understandably not set up to let
-anonymous users push to it.
-\interaction{tour.push.net}
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/tour-history.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="tour-history.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path2973"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3066"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="232.14286"
-     inkscape:cy="672.75296"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="5"
-     inkscape:window-y="49" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect1878"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="479.50504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="493.12619"
-       id="text1872"><tspan
-         sodipodi:role="line"
-         id="tspan1874"
-         x="162.09892"
-         y="493.12619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1876">0</tspan>: 0a04</tspan></text>
-    <rect
-       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2800"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="432.63004" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="446.25119"
-       id="text2794"><tspan
-         sodipodi:role="line"
-         id="tspan2796"
-         x="162.09892"
-         y="446.25119"
-         style="font-family:Courier"><tspan
-   id="tspan2868"
-   style="font-weight:bold">1</tspan>: 82e5</tspan></text>
-    <rect
-       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2810"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="385.75504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="399.37619"
-       id="text2804"><tspan
-         sodipodi:role="line"
-         id="tspan2806"
-         x="162.09892"
-         y="399.37619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2866">2</tspan>: 057d</tspan></text>
-    <rect
-       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2820"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="338.88007" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="352.50122"
-       id="text2814"><tspan
-         sodipodi:role="line"
-         id="tspan2816"
-         x="162.09892"
-         y="352.50122"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2864">3</tspan>: ff5d</tspan></text>
-    <rect
-       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2830"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="292.00504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="305.62619"
-       id="text2824"><tspan
-         sodipodi:role="line"
-         id="tspan2826"
-         x="162.09892"
-         y="305.62619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2862">4</tspan>: b57f</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="173.57143"
-       y="443.79074"
-       id="text2832"><tspan
-         sodipodi:role="line"
-         id="tspan2834"
-         x="173.57143"
-         y="443.79074" /></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 185.14286,478.50504 L 185.14286,454.34432"
-       id="path2894"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 185.14286,431.63004 L 185.14286,407.46932"
-       id="path2896"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 185.14286,384.75504 L 185.14286,360.59435"
-       id="path2898"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 185.14286,337.88007 L 185.14286,313.71932"
-       id="path2900"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
-       x="244.60992"
-       y="305.245"
-       id="text1902"><tspan
-         sodipodi:role="line"
-         id="tspan1904"
-         x="244.60992"
-         y="305.245">(newest)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
-       x="244.60992"
-       y="492.745"
-       id="text1906"><tspan
-         sodipodi:role="line"
-         id="tspan1908"
-         x="244.60992"
-         y="492.745">(oldest)</tspan></text>
-    <rect
-       style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect1907"
-       width="94.285713"
-       height="20.714285"
-       x="309.28571"
-       y="324.86218" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="333.38464"
-       y="338.48334"
-       id="text1909"><tspan
-         sodipodi:role="line"
-         id="tspan1911"
-         x="333.38464"
-         y="338.48334"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1913">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 332.14286,375.21932 L 335.71429,347.36218"
-       id="path2802" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 372.69968,375.21932 L 369.12825,347.36218"
-       id="path2986" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
-       x="335.14285"
-       y="387.21933"
-       id="text2988"><tspan
-         sodipodi:role="line"
-         x="335.14285"
-         y="387.21933"
-         id="tspan3020"
-         style="text-align:end;text-anchor:end">revision</tspan><tspan
-         sodipodi:role="line"
-         x="335.14285"
-         y="402.21933"
-         id="tspan3014"
-         style="text-align:end;text-anchor:end">number</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
-       x="368.71429"
-       y="387.21933"
-       id="text2994"><tspan
-         sodipodi:role="line"
-         id="tspan2996"
-         x="368.71429"
-         y="387.21933">changeset</tspan><tspan
-         sodipodi:role="line"
-         x="368.71429"
-         y="402.21933"
-         id="tspan2998">identifier</tspan></text>
-  </g>
-</svg>
--- a/en/tour-merge-conflict.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="tour-merge-conflict.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3053"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="164.78349"
-     inkscape:cy="590.07679"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="5"
-     inkscape:window-y="49" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <g
-       id="g1988"
-       transform="translate(84.85711,0)">
-      <g
-         id="g1876">
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
-           id="path1872"
-           sodipodi:nodetypes="cccccc" />
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
-           id="path1874"
-           sodipodi:nodetypes="cccc" />
-      </g>
-      <flowRoot
-         style="font-size:8px;font-family:Times New Roman"
-         id="flowRoot1898"
-         xml:space="preserve"><flowRegion
-           id="flowRegion1900"><rect
-             style="font-size:8px;font-family:Times New Roman"
-             y="464.50504"
-             x="122.85714"
-             height="93.571426"
-             width="76.428574"
-             id="rect1902" /></flowRegion><flowPara
-           id="flowPara1904">Greetings!</flowPara><flowPara
-           id="flowPara1906" /><flowPara
-           id="flowPara1908">I am Mariam Abacha, the wife of former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
-    <g
-       id="g1966"
-       transform="translate(82,0.35715)">
-      <g
-         transform="translate(-77.85718,-140.0714)"
-         id="g1910">
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
-           id="path1912"
-           sodipodi:nodetypes="cccccc" />
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
-           id="path1914"
-           sodipodi:nodetypes="cccc" />
-      </g>
-      <flowRoot
-         transform="translate(-77.85718,-140.0714)"
-         style="font-size:8px;font-family:Times New Roman"
-         id="flowRoot1916"
-         xml:space="preserve"><flowRegion
-           id="flowRegion1918"><rect
-             style="font-size:8px;font-family:Times New Roman"
-             y="464.50504"
-             x="122.85714"
-             height="93.571426"
-             width="76.428574"
-             id="rect1920" /></flowRegion><flowPara
-           id="flowPara1922">Greetings!</flowPara><flowPara
-           id="flowPara1924" /><flowPara
-           id="flowPara1926">I am <flowSpan
-   style="font-style:italic;fill:red"
-   id="flowSpan3094">Shehu Musa Abacha, cousin to</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
-    <g
-       id="g1977"
-       transform="translate(81.99999,-0.35715)">
-      <g
-         transform="translate(83.57141,-139.3571)"
-         id="g1932">
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
-           id="path1934"
-           sodipodi:nodetypes="cccccc" />
-        <path
-           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
-           id="path1936"
-           sodipodi:nodetypes="cccc" />
-      </g>
-      <flowRoot
-         transform="translate(83.57141,-139.3571)"
-         style="font-size:8px;font-family:Times New Roman"
-         id="flowRoot1938"
-         xml:space="preserve"><flowRegion
-           id="flowRegion1940"><rect
-             style="font-size:8px;font-family:Times New Roman"
-             y="464.50504"
-             x="122.85714"
-             height="93.571426"
-             width="76.428574"
-             id="rect1942" /></flowRegion><flowPara
-           id="flowPara1944">Greetings!</flowPara><flowPara
-           id="flowPara1946" /><flowPara
-           id="flowPara1948">I am <flowSpan
-   style="font-style:italic;fill:red"
-   id="flowSpan3096">Alhaji Abba Abacha, son of</flowSpan> the former Nigerian dictator Sani Abacha. I am contacting you in confidence, and as a means of developing</flowPara></flowRoot>    </g>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 215.502,457.71933 L 196.35507,424.5765"
-       id="path1999"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g1988"
-       inkscape:connection-end="#g1966" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 277.06936,457.71933 L 296.21629,424.5765"
-       id="path2001"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g1988"
-       inkscape:connection-end="#g1977" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="302.42859"
-       y="515.08905"
-       id="text1905"><tspan
-         sodipodi:role="line"
-         id="tspan1907"
-         x="302.42859"
-         y="515.08905">Base version</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="45.57143"
-       y="374.1619"
-       id="text1917"><tspan
-         sodipodi:role="line"
-         id="tspan1919"
-         x="45.57143"
-         y="374.1619">Our changes</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="385.71429"
-       y="374.1619"
-       id="text1921"><tspan
-         sodipodi:role="line"
-         id="tspan1923"
-         x="385.71429"
-         y="374.1619">Their changes</tspan></text>
-  </g>
-</svg>
--- a/en/tour-merge-merge.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="tour-merge-merge.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path2973"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3066"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="247.53795"
-     inkscape:cy="871.05738"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="38"
-     inkscape:window-y="95" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2995"
-       width="94.285713"
-       height="20.714285"
-       x="532.85718"
-       y="203.0479" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="173.57143"
-       y="443.79074"
-       id="text2832"><tspan
-         sodipodi:role="line"
-         id="tspan2834"
-         x="173.57143"
-         y="443.79074" /></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2830"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="297.76227" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="311.38342"
-       id="text2824"><tspan
-         sodipodi:role="line"
-         id="tspan2826"
-         x="162.09892"
-         y="311.38342"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2862">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,343.63731 L 185.14286,319.47656"
-       id="path2900"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2863"
-       width="94.285713"
-       height="20.714285"
-       x="91.428574"
-       y="250.47656" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="116.09886"
-       y="264.56592"
-       id="text1965"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan1967"
-         x="116.09886"
-         y="264.56592"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1973">5</tspan>: ae13</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 173.95727,296.76228 L 149.75702,272.19085"
-       id="path1971"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2863"
-       inkscape:connection-start="#rect2830" />
-    <rect
-       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2911"
-       width="94.285995"
-       height="20.714283"
-       x="186.71414"
-       y="204.40514" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="210.81311"
-       y="218.02673"
-       id="text2913"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan2915"
-         x="210.81311"
-         y="218.02673"
-         style="font-family:Courier"><tspan
-   id="tspan1966"
-   style="font-weight:bold">6</tspan>: d2b5</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 191.06908,296.76228 L 227.93092,226.11942"
-       id="path2919"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2830" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="295.28571"
-       y="217.56711"
-       id="text2871"><tspan
-         sodipodi:role="line"
-         id="tspan2873"
-         x="295.28571"
-         y="217.56711">tip (and head)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="76"
-       y="264.91769"
-       id="text2875"><tspan
-         sodipodi:role="line"
-         id="tspan2877"
-         x="76"
-         y="264.91769"
-         style="text-align:end;text-anchor:end">head</tspan></text>
-    <rect
-       style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect1913"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="156.90514" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 144.22399,249.47657 L 179.49029,178.61943"
-       id="path1915"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2863"
-       inkscape:connection-end="#rect1913" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 222.20966,203.40514 L 196.79033,178.61943"
-       id="path1917"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2911"
-       inkscape:connection-end="#rect1913" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="166.16823"
-       y="168.52228"
-       id="text2806"><tspan
-         sodipodi:role="line"
-         id="tspan2808"
-         x="166.16823"
-         y="168.52228"
-         style="font-family:Courier">merge</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="246"
-       y="162.63338"
-       id="text2810"><tspan
-         sodipodi:role="line"
-         id="tspan2812"
-         x="246"
-         y="162.63338">working directory</tspan><tspan
-         sodipodi:role="line"
-         x="246"
-         y="177.63338"
-         id="tspan2814">during merge</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2816"
-       width="94.285713"
-       height="20.714285"
-       x="483.14636"
-       y="297.76227" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="507.24527"
-       y="311.38342"
-       id="text2818"><tspan
-         sodipodi:role="line"
-         id="tspan2820"
-         x="507.24527"
-         y="311.38342"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2822">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 530.28921,343.6373 L 530.28921,319.47655"
-       id="path2824"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2826"
-       width="94.285713"
-       height="20.714285"
-       x="436.57492"
-       y="250.47656" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="461.24484"
-       y="264.56613"
-       id="text2828"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan2830"
-         x="461.24484"
-         y="264.56613"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2832">5</tspan>: ae13</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 519.10362,296.76227 L 494.90337,272.19084"
-       id="path2834"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2836"
-       width="94.285995"
-       height="20.714283"
-       x="483.14001"
-       y="156.548" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="555.95911"
-       y="218.02698"
-       id="text2838"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan2840"
-         x="555.95911"
-         y="218.02698"
-         style="font-family:Courier"><tspan
-   id="tspan2842"
-   style="font-weight:bold">6</tspan>: d2b5</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 536.21543,296.76227 L 574.03453,224.76218"
-       id="path2844"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="594.43207"
-       y="169.78796"
-       id="text2846"><tspan
-         sodipodi:role="line"
-         id="tspan2848"
-         x="594.43207"
-         y="169.78796">tip</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 489.37034,249.47656 L 524.65575,178.26229"
-       id="path2856"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2836" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
-       d="M 567.85714,202.0479 L 542.42591,178.26229"
-       id="path2858"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2836"
-       inkscape:connection-start="#rect2995" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="504.54507"
-       y="170.39714"
-       id="text2860"><tspan
-         sodipodi:role="line"
-         id="tspan2863"
-         x="504.54507"
-         y="170.39714"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2997">7</tspan>: dba3</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="90.323105"
-       y="120.21933"
-       id="text2929"><tspan
-         sodipodi:role="line"
-         id="tspan2931"
-         x="90.323105"
-         y="120.21933"
-         style="font-weight:bold">Working directory during merge</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="435.35226"
-       y="120.21933"
-       id="text2937"><tspan
-         sodipodi:role="line"
-         id="tspan2939"
-         x="435.35226"
-         y="120.21933"
-         style="font-weight:bold">Repository after merge committed</tspan></text>
-  </g>
-</svg>
--- a/en/tour-merge-pull.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="tour-merge-pull.svg"
-   sodipodi:docbase="/home/bos/hg/hgbook/en">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path2973"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3066"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="233.63208"
-     inkscape:cy="832.54381"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="237"
-     inkscape:window-y="103" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="173.57143"
-       y="443.79074"
-       id="text2832"><tspan
-         sodipodi:role="line"
-         id="tspan2834"
-         x="173.57143"
-         y="443.79074" /></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect1878"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="479.50504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="493.12619"
-       id="text1872"><tspan
-         sodipodi:role="line"
-         id="tspan1874"
-         x="162.09892"
-         y="493.12619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1876">0</tspan>: 0a04</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2800"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="432.63004" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="446.25119"
-       id="text2794"><tspan
-         sodipodi:role="line"
-         id="tspan2796"
-         x="162.09892"
-         y="446.25119"
-         style="font-family:Courier"><tspan
-   id="tspan2868"
-   style="font-weight:bold">1</tspan>: 82e5</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2810"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="385.75504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="399.37619"
-       id="text2804"><tspan
-         sodipodi:role="line"
-         id="tspan2806"
-         x="162.09892"
-         y="399.37619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2866">2</tspan>: 057d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2820"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="338.88007" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="352.50122"
-       id="text2814"><tspan
-         sodipodi:role="line"
-         id="tspan2816"
-         x="162.09892"
-         y="352.50122"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2864">3</tspan>: ff5d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2830"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="292.00504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="305.62619"
-       id="text2824"><tspan
-         sodipodi:role="line"
-         id="tspan2826"
-         x="162.09892"
-         y="305.62619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2862">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,478.50504 L 185.14286,454.34432"
-       id="path2894"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,431.63004 L 185.14286,407.46932"
-       id="path2896"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,384.75504 L 185.14286,360.59435"
-       id="path2898"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,337.88007 L 185.14286,313.71932"
-       id="path2900"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2863"
-       width="94.285713"
-       height="20.714285"
-       x="91.428574"
-       y="244.71933" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="116.09886"
-       y="258.80865"
-       id="text1965"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan1967"
-         x="116.09886"
-         y="258.80865"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1973">5</tspan>: ae13</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 173.95727,291.00504 L 149.75702,266.43361"
-       id="path1971"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#rect2863"
-       inkscape:connection-start="#rect2830" />
-    <rect
-       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2911"
-       width="94.285995"
-       height="20.714283"
-       x="186.71414"
-       y="198.6479" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="210.81311"
-       y="212.26949"
-       id="text2913"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan2915"
-         x="210.81311"
-         y="212.26949"
-         style="font-family:Courier"><tspan
-   id="tspan1966"
-   style="font-weight:bold">6</tspan>: d2b5</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       d="M 191.06908,291.00504 L 227.93092,220.36218"
-       id="path2919"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#rect2830" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="295.28571"
-       y="211.80988"
-       id="text2871"><tspan
-         sodipodi:role="line"
-         id="tspan2873"
-         x="295.28571"
-         y="211.80988">tip (and head)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="76"
-       y="259.16046"
-       id="text2875"><tspan
-         sodipodi:role="line"
-         id="tspan2877"
-         x="76"
-         y="259.16046"
-         style="text-align:end;text-anchor:end">head</tspan></text>
-  </g>
-</svg>
--- a/en/tour-merge-sep-repos.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,466 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docname="tour-merge-sep-repos.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path2973"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path3066"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4"
-     inkscape:cx="307.20351"
-     inkscape:cy="716.87911"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="5"
-     inkscape:window-y="49" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="173.57143"
-       y="443.79074"
-       id="text2832"><tspan
-         sodipodi:role="line"
-         id="tspan2834"
-         x="173.57143"
-         y="443.79074" /></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect1878"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="479.50504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="493.12619"
-       id="text1872"><tspan
-         sodipodi:role="line"
-         id="tspan1874"
-         x="162.09892"
-         y="493.12619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1876">0</tspan>: 0a04</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2800"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="432.63004" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="446.25119"
-       id="text2794"><tspan
-         sodipodi:role="line"
-         id="tspan2796"
-         x="162.09892"
-         y="446.25119"
-         style="font-family:Courier"><tspan
-   id="tspan2868"
-   style="font-weight:bold">1</tspan>: 82e5</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2810"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="385.75504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="399.37619"
-       id="text2804"><tspan
-         sodipodi:role="line"
-         id="tspan2806"
-         x="162.09892"
-         y="399.37619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2866">2</tspan>: 057d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2820"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="338.88007" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="352.50122"
-       id="text2814"><tspan
-         sodipodi:role="line"
-         id="tspan2816"
-         x="162.09892"
-         y="352.50122"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2864">3</tspan>: ff5d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2830"
-       width="94.285713"
-       height="20.714285"
-       x="138"
-       y="292.00504" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09892"
-       y="305.62619"
-       id="text2824"><tspan
-         sodipodi:role="line"
-         id="tspan2826"
-         x="162.09892"
-         y="305.62619"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2862">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,478.50504 L 185.14286,454.34432"
-       id="path2894"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,431.63004 L 185.14286,407.46932"
-       id="path2896"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,384.75504 L 185.14286,360.59435"
-       id="path2898"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.14286,337.88007 L 185.14286,313.71932"
-       id="path2900"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect1963"
-       width="94.285995"
-       height="20.714283"
-       x="138"
-       y="245.18723" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="162.09877"
-       y="258.80865"
-       id="text1965"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan1967"
-         x="162.09877"
-         y="258.80865"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan1973">5</tspan>: ae13</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 185.143,291.06218 L 185.143,266.90143"
-       id="path1971"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="136.90039"
-       y="232.25546"
-       id="text2921"><tspan
-         sodipodi:role="line"
-         id="tspan2923"
-         x="136.90039"
-         y="232.25546">my-hello</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2863"
-       width="94.285713"
-       height="20.714285"
-       x="370.71414"
-       y="479.49289" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81305"
-       y="493.11404"
-       id="text2865"><tspan
-         sodipodi:role="line"
-         id="tspan2867"
-         x="394.81305"
-         y="493.11404"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2869">0</tspan>: 0a04</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2871"
-       width="94.285713"
-       height="20.714285"
-       x="370.71414"
-       y="432.61789" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81305"
-       y="446.23904"
-       id="text2873"><tspan
-         sodipodi:role="line"
-         id="tspan2875"
-         x="394.81305"
-         y="446.23904"
-         style="font-family:Courier"><tspan
-   id="tspan2877"
-   style="font-weight:bold">1</tspan>: 82e5</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2879"
-       width="94.285713"
-       height="20.714285"
-       x="370.71414"
-       y="385.74289" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81305"
-       y="399.36404"
-       id="text2881"><tspan
-         sodipodi:role="line"
-         id="tspan2883"
-         x="394.81305"
-         y="399.36404"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2885">2</tspan>: 057d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2887"
-       width="94.285713"
-       height="20.714285"
-       x="370.71414"
-       y="338.86792" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81305"
-       y="352.48907"
-       id="text2889"><tspan
-         sodipodi:role="line"
-         id="tspan2891"
-         x="394.81305"
-         y="352.48907"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2893">3</tspan>: ff5d</tspan></text>
-    <rect
-       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2895"
-       width="94.285713"
-       height="20.714285"
-       x="370.71414"
-       y="291.99289" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81305"
-       y="305.61404"
-       id="text2897"><tspan
-         sodipodi:role="line"
-         id="tspan2899"
-         x="394.81305"
-         y="305.61404"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2901">4</tspan>: b57f</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 417.85701,478.4929 L 417.85701,454.33218"
-       id="path2903"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 417.85701,431.6179 L 417.85701,407.45718"
-       id="path2905"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 417.85701,384.7429 L 417.85701,360.58221"
-       id="path2907"
-       inkscape:connector-type="polyline" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 417.85701,337.86793 L 417.85701,313.70718"
-       id="path2909"
-       inkscape:connector-type="polyline" />
-    <rect
-       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect2911"
-       width="94.285995"
-       height="20.714283"
-       x="370.71414"
-       y="245.17511" />
-    <text
-       xml:space="preserve"
-       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
-       x="394.81274"
-       y="258.79678"
-       id="text2913"
-       transform="scale(1.000002,0.999998)"><tspan
-         sodipodi:role="line"
-         id="tspan2915"
-         x="394.81274"
-         y="258.79678"
-         style="font-family:Courier"><tspan
-   style="font-weight:bold"
-   id="tspan2917">5</tspan>: d2b5</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-       d="M 417.85715,291.05004 L 417.85715,266.88929"
-       id="path2919"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="369.61453"
-       y="232.25546"
-       id="text2925"><tspan
-         sodipodi:role="line"
-         id="tspan2927"
-         x="369.61453"
-         y="232.25546">my-new-hello</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="300.54352"
-       y="252.12723"
-       id="text2933"><tspan
-         sodipodi:role="line"
-         id="tspan2935"
-         x="300.54352"
-         y="252.12723"
-         style="text-align:center;text-anchor:middle">newest changes</tspan><tspan
-         sodipodi:role="line"
-         x="300.54352"
-         y="267.12723"
-         style="text-align:center;text-anchor:middle"
-         id="tspan3132">differ</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="262.15436"
-       y="398.37112"
-       id="text2929"><tspan
-         sodipodi:role="line"
-         x="262.15436"
-         y="398.37112"
-         id="tspan3013"
-         style="text-align:start;text-anchor:start">common history</tspan></text>
-    <g
-       id="g3107"
-       transform="translate(0,0.855744)">
-      <path
-         id="path3101"
-         d="M 300.35713,381.29075 L 300.35713,304.50504"
-         style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" />
-      <path
-         id="path3105"
-         d="M 291.07142,301.64789 L 309.28571,301.64789"
-         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
-    </g>
-    <path
-       style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
-       d="M 300.53571,486.38926 L 300.53571,409.60355"
-       id="path3113" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 291.25,488.49641 L 309.46429,488.49641"
-       id="path3115" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="480.71429"
-       y="250.91507"
-       id="text1949"><tspan
-         sodipodi:role="line"
-         id="tspan1951"
-         x="480.71429"
-         y="250.91507"
-         style="text-align:start;text-anchor:start">head revision</tspan><tspan
-         sodipodi:role="line"
-         x="480.71429"
-         y="265.91507"
-         id="tspan1953"
-         style="text-align:start;text-anchor:start">(has no children)</tspan></text>
-  </g>
-</svg>
--- a/en/tour-merge.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-\chapter{A tour of Mercurial: merging work}
-\label{chap:tour-merge}
-
-We've now covered cloning a repository, making changes in a
-repository, and pulling or pushing changes from one repository into
-another.  Our next step is \emph{merging} changes from separate
-repositories.
-
-\section{Merging streams of work}
-
-Merging is a fundamental part of working with a distributed revision
-control tool.
-\begin{itemize}
-\item Alice and Bob each have a personal copy of a repository for a
-  project they're collaborating on.  Alice fixes a bug in her
-  repository; Bob adds a new feature in his.  They want the shared
-  repository to contain both the bug fix and the new feature.
-\item I frequently work on several different tasks for a single
-  project at once, each safely isolated in its own repository.
-  Working this way means that I often need to merge one piece of my
-  own work with another.
-\end{itemize}
-
-Because merging is such a common thing to need to do, Mercurial makes
-it easy.  Let's walk through the process.  We'll begin by cloning yet
-another repository (see how often they spring up?) and making a change
-in it.
-\interaction{tour.merge.clone}
-We should now have two copies of \filename{hello.c} with different
-contents.  The histories of the two repositories have also diverged,
-as illustrated in figure~\ref{fig:tour-merge:sep-repos}.
-\interaction{tour.merge.cat}
-
-\begin{figure}[ht]
-  \centering
-  \grafix{tour-merge-sep-repos}
-  \caption{Divergent recent histories of the \dirname{my-hello} and
-    \dirname{my-new-hello} repositories}
-  \label{fig:tour-merge:sep-repos}
-\end{figure}
-
-We already know that pulling changes from our \dirname{my-hello}
-repository will have no effect on the working directory.
-\interaction{tour.merge.pull}
-However, the \hgcmd{pull} command says something about ``heads''.  
-
-\subsection{Head changesets}
-
-A head is a change that has no descendants, or children, as they're
-also known.  The tip revision is thus a head, because the newest
-revision in a repository doesn't have any children, but a repository
-can contain more than one head.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{tour-merge-pull}
-  \caption{Repository contents after pulling from \dirname{my-hello} into
-    \dirname{my-new-hello}}
-  \label{fig:tour-merge:pull}
-\end{figure}
-
-In figure~\ref{fig:tour-merge:pull}, you can see the effect of the
-pull from \dirname{my-hello} into \dirname{my-new-hello}.  The history
-that was already present in \dirname{my-new-hello} is untouched, but a
-new revision has been added.  By referring to
-figure~\ref{fig:tour-merge:sep-repos}, we can see that the
-\emph{changeset ID} remains the same in the new repository, but the
-\emph{revision number} has changed.  (This, incidentally, is a fine
-example of why it's not safe to use revision numbers when discussing
-changesets.)  We can view the heads in a repository using the
-\hgcmd{heads} command.
-\interaction{tour.merge.heads}
-
-\subsection{Performing the merge}
-
-What happens if we try to use the normal \hgcmd{update} command to
-update to the new tip?
-\interaction{tour.merge.update}
-Mercurial is telling us that the \hgcmd{update} command won't do a
-merge; it won't update the working directory when it thinks we might
-be wanting to do a merge, unless we force it to do so.  Instead, we
-use the \hgcmd{merge} command to merge the two heads.
-\interaction{tour.merge.merge}
-
-\begin{figure}[ht]
-  \centering
-  \grafix{tour-merge-merge}
-  \caption{Working directory and repository during merge, and
-    following commit}
-  \label{fig:tour-merge:merge}
-\end{figure}
-
-This updates the working directory so that it contains changes from
-\emph{both} heads, which is reflected in both the output of
-\hgcmd{parents} and the contents of \filename{hello.c}.
-\interaction{tour.merge.parents}
-
-\subsection{Committing the results of the merge}
-
-Whenever we've done a merge, \hgcmd{parents} will display two parents
-until we \hgcmd{commit} the results of the merge.
-\interaction{tour.merge.commit}
-We now have a new tip revision; notice that it has \emph{both} of
-our former heads as its parents.  These are the same revisions that
-were previously displayed by \hgcmd{parents}.
-\interaction{tour.merge.tip}
-In figure~\ref{fig:tour-merge:merge}, you can see a representation of
-what happens to the working directory during the merge, and how this
-affects the repository when the commit happens.  During the merge, the
-working directory has two parent changesets, and these become the
-parents of the new changeset.
-
-\section{Merging conflicting changes}
-
-Most merges are simple affairs, but sometimes you'll find yourself
-merging changes where each modifies the same portions of the same
-files.  Unless both modifications are identical, this results in a
-\emph{conflict}, where you have to decide how to reconcile the
-different changes into something coherent.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{tour-merge-conflict}
-  \caption{Conflicting changes to a document}
-  \label{fig:tour-merge:conflict}
-\end{figure}
-
-Figure~\ref{fig:tour-merge:conflict} illustrates an instance of two
-conflicting changes to a document.  We started with a single version
-of the file; then we made some changes; while someone else made
-different changes to the same text.  Our task in resolving the
-conflicting changes is to decide what the file should look like.
-
-Mercurial doesn't have a built-in facility for handling conflicts.
-Instead, it runs an external program called \command{hgmerge}.  This
-is a shell script that is bundled with Mercurial; you can change it to
-behave however you please.  What it does by default is try to find one
-of several different merging tools that are likely to be installed on
-your system.  It first tries a few fully automatic merging tools; if
-these don't succeed (because the resolution process requires human
-guidance) or aren't present, the script tries a few different
-graphical merging tools.
-
-It's also possible to get Mercurial to run another program or script
-instead of \command{hgmerge}, by setting the \envar{HGMERGE}
-environment variable to the name of your preferred program.
-
-\subsection{Using a graphical merge tool}
-
-My preferred graphical merge tool is \command{kdiff3}, which I'll use
-to describe the features that are common to graphical file merging
-tools.  You can see a screenshot of \command{kdiff3} in action in
-figure~\ref{fig:tour-merge:kdiff3}.  The kind of merge it is
-performing is called a \emph{three-way merge}, because there are three
-different versions of the file of interest to us.  The tool thus
-splits the upper portion of the window into three panes:
-\begin{itemize}
-\item At the left is the \emph{base} version of the file, i.e.~the
-  most recent version from which the two versions we're trying to
-  merge are descended.
-\item In the middle is ``our'' version of the file, with the contents
-  that we modified.
-\item On the right is ``their'' version of the file, the one that
-  from the changeset that we're trying to merge with.
-\end{itemize}
-In the pane below these is the current \emph{result} of the merge.
-Our task is to replace all of the red text, which indicates unresolved
-conflicts, with some sensible merger of the ``ours'' and ``theirs''
-versions of the file.
-
-All four of these panes are \emph{locked together}; if we scroll
-vertically or horizontally in any of them, the others are updated to
-display the corresponding sections of their respective files.
-
-\begin{figure}[ht]
-  \centering
-  \grafix{kdiff3}
-  \caption{Using \command{kdiff3} to merge versions of a file}
-  \label{fig:tour-merge:kdiff3}
-\end{figure}
-
-For each conflicting portion of the file, we can choose to resolve
-the conflict using some combination of text from the base version,
-ours, or theirs.  We can also manually edit the merged file at any
-time, in case we need to make further modifications.
-
-There are \emph{many} file merging tools available, too many to cover
-here.  They vary in which platforms they are available for, and in
-their particular strengths and weaknesses.  Most are tuned for merging
-files containing plain text, while a few are aimed at specialised file
-formats (generally XML).
-
-\subsection{A worked example}
-
-In this example, we will reproduce the file modification history of
-figure~\ref{fig:tour-merge:conflict} above.  Let's begin by creating a
-repository with a base version of our document.
-\interaction{tour-merge-conflict.wife}
-We'll clone the repository and make a change to the file.
-\interaction{tour-merge-conflict.cousin}
-And another clone, to simulate someone else making a change to the
-file.  (This hints at the idea that it's not all that unusual to merge
-with yourself when you isolate tasks in separate repositories, and
-indeed to find and resolve conflicts while doing so.)
-\interaction{tour-merge-conflict.son}
-Having created two different versions of the file, we'll set up an
-environment suitable for running our merge.
-\interaction{tour-merge-conflict.pull}
-
-In this example, I won't use Mercurial's normal \command{hgmerge}
-program to do the merge, because it would drop my nice automated
-example-running tool into a graphical user interface.  Instead, I'll
-set \envar{HGMERGE} to tell Mercurial to use the non-interactive
-\command{merge} command.  This is bundled with many Unix-like systems.
-If you're following this example on your computer, don't bother
-setting \envar{HGMERGE}.
-\interaction{tour-merge-conflict.merge}
-Because \command{merge} can't resolve the conflicting changes, it
-leaves \emph{merge markers} inside the file that has conflicts,
-indicating which lines have conflicts, and whether they came from our
-version of the file or theirs.
-
-Mercurial can tell from the way \command{merge} exits that it wasn't
-able to merge successfully, so it tells us what commands we'll need to
-run if we want to redo the merging operation.  This could be useful
-if, for example, we were running a graphical merge tool and quit
-because we were confused or realised we had made a mistake.
-
-If automatic or manual merges fail, there's nothing to prevent us from
-``fixing up'' the affected files ourselves, and committing the results
-of our merge:
-\interaction{tour-merge-conflict.commit}
-
-\section{Simplifying the pull-merge-commit sequence}
-\label{sec:tour-merge:fetch}
-
-The process of merging changes as outlined above is straightforward,
-but requires running three commands in sequence.
-\begin{codesample2}
-  hg pull
-  hg merge
-  hg commit -m 'Merged remote changes'
-\end{codesample2}
-In the case of the final commit, you also need to enter a commit
-message, which is almost always going to be a piece of uninteresting
-``boilerplate'' text.
-
-It would be nice to reduce the number of steps needed, if this were
-possible.  Indeed, Mercurial is distributed with an extension called
-\hgext{fetch} that does just this.
-
-Mercurial provides a flexible extension mechanism that lets people
-extend its functionality, while keeping the core of Mercurial small
-and easy to deal with.  Some extensions add new commands that you can
-use from the command line, while others work ``behind the scenes,''
-for example adding capabilities to the server.
-
-The \hgext{fetch} extension adds a new command called, not
-surprisingly, \hgcmd{fetch}.  This extension acts as a combination of
-\hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}.  It begins by pulling
-changes from another repository into the current repository.  If it
-finds that the changes added a new head to the repository, it begins a
-merge, then commits the result of the merge with an
-automatically-generated commit message.  If no new heads were added,
-it updates the working directory to the new tip changeset.
-
-Enabling the \hgext{fetch} extension is easy.  Edit your
-\sfilename{.hgrc}, and either go to the \rcsection{extensions} section
-or create an \rcsection{extensions} section.  Then add a line that
-simply reads ``\Verb+fetch +''.
-\begin{codesample2}
-  [extensions]
-  fetch =
-\end{codesample2}
-(Normally, on the right-hand side of the ``\texttt{=}'' would appear
-the location of the extension, but since the \hgext{fetch} extension
-is in the standard distribution, Mercurial knows where to search for
-it.)
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/undo-manual-merge.dot	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-digraph undo_manual {
-	"first change" -> "second change";
-	"second change" -> "third change";
-	backout [label="back out\nsecond change", shape=box];
-	"second change" -> backout;
-	"third change" -> "manual\nmerge";
-	backout -> "manual\nmerge";
-}
--- a/en/undo-manual.dot	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-digraph undo_manual {
-	"first change" -> "second change";
-	"second change" -> "third change";
-	backout [label="back out\nsecond change", shape=box];
-	"second change" -> backout;
-}
--- a/en/undo-non-tip.dot	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-digraph undo_non_tip {
-	"first change" -> "second change";
-	"second change" -> "third change";
-	backout [label="back out\nsecond change", shape=box];
-	"second change" -> backout;
-	merge [label="automated\nmerge", shape=box];
-	"third change" -> merge;
-	backout -> merge;
-}
--- a/en/undo-simple.dot	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-digraph undo_simple {
-	"first change" -> "second change";
-	"second change" -> "back out\nsecond change";
-}
--- a/en/undo.tex	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,763 +0,0 @@
-\chapter{Finding and fixing your mistakes}
-\label{chap:undo}
-
-To err might be human, but to really handle the consequences well
-takes a top-notch revision control system.  In this chapter, we'll
-discuss some of the techniques you can use when you find that a
-problem has crept into your project.  Mercurial has some highly
-capable features that will help you to isolate the sources of
-problems, and to handle them appropriately.
-
-\section{Erasing local history}
-
-\subsection{The accidental commit}
-
-I have the occasional but persistent problem of typing rather more
-quickly than I can think, which sometimes results in me committing a
-changeset that is either incomplete or plain wrong.  In my case, the
-usual kind of incomplete changeset is one in which I've created a new
-source file, but forgotten to \hgcmd{add} it.  A ``plain wrong''
-changeset is not as common, but no less annoying.
-
-\subsection{Rolling back a transaction}
-\label{sec:undo:rollback}
-
-In section~\ref{sec:concepts:txn}, I mentioned that Mercurial treats
-each modification of a repository as a \emph{transaction}.  Every time
-you commit a changeset or pull changes from another repository,
-Mercurial remembers what you did.  You can undo, or \emph{roll back},
-exactly one of these actions using the \hgcmd{rollback} command.  (See
-section~\ref{sec:undo:rollback-after-push} for an important caveat
-about the use of this command.)
-
-Here's a mistake that I often find myself making: committing a change
-in which I've created a new file, but forgotten to \hgcmd{add} it.
-\interaction{rollback.commit}
-Looking at the output of \hgcmd{status} after the commit immediately
-confirms the error.
-\interaction{rollback.status}
-The commit captured the changes to the file \filename{a}, but not the
-new file \filename{b}.  If I were to push this changeset to a
-repository that I shared with a colleague, the chances are high that
-something in \filename{a} would refer to \filename{b}, which would not
-be present in their repository when they pulled my changes.  I would
-thus become the object of some indignation.
-
-However, luck is with me---I've caught my error before I pushed the
-changeset.  I use the \hgcmd{rollback} command, and Mercurial makes
-that last changeset vanish.
-\interaction{rollback.rollback}
-Notice that the changeset is no longer present in the repository's
-history, and the working directory once again thinks that the file
-\filename{a} is modified.  The commit and rollback have left the
-working directory exactly as it was prior to the commit; the changeset
-has been completely erased.  I can now safely \hgcmd{add} the file
-\filename{b}, and rerun my commit.
-\interaction{rollback.add}
-
-\subsection{The erroneous pull}
-
-It's common practice with Mercurial to maintain separate development
-branches of a project in different repositories.  Your development
-team might have one shared repository for your project's ``0.9''
-release, and another, containing different changes, for the ``1.0''
-release.
-
-Given this, you can imagine that the consequences could be messy if
-you had a local ``0.9'' repository, and accidentally pulled changes
-from the shared ``1.0'' repository into it.  At worst, you could be
-paying insufficient attention, and push those changes into the shared
-``0.9'' tree, confusing your entire team (but don't worry, we'll
-return to this horror scenario later).  However, it's more likely that
-you'll notice immediately, because Mercurial will display the URL it's
-pulling from, or you will see it pull a suspiciously large number of
-changes into the repository.
-
-The \hgcmd{rollback} command will work nicely to expunge all of the
-changesets that you just pulled.  Mercurial groups all changes from
-one \hgcmd{pull} into a single transaction, so one \hgcmd{rollback} is
-all you need to undo this mistake.
-
-\subsection{Rolling back is useless once you've pushed}
-\label{sec:undo:rollback-after-push}
-
-The value of the \hgcmd{rollback} command drops to zero once you've
-pushed your changes to another repository.  Rolling back a change
-makes it disappear entirely, but \emph{only} in the repository in
-which you perform the \hgcmd{rollback}.  Because a rollback eliminates
-history, there's no way for the disappearance of a change to propagate
-between repositories.
-
-If you've pushed a change to another repository---particularly if it's
-a shared repository---it has essentially ``escaped into the wild,''
-and you'll have to recover from your mistake in a different way.  What
-will happen if you push a changeset somewhere, then roll it back, then
-pull from the repository you pushed to, is that the changeset will
-reappear in your repository.
-
-(If you absolutely know for sure that the change you want to roll back
-is the most recent change in the repository that you pushed to,
-\emph{and} you know that nobody else could have pulled it from that
-repository, you can roll back the changeset there, too, but you really
-should really not rely on this working reliably.  If you do this,
-sooner or later a change really will make it into a repository that
-you don't directly control (or have forgotten about), and come back to
-bite you.)
-
-\subsection{You can only roll back once}
-
-Mercurial stores exactly one transaction in its transaction log; that
-transaction is the most recent one that occurred in the repository.
-This means that you can only roll back one transaction.  If you expect
-to be able to roll back one transaction, then its predecessor, this is
-not the behaviour you will get.
-\interaction{rollback.twice}
-Once you've rolled back one transaction in a repository, you can't
-roll back again in that repository until you perform another commit or
-pull.
-
-\section{Reverting the mistaken change}
-
-If you make a modification to a file, and decide that you really
-didn't want to change the file at all, and you haven't yet committed
-your changes, the \hgcmd{revert} command is the one you'll need.  It
-looks at the changeset that's the parent of the working directory, and
-restores the contents of the file to their state as of that changeset.
-(That's a long-winded way of saying that, in the normal case, it
-undoes your modifications.)
-
-Let's illustrate how the \hgcmd{revert} command works with yet another
-small example.  We'll begin by modifying a file that Mercurial is
-already tracking.
-\interaction{daily.revert.modify}
-If we don't want that change, we can simply \hgcmd{revert} the file.
-\interaction{daily.revert.unmodify}
-The \hgcmd{revert} command provides us with an extra degree of safety
-by saving our modified file with a \filename{.orig} extension.
-\interaction{daily.revert.status}
-
-Here is a summary of the cases that the \hgcmd{revert} command can
-deal with.  We will describe each of these in more detail in the
-section that follows.
-\begin{itemize}
-\item If you modify a file, it will restore the file to its unmodified
-  state.
-\item If you \hgcmd{add} a file, it will undo the ``added'' state of
-  the file, but leave the file itself untouched.
-\item If you delete a file without telling Mercurial, it will restore
-  the file to its unmodified contents.
-\item If you use the \hgcmd{remove} command to remove a file, it will
-  undo the ``removed'' state of the file, and restore the file to its
-  unmodified contents.
-\end{itemize}
-
-\subsection{File management errors}
-\label{sec:undo:mgmt}
-
-The \hgcmd{revert} command is useful for more than just modified
-files.  It lets you reverse the results of all of Mercurial's file
-management commands---\hgcmd{add}, \hgcmd{remove}, and so on.
-
-If you \hgcmd{add} a file, then decide that in fact you don't want
-Mercurial to track it, use \hgcmd{revert} to undo the add.  Don't
-worry; Mercurial will not modify the file in any way.  It will just
-``unmark'' the file.
-\interaction{daily.revert.add}
-
-Similarly, if you ask Mercurial to \hgcmd{remove} a file, you can use
-\hgcmd{revert} to restore it to the contents it had as of the parent
-of the working directory.
-\interaction{daily.revert.remove}
-This works just as well for a file that you deleted by hand, without
-telling Mercurial (recall that in Mercurial terminology, this kind of
-file is called ``missing'').
-\interaction{daily.revert.missing}
-
-If you revert a \hgcmd{copy}, the copied-to file remains in your
-working directory afterwards, untracked.  Since a copy doesn't affect
-the copied-from file in any way, Mercurial doesn't do anything with
-the copied-from file.
-\interaction{daily.revert.copy}
-
-\subsubsection{A slightly special case: reverting a rename}
-
-If you \hgcmd{rename} a file, there is one small detail that
-you should remember.  When you \hgcmd{revert} a rename, it's not
-enough to provide the name of the renamed-to file, as you can see
-here.
-\interaction{daily.revert.rename}
-As you can see from the output of \hgcmd{status}, the renamed-to file
-is no longer identified as added, but the renamed-\emph{from} file is
-still removed!  This is counter-intuitive (at least to me), but at
-least it's easy to deal with.
-\interaction{daily.revert.rename-orig}
-So remember, to revert a \hgcmd{rename}, you must provide \emph{both}
-the source and destination names.  
-
-(By the way, if you rename a file, then modify the renamed-to file,
-then revert both components of the rename, when Mercurial restores the
-file that was removed as part of the rename, it will be unmodified.
-If you need the modifications in the renamed-to file to show up in the
-renamed-from file, don't forget to copy them over.)
-
-These fiddly aspects of reverting a rename arguably constitute a small
-bug in Mercurial.
-
-\section{Dealing with committed changes}
-
-Consider a case where you have committed a change $a$, and another
-change $b$ on top of it; you then realise that change $a$ was
-incorrect.  Mercurial lets you ``back out'' an entire changeset
-automatically, and building blocks that let you reverse part of a
-changeset by hand.
-
-Before you read this section, here's something to keep in mind: the
-\hgcmd{backout} command undoes changes by \emph{adding} history, not
-by modifying or erasing it.  It's the right tool to use if you're
-fixing bugs, but not if you're trying to undo some change that has
-catastrophic consequences.  To deal with those, see
-section~\ref{sec:undo:aaaiiieee}.
-
-\subsection{Backing out a changeset}
-
-The \hgcmd{backout} command lets you ``undo'' the effects of an entire
-changeset in an automated fashion.  Because Mercurial's history is
-immutable, this command \emph{does not} get rid of the changeset you
-want to undo.  Instead, it creates a new changeset that
-\emph{reverses} the effect of the to-be-undone changeset.
-
-The operation of the \hgcmd{backout} command is a little intricate, so
-let's illustrate it with some examples.  First, we'll create a
-repository with some simple changes.
-\interaction{backout.init}
-
-The \hgcmd{backout} command takes a single changeset ID as its
-argument; this is the changeset to back out.  Normally,
-\hgcmd{backout} will drop you into a text editor to write a commit
-message, so you can record why you're backing the change out.  In this
-example, we provide a commit message on the command line using the
-\hgopt{backout}{-m} option.
-
-\subsection{Backing out the tip changeset}
-
-We're going to start by backing out the last changeset we committed.
-\interaction{backout.simple}
-You can see that the second line from \filename{myfile} is no longer
-present.  Taking a look at the output of \hgcmd{log} gives us an idea
-of what the \hgcmd{backout} command has done.
-\interaction{backout.simple.log}
-Notice that the new changeset that \hgcmd{backout} has created is a
-child of the changeset we backed out.  It's easier to see this in
-figure~\ref{fig:undo:backout}, which presents a graphical view of the
-change history.  As you can see, the history is nice and linear.
-
-\begin{figure}[htb]
-  \centering
-  \grafix{undo-simple}
-  \caption{Backing out a change using the \hgcmd{backout} command}
-  \label{fig:undo:backout}
-\end{figure}
-
-\subsection{Backing out a non-tip change}
-
-If you want to back out a change other than the last one you
-committed, pass the \hgopt{backout}{--merge} option to the
-\hgcmd{backout} command.
-\interaction{backout.non-tip.clone}
-This makes backing out any changeset a ``one-shot'' operation that's
-usually simple and fast.
-\interaction{backout.non-tip.backout}
-
-If you take a look at the contents of \filename{myfile} after the
-backout finishes, you'll see that the first and third changes are
-present, but not the second.
-\interaction{backout.non-tip.cat}
-
-As the graphical history in figure~\ref{fig:undo:backout-non-tip}
-illustrates, Mercurial actually commits \emph{two} changes in this
-kind of situation (the box-shaped nodes are the ones that Mercurial
-commits automatically).  Before Mercurial begins the backout process,
-it first remembers what the current parent of the working directory
-is.  It then backs out the target changeset, and commits that as a
-changeset.  Finally, it merges back to the previous parent of the
-working directory, and commits the result of the merge.
-
-\begin{figure}[htb]
-  \centering
-  \grafix{undo-non-tip}
-  \caption{Automated backout of a non-tip change using the \hgcmd{backout} command}
-  \label{fig:undo:backout-non-tip}
-\end{figure}
-
-The result is that you end up ``back where you were'', only with some
-extra history that undoes the effect of the changeset you wanted to
-back out.
-
-\subsubsection{Always use the \hgopt{backout}{--merge} option}
-
-In fact, since the \hgopt{backout}{--merge} option will do the ``right
-thing'' whether or not the changeset you're backing out is the tip
-(i.e.~it won't try to merge if it's backing out the tip, since there's
-no need), you should \emph{always} use this option when you run the
-\hgcmd{backout} command.
-
-\subsection{Gaining more control of the backout process}
-
-While I've recommended that you always use the
-\hgopt{backout}{--merge} option when backing out a change, the
-\hgcmd{backout} command lets you decide how to merge a backout
-changeset.  Taking control of the backout process by hand is something
-you will rarely need to do, but it can be useful to understand what
-the \hgcmd{backout} command is doing for you automatically.  To
-illustrate this, let's clone our first repository, but omit the
-backout change that it contains.
-
-\interaction{backout.manual.clone}
-As with our earlier example, We'll commit a third changeset, then back
-out its parent, and see what happens.
-\interaction{backout.manual.backout} 
-Our new changeset is again a descendant of the changeset we backout
-out; it's thus a new head, \emph{not} a descendant of the changeset
-that was the tip.  The \hgcmd{backout} command was quite explicit in
-telling us this.
-\interaction{backout.manual.log}
-
-Again, it's easier to see what has happened by looking at a graph of
-the revision history, in figure~\ref{fig:undo:backout-manual}.  This
-makes it clear that when we use \hgcmd{backout} to back out a change
-other than the tip, Mercurial adds a new head to the repository (the
-change it committed is box-shaped).
-
-\begin{figure}[htb]
-  \centering
-  \grafix{undo-manual}
-  \caption{Backing out a change using the \hgcmd{backout} command}
-  \label{fig:undo:backout-manual}
-\end{figure}
-
-After the \hgcmd{backout} command has completed, it leaves the new
-``backout'' changeset as the parent of the working directory.
-\interaction{backout.manual.parents}
-Now we have two isolated sets of changes.
-\interaction{backout.manual.heads}
-
-Let's think about what we expect to see as the contents of
-\filename{myfile} now.  The first change should be present, because
-we've never backed it out.  The second change should be missing, as
-that's the change we backed out.  Since the history graph shows the
-third change as a separate head, we \emph{don't} expect to see the
-third change present in \filename{myfile}.
-\interaction{backout.manual.cat}
-To get the third change back into the file, we just do a normal merge
-of our two heads.
-\interaction{backout.manual.merge}
-Afterwards, the graphical history of our repository looks like
-figure~\ref{fig:undo:backout-manual-merge}.
-
-\begin{figure}[htb]
-  \centering
-  \grafix{undo-manual-merge}
-  \caption{Manually merging a backout change}
-  \label{fig:undo:backout-manual-merge}
-\end{figure}
-
-\subsection{Why \hgcmd{backout} works as it does}
-
-Here's a brief description of how the \hgcmd{backout} command works.
-\begin{enumerate}
-\item It ensures that the working directory is ``clean'', i.e.~that
-  the output of \hgcmd{status} would be empty.
-\item It remembers the current parent of the working directory.  Let's
-  call this changeset \texttt{orig}
-\item It does the equivalent of a \hgcmd{update} to sync the working
-  directory to the changeset you want to back out.  Let's call this
-  changeset \texttt{backout}
-\item It finds the parent of that changeset.  Let's call that
-  changeset \texttt{parent}.
-\item For each file that the \texttt{backout} changeset affected, it
-  does the equivalent of a \hgcmdargs{revert}{-r parent} on that file,
-  to restore it to the contents it had before that changeset was
-  committed.
-\item It commits the result as a new changeset.  This changeset has
-  \texttt{backout} as its parent.
-\item If you specify \hgopt{backout}{--merge} on the command line, it
-  merges with \texttt{orig}, and commits the result of the merge.
-\end{enumerate}
-
-An alternative way to implement the \hgcmd{backout} command would be
-to \hgcmd{export} the to-be-backed-out changeset as a diff, then use
-the \cmdopt{patch}{--reverse} option to the \command{patch} command to
-reverse the effect of the change without fiddling with the working
-directory.  This sounds much simpler, but it would not work nearly as
-well.
-
-The reason that \hgcmd{backout} does an update, a commit, a merge, and
-another commit is to give the merge machinery the best chance to do a
-good job when dealing with all the changes \emph{between} the change
-you're backing out and the current tip.  
-
-If you're backing out a changeset that's~100 revisions back in your
-project's history, the chances that the \command{patch} command will
-be able to apply a reverse diff cleanly are not good, because
-intervening changes are likely to have ``broken the context'' that
-\command{patch} uses to determine whether it can apply a patch (if
-this sounds like gibberish, see \ref{sec:mq:patch} for a
-discussion of the \command{patch} command).  Also, Mercurial's merge
-machinery will handle files and directories being renamed, permission
-changes, and modifications to binary files, none of which
-\command{patch} can deal with.
-
-\section{Changes that should never have been}
-\label{sec:undo:aaaiiieee}
-
-Most of the time, the \hgcmd{backout} command is exactly what you need
-if you want to undo the effects of a change.  It leaves a permanent
-record of exactly what you did, both when committing the original
-changeset and when you cleaned up after it.
-
-On rare occasions, though, you may find that you've committed a change
-that really should not be present in the repository at all.  For
-example, it would be very unusual, and usually considered a mistake,
-to commit a software project's object files as well as its source
-files.  Object files have almost no intrinsic value, and they're
-\emph{big}, so they increase the size of the repository and the amount
-of time it takes to clone or pull changes.
-
-Before I discuss the options that you have if you commit a ``brown
-paper bag'' change (the kind that's so bad that you want to pull a
-brown paper bag over your head), let me first discuss some approaches
-that probably won't work.
-
-Since Mercurial treats history as accumulative---every change builds
-on top of all changes that preceded it---you generally can't just make
-disastrous changes disappear.  The one exception is when you've just
-committed a change, and it hasn't been pushed or pulled into another
-repository.  That's when you can safely use the \hgcmd{rollback}
-command, as I detailed in section~\ref{sec:undo:rollback}.
-
-After you've pushed a bad change to another repository, you
-\emph{could} still use \hgcmd{rollback} to make your local copy of the
-change disappear, but it won't have the consequences you want.  The
-change will still be present in the remote repository, so it will
-reappear in your local repository the next time you pull.
-
-If a situation like this arises, and you know which repositories your
-bad change has propagated into, you can \emph{try} to get rid of the
-changeefrom \emph{every} one of those repositories.  This is, of
-course, not a satisfactory solution: if you miss even a single
-repository while you're expunging, the change is still ``in the
-wild'', and could propagate further.
-
-If you've committed one or more changes \emph{after} the change that
-you'd like to see disappear, your options are further reduced.
-Mercurial doesn't provide a way to ``punch a hole'' in history,
-leaving changesets intact.
-
-XXX This needs filling out.  The \texttt{hg-replay} script in the
-\texttt{examples} directory works, but doesn't handle merge
-changesets.  Kind of an important omission.
-
-\subsection{Protect yourself from ``escaped'' changes}
-
-If you've committed some changes to your local repository and they've
-been pushed or pulled somewhere else, this isn't necessarily a
-disaster.  You can protect yourself ahead of time against some classes
-of bad changeset.  This is particularly easy if your team usually
-pulls changes from a central repository.
-
-By configuring some hooks on that repository to validate incoming
-changesets (see chapter~\ref{chap:hook}), you can automatically
-prevent some kinds of bad changeset from being pushed to the central
-repository at all.  With such a configuration in place, some kinds of
-bad changeset will naturally tend to ``die out'' because they can't
-propagate into the central repository.  Better yet, this happens
-without any need for explicit intervention.
-
-For instance, an incoming change hook that verifies that a changeset
-will actually compile can prevent people from inadvertantly ``breaking
-the build''.
-
-\section{Finding the source of a bug}
-\label{sec:undo:bisect}
-
-While it's all very well to be able to back out a changeset that
-introduced a bug, this requires that you know which changeset to back
-out.  Mercurial provides an invaluable command, called
-\hgcmd{bisect}, that helps you to automate this process and accomplish
-it very efficiently.
-
-The idea behind the \hgcmd{bisect} command is that a changeset has
-introduced some change of behaviour that you can identify with a
-simple binary test.  You don't know which piece of code introduced the
-change, but you know how to test for the presence of the bug.  The
-\hgcmd{bisect} command uses your test to direct its search for the
-changeset that introduced the code that caused the bug.
-
-Here are a few scenarios to help you understand how you might apply
-this command.
-\begin{itemize}
-\item The most recent version of your software has a bug that you
-  remember wasn't present a few weeks ago, but you don't know when it
-  was introduced.  Here, your binary test checks for the presence of
-  that bug.
-\item You fixed a bug in a rush, and now it's time to close the entry
-  in your team's bug database.  The bug database requires a changeset
-  ID when you close an entry, but you don't remember which changeset
-  you fixed the bug in.  Once again, your binary test checks for the
-  presence of the bug.
-\item Your software works correctly, but runs~15\% slower than the
-  last time you measured it.  You want to know which changeset
-  introduced the performance regression.  In this case, your binary
-  test measures the performance of your software, to see whether it's
-  ``fast'' or ``slow''.
-\item The sizes of the components of your project that you ship
-  exploded recently, and you suspect that something changed in the way
-  you build your project.
-\end{itemize}
-
-From these examples, it should be clear that the \hgcmd{bisect}
-command is not useful only for finding the sources of bugs.  You can
-use it to find any ``emergent property'' of a repository (anything
-that you can't find from a simple text search of the files in the
-tree) for which you can write a binary test.
-
-We'll introduce a little bit of terminology here, just to make it
-clear which parts of the search process are your responsibility, and
-which are Mercurial's.  A \emph{test} is something that \emph{you} run
-when \hgcmd{bisect} chooses a changeset.  A \emph{probe} is what
-\hgcmd{bisect} runs to tell whether a revision is good.  Finally,
-we'll use the word ``bisect'', as both a noun and a verb, to stand in
-for the phrase ``search using the \hgcmd{bisect} command.
-
-One simple way to automate the searching process would be simply to
-probe every changeset.  However, this scales poorly.  If it took ten
-minutes to test a single changeset, and you had 10,000 changesets in
-your repository, the exhaustive approach would take on average~35
-\emph{days} to find the changeset that introduced a bug.  Even if you
-knew that the bug was introduced by one of the last 500 changesets,
-and limited your search to those, you'd still be looking at over 40
-hours to find the changeset that introduced your bug.
-
-What the \hgcmd{bisect} command does is use its knowledge of the
-``shape'' of your project's revision history to perform a search in
-time proportional to the \emph{logarithm} of the number of changesets
-to check (the kind of search it performs is called a dichotomic
-search).  With this approach, searching through 10,000 changesets will
-take less than three hours, even at ten minutes per test (the search
-will require about 14 tests).  Limit your search to the last hundred
-changesets, and it will take only about an hour (roughly seven tests).
-
-The \hgcmd{bisect} command is aware of the ``branchy'' nature of a
-Mercurial project's revision history, so it has no problems dealing
-with branches, merges, or multiple heads in a repoository.  It can
-prune entire branches of history with a single probe, which is how it
-operates so efficiently.
-
-\subsection{Using the \hgcmd{bisect} command}
-
-Here's an example of \hgcmd{bisect} in action.
-
-\begin{note}
-  In versions 0.9.5 and earlier of Mercurial, \hgcmd{bisect} was not a
-  core command: it was distributed with Mercurial as an extension.
-  This section describes the built-in command, not the old extension.
-\end{note}
-
-Now let's create a repository, so that we can try out the
-\hgcmd{bisect} command in isolation.
-\interaction{bisect.init}
-We'll simulate a project that has a bug in it in a simple-minded way:
-create trivial changes in a loop, and nominate one specific change
-that will have the ``bug''.  This loop creates 35 changesets, each
-adding a single file to the repository.  We'll represent our ``bug''
-with a file that contains the text ``i have a gub''.
-\interaction{bisect.commits}
-
-The next thing that we'd like to do is figure out how to use the
-\hgcmd{bisect} command.  We can use Mercurial's normal built-in help
-mechanism for this.
-\interaction{bisect.help}
-
-The \hgcmd{bisect} command works in steps.  Each step proceeds as follows.
-\begin{enumerate}
-\item You run your binary test.
-  \begin{itemize}
-  \item If the test succeeded, you tell \hgcmd{bisect} by running the
-    \hgcmdargs{bisect}{good} command.
-  \item If it failed, run the \hgcmdargs{bisect}{--bad} command.
-  \end{itemize}
-\item The command uses your information to decide which changeset to
-  test next.
-\item It updates the working directory to that changeset, and the
-  process begins again.
-\end{enumerate}
-The process ends when \hgcmd{bisect} identifies a unique changeset
-that marks the point where your test transitioned from ``succeeding''
-to ``failing''.
-
-To start the search, we must run the \hgcmdargs{bisect}{--reset} command.
-\interaction{bisect.search.init}
-
-In our case, the binary test we use is simple: we check to see if any
-file in the repository contains the string ``i have a gub''.  If it
-does, this changeset contains the change that ``caused the bug''.  By
-convention, a changeset that has the property we're searching for is
-``bad'', while one that doesn't is ``good''.
-
-Most of the time, the revision to which the working directory is
-synced (usually the tip) already exhibits the problem introduced by
-the buggy change, so we'll mark it as ``bad''.
-\interaction{bisect.search.bad-init}
-
-Our next task is to nominate a changeset that we know \emph{doesn't}
-have the bug; the \hgcmd{bisect} command will ``bracket'' its search
-between the first pair of good and bad changesets.  In our case, we
-know that revision~10 didn't have the bug.  (I'll have more words
-about choosing the first ``good'' changeset later.)
-\interaction{bisect.search.good-init}
-
-Notice that this command printed some output.
-\begin{itemize}
-\item It told us how many changesets it must consider before it can
-  identify the one that introduced the bug, and how many tests that
-  will require.
-\item It updated the working directory to the next changeset to test,
-  and told us which changeset it's testing.
-\end{itemize}
-
-We now run our test in the working directory.  We use the
-\command{grep} command to see if our ``bad'' file is present in the
-working directory.  If it is, this revision is bad; if not, this
-revision is good.
-\interaction{bisect.search.step1}
-
-This test looks like a perfect candidate for automation, so let's turn
-it into a shell function.
-\interaction{bisect.search.mytest}
-We can now run an entire test step with a single command,
-\texttt{mytest}.
-\interaction{bisect.search.step2}
-A few more invocations of our canned test step command, and we're
-done.
-\interaction{bisect.search.rest}
-
-Even though we had~40 changesets to search through, the \hgcmd{bisect}
-command let us find the changeset that introduced our ``bug'' with
-only five tests.  Because the number of tests that the \hgcmd{bisect}
-command grows logarithmically with the number of changesets to
-search, the advantage that it has over the ``brute force'' search
-approach increases with every changeset you add.
-
-\subsection{Cleaning up after your search}
-
-When you're finished using the \hgcmd{bisect} command in a
-repository, you can use the \hgcmdargs{bisect}{reset} command to drop
-the information it was using to drive your search.  The command
-doesn't use much space, so it doesn't matter if you forget to run this
-command.  However, \hgcmd{bisect} won't let you start a new search in
-that repository until you do a \hgcmdargs{bisect}{reset}.
-\interaction{bisect.search.reset}
-
-\section{Tips for finding bugs effectively}
-
-\subsection{Give consistent input}
-
-The \hgcmd{bisect} command requires that you correctly report the
-result of every test you perform.  If you tell it that a test failed
-when it really succeeded, it \emph{might} be able to detect the
-inconsistency.  If it can identify an inconsistency in your reports,
-it will tell you that a particular changeset is both good and bad.
-However, it can't do this perfectly; it's about as likely to report
-the wrong changeset as the source of the bug.
-
-\subsection{Automate as much as possible}
-
-When I started using the \hgcmd{bisect} command, I tried a few times
-to run my tests by hand, on the command line.  This is an approach
-that I, at least, am not suited to.  After a few tries, I found that I
-was making enough mistakes that I was having to restart my searches
-several times before finally getting correct results.
-
-My initial problems with driving the \hgcmd{bisect} command by hand
-occurred even with simple searches on small repositories; if the
-problem you're looking for is more subtle, or the number of tests that
-\hgcmd{bisect} must perform increases, the likelihood of operator
-error ruining the search is much higher.  Once I started automating my
-tests, I had much better results.
-
-The key to automated testing is twofold:
-\begin{itemize}
-\item always test for the same symptom, and
-\item always feed consistent input to the \hgcmd{bisect} command.
-\end{itemize}
-In my tutorial example above, the \command{grep} command tests for the
-symptom, and the \texttt{if} statement takes the result of this check
-and ensures that we always feed the same input to the \hgcmd{bisect}
-command.  The \texttt{mytest} function marries these together in a
-reproducible way, so that every test is uniform and consistent.
-
-\subsection{Check your results}
-
-Because the output of a \hgcmd{bisect} search is only as good as the
-input you give it, don't take the changeset it reports as the
-absolute truth.  A simple way to cross-check its report is to manually
-run your test at each of the following changesets:
-\begin{itemize}
-\item The changeset that it reports as the first bad revision.  Your
-  test should still report this as bad.
-\item The parent of that changeset (either parent, if it's a merge).
-  Your test should report this changeset as good.
-\item A child of that changeset.  Your test should report this
-  changeset as bad.
-\end{itemize}
-
-\subsection{Beware interference between bugs}
-
-It's possible that your search for one bug could be disrupted by the
-presence of another.  For example, let's say your software crashes at
-revision 100, and worked correctly at revision 50.  Unknown to you,
-someone else introduced a different crashing bug at revision 60, and
-fixed it at revision 80.  This could distort your results in one of
-several ways.
-
-It is possible that this other bug completely ``masks'' yours, which
-is to say that it occurs before your bug has a chance to manifest
-itself.  If you can't avoid that other bug (for example, it prevents
-your project from building), and so can't tell whether your bug is
-present in a particular changeset, the \hgcmd{bisect} command cannot
-help you directly.  Instead, you can mark a changeset as untested by
-running \hgcmdargs{bisect}{--skip}.
-
-A different problem could arise if your test for a bug's presence is
-not specific enough.  If you check for ``my program crashes'', then
-both your crashing bug and an unrelated crashing bug that masks it
-will look like the same thing, and mislead \hgcmd{bisect}.
-
-Another useful situation in which to use \hgcmdargs{bisect}{--skip} is
-if you can't test a revision because your project was in a broken and
-hence untestable state at that revision, perhaps because someone
-checked in a change that prevented the project from building.
-
-\subsection{Bracket your search lazily}
-
-Choosing the first ``good'' and ``bad'' changesets that will mark the
-end points of your search is often easy, but it bears a little
-discussion nevertheless.  From the perspective of \hgcmd{bisect}, the
-``newest'' changeset is conventionally ``bad'', and the older
-changeset is ``good''.
-
-If you're having trouble remembering when a suitable ``good'' change
-was, so that you can tell \hgcmd{bisect}, you could do worse than
-testing changesets at random.  Just remember to eliminate contenders
-that can't possibly exhibit the bug (perhaps because the feature with
-the bug isn't present yet) and those where another problem masks the
-bug (as I discussed above).
-
-Even if you end up ``early'' by thousands of changesets or months of
-history, you will only add a handful of tests to the total number that
-\hgcmd{bisect} must perform, thanks to its logarithmic behaviour.
-
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "00book"
-%%% End: 
--- a/en/wdir-after-commit.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg5971"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="wdir-after-commit.svg">
-  <defs
-     id="defs5973">
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6445"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path4855"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient6049">
-      <stop
-         style="stop-color:#686868;stop-opacity:1;"
-         offset="0"
-         id="stop6051" />
-      <stop
-         style="stop-color:#f0f0f0;stop-opacity:1;"
-         offset="1"
-         id="stop6053" />
-    </linearGradient>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6083"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6142"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-42.00893,-30.49544)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6216"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-6.0462,-0.664361)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6232"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6772"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.90509668"
-     inkscape:cx="390.0539"
-     inkscape:cy="690.49342"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="0"
-     inkscape:window-y="25">
-    <sodipodi:guide
-       orientation="vertical"
-       position="-1.4285714"
-       id="guide6022" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata5976">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       y="245.98355"
-       x="328.23956"
-       height="258.57144"
-       width="174.28572"
-       id="rect6047"
-       style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6261"
-       transform="translate(234,0)">
-      <rect
-         y="258.7149"
-         x="114.11369"
-         height="44.537449"
-         width="134.53746"
-         id="rect5983"
-         style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5985"
-         y="284.47562"
-         x="138.7962"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="284.47562"
-           x="138.7962"
-           id="tspan5987"
-           sodipodi:role="line">dfbbb33f3fa3</tspan></text>
-    </g>
-    <rect
-       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect5996"
-       width="134.53746"
-       height="44.537449"
-       x="348.11371"
-       y="320.38159" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="372.7962"
-       y="346.1423"
-       id="text5998"><tspan
-         sodipodi:role="line"
-         id="tspan6000"
-         x="372.7962"
-         y="346.1423"
-         style="font-family:Courier">e7639888bb2f</tspan></text>
-    <rect
-       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect6004"
-       width="134.53746"
-       height="44.537449"
-       x="348.11371"
-       y="382.04825" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="370.65421"
-       y="407.80896"
-       id="text6006"><tspan
-         sodipodi:role="line"
-         id="tspan6008"
-         x="370.65421"
-         y="407.80896"
-         style="font-family:Courier">7b064d8bac5e</tspan></text>
-    <path
-       inkscape:connector-type="polyline"
-       id="path6018"
-       d="M 415.38242,303.62646 L 415.38242,320.00744"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <path
-       inkscape:connection-end="#rect6004"
-       inkscape:connector-type="polyline"
-       id="path6020"
-       d="M 415.38242,365.29315 L 415.38243,381.67412"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <rect
-       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect6039"
-       width="134.53746"
-       height="44.537449"
-       x="348.11359"
-       y="443.71487" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="372.79706"
-       y="469.47556"
-       id="text6041"><tspan
-         sodipodi:role="line"
-         id="tspan6043"
-         x="372.79706"
-         y="469.47556"
-         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    <path
-       inkscape:connection-end="#rect6039"
-       inkscape:connector-type="polyline"
-       id="path6045"
-       d="M 415.38238,426.95981 L 415.38235,443.34087"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="327.66046"
-       y="231.36218"
-       id="text6102"><tspan
-         sodipodi:role="line"
-         id="tspan6104"
-         x="327.66046"
-         y="231.36218">History in repository</tspan></text>
-    <rect
-       y="245.94225"
-       x="557.28418"
-       height="204.51619"
-       width="174.36833"
-       id="rect6140"
-       style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6130"
-       transform="translate(262.3254,24.38544)">
-      <rect
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6106"
-         width="134.53746"
-         height="44.537449"
-         x="314.87415"
-         y="257.95059" />
-      <text
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="339.55664"
-         y="283.7113"
-         id="text6108"><tspan
-           sodipodi:role="line"
-           id="tspan6110"
-           x="339.55664"
-           y="283.7113"
-           style="font-family:Courier">dfbbb33f3fa3</tspan></text>
-    </g>
-    <g
-       id="g6135"
-       transform="translate(263.0396,49.83106)">
-      <rect
-         inkscape:transform-center-y="102.85714"
-         inkscape:transform-center-x="129.28571"
-         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6112"
-         width="134.53746"
-         height="44.537449"
-         x="314.15985"
-         y="326.52203" />
-      <text
-         inkscape:transform-center-y="102.7311"
-         inkscape:transform-center-x="128.69672"
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="338.84335"
-         y="352.28271"
-         id="text6114"><tspan
-           sodipodi:role="line"
-           id="tspan6116"
-           x="338.84335"
-           y="352.28271"
-           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="576.63208"
-       y="270.479"
-       id="text6118"><tspan
-         sodipodi:role="line"
-         id="tspan6120"
-         x="576.63208"
-         y="270.479">First parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="576.07544"
-       y="364.49615"
-       id="text6122"><tspan
-         sodipodi:role="line"
-         id="tspan6124"
-         x="576.07544"
-         y="364.49615">Second parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="556.61743"
-       y="231.36218"
-       id="text6195"><tspan
-         sodipodi:role="line"
-         id="tspan6197"
-         x="556.61743"
-         y="231.36218">Parents of working directory</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 576.82542,297.63008 L 483.02528,287.95831"
-       id="path6266"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g6130"
-       inkscape:connection-end="#g6261" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 665.12232,418.17579 L 665.12232,418.17579"
-       id="path6270"
-       inkscape:connector-type="polyline" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="316.86407"
-       y="275.6496"
-       id="text6573"><tspan
-         sodipodi:role="line"
-         id="tspan6575"
-         x="316.86407"
-         y="275.6496"
-         style="text-align:end;text-anchor:end">New</tspan><tspan
-         sodipodi:role="line"
-         x="316.86407"
-         y="290.6496"
-         id="tspan6577"
-         style="text-align:end;text-anchor:end">changeset</tspan></text>
-  </g>
-</svg>
--- a/en/wdir-branch.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,418 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg5971"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="wdir-branch.svg">
-  <defs
-     id="defs5973">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path4855"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient6049">
-      <stop
-         style="stop-color:#686868;stop-opacity:1;"
-         offset="0"
-         id="stop6051" />
-      <stop
-         style="stop-color:#f0f0f0;stop-opacity:1;"
-         offset="1"
-         id="stop6053" />
-    </linearGradient>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6083"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6142"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-42.00893,-30.49544)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6216"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6232"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6445"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6974"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6996"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.90509668"
-     inkscape:cx="345.85973"
-     inkscape:cy="690.49342"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="0"
-     inkscape:window-y="25">
-    <sodipodi:guide
-       orientation="vertical"
-       position="-1.4285714"
-       id="guide6022" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata5976">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       y="246.06918"
-       x="64.325172"
-       height="204.26233"
-       width="333.2135"
-       id="rect6047"
-       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g1935">
-      <rect
-         y="266.24374"
-         x="84.113708"
-         height="44.537449"
-         width="134.53746"
-         id="rect5996"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5998"
-         y="292.00446"
-         x="108.7962"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="292.00446"
-           x="108.7962"
-           id="tspan6000"
-           sodipodi:role="line">e7639888bb2f</tspan></text>
-    </g>
-    <g
-       id="g6976"
-       transform="translate(70,0)">
-      <rect
-         y="327.9104"
-         x="40.113693"
-         height="44.537449"
-         width="134.53746"
-         id="rect6004"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text6006"
-         y="353.67111"
-         x="62.654205"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="353.67111"
-           x="62.654205"
-           id="tspan6008"
-           sodipodi:role="line">7b064d8bac5e</tspan></text>
-    </g>
-    <path
-       inkscape:connector-type="polyline"
-       id="path6020"
-       d="M 160.92915,311.15532 L 167.83571,327.53627"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       inkscape:connection-end="#g6976"
-       inkscape:connection-start="#g1935" />
-    <rect
-       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect6039"
-       width="134.53746"
-       height="44.537449"
-       x="110.11359"
-       y="389.57703" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="134.79706"
-       y="415.33771"
-       id="text6041"><tspan
-         sodipodi:role="line"
-         id="tspan6043"
-         x="134.79706"
-         y="415.33771"
-         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    <path
-       inkscape:connection-end="#rect6039"
-       inkscape:connector-type="polyline"
-       id="path6045"
-       d="M 177.38238,372.82195 L 177.38235,389.20303"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <rect
-       y="245.94225"
-       x="447.28412"
-       height="204.51619"
-       width="174.36833"
-       id="rect6140"
-       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6130"
-       transform="translate(152.3254,24.38544)">
-      <rect
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6106"
-         width="134.53746"
-         height="44.537449"
-         x="314.87415"
-         y="257.95059" />
-      <text
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="339.55664"
-         y="283.7113"
-         id="text6108"><tspan
-           sodipodi:role="line"
-           id="tspan6110"
-           x="339.55664"
-           y="283.7113"
-           style="font-family:Courier">ffb20e1701ea</tspan></text>
-    </g>
-    <g
-       id="g6135"
-       transform="translate(153.0396,49.83106)">
-      <rect
-         inkscape:transform-center-y="102.85714"
-         inkscape:transform-center-x="129.28571"
-         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6112"
-         width="134.53746"
-         height="44.537449"
-         x="314.15985"
-         y="326.52203" />
-      <text
-         inkscape:transform-center-y="102.7311"
-         inkscape:transform-center-x="128.69672"
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="338.84335"
-         y="352.28271"
-         id="text6114"><tspan
-           sodipodi:role="line"
-           id="tspan6116"
-           x="338.84335"
-           y="352.28271"
-           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="466.63208"
-       y="270.479"
-       id="text6118"><tspan
-         sodipodi:role="line"
-         id="tspan6120"
-         x="466.63208"
-         y="270.479">First parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="466.07544"
-       y="364.49615"
-       id="text6122"><tspan
-         sodipodi:role="line"
-         id="tspan6124"
-         x="466.07544"
-         y="364.49615">Second parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="446.61743"
-       y="231.36218"
-       id="text6195"><tspan
-         sodipodi:role="line"
-         id="tspan6197"
-         x="446.61743"
-         y="231.36218">Parents of working directory</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 466.82542,300.21999 L 377.00207,294.39744"
-       id="path6266"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g6130"
-       inkscape:connection-end="#rect1925" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 665.12232,418.17579 L 665.12232,418.17579"
-       id="path6270"
-       inkscape:connector-type="polyline" />
-    <g
-       id="g2845">
-      <rect
-         y="266.24374"
-         x="242.09048"
-         height="44.537449"
-         width="134.53746"
-         id="rect1925"
-         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text1927"
-         y="292.00446"
-         x="266.77298"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="292.00446"
-           x="266.77298"
-           id="tspan1929"
-           sodipodi:role="line">ffb20e1701ea</tspan></text>
-    </g>
-    <path
-       inkscape:connector-type="polyline"
-       id="path1933"
-       d="M 260.89978,311.15532 L 225.84185,327.53627"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       inkscape:connection-end="#g6976" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="109.45568"
-       y="231.4554"
-       id="text2837"><tspan
-         sodipodi:role="line"
-         id="tspan2839"
-         x="109.45568"
-         y="231.4554">Pre-existing head</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="237.54184"
-       y="231.4554"
-       id="text2841"><tspan
-         sodipodi:role="line"
-         id="tspan2843"
-         x="237.54184"
-         y="231.4554">Newly created head (and tip)</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 148.05048,235.87482 L 149.94915,265.86962"
-       id="path2850"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g1935" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 303.83495,238.08453 L 306.87874,265.86962"
-       id="path2852"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g2845" />
-  </g>
-</svg>
--- a/en/wdir-merge.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg5971"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="wdir-merge.svg">
-  <defs
-     id="defs5973">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path4855"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient6049">
-      <stop
-         style="stop-color:#686868;stop-opacity:1;"
-         offset="0"
-         id="stop6051" />
-      <stop
-         style="stop-color:#f0f0f0;stop-opacity:1;"
-         offset="1"
-         id="stop6053" />
-    </linearGradient>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6083"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6142"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-42.00893,-30.49544)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6216"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6232"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6445"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6974"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6996"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.28"
-     inkscape:cx="345.85973"
-     inkscape:cy="690.49342"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="0"
-     inkscape:window-y="25">
-    <sodipodi:guide
-       orientation="vertical"
-       position="-1.4285714"
-       id="guide6022" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata5976">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       y="246.06918"
-       x="64.325172"
-       height="204.26233"
-       width="333.2135"
-       id="rect6047"
-       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6976"
-       transform="translate(70,0)">
-      <rect
-         y="327.9104"
-         x="40.113693"
-         height="44.537449"
-         width="134.53746"
-         id="rect6004"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text6006"
-         y="353.67111"
-         x="62.654205"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="353.67111"
-           x="62.654205"
-           id="tspan6008"
-           sodipodi:role="line">7b064d8bac5e</tspan></text>
-    </g>
-    <path
-       inkscape:connector-type="polyline"
-       id="path6020"
-       d="M 160.92915,311.15532 L 167.83571,327.53627"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       inkscape:connection-end="#g6976"
-       inkscape:connection-start="#g1935" />
-    <rect
-       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect6039"
-       width="134.53746"
-       height="44.537449"
-       x="110.11359"
-       y="389.57703" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="134.79706"
-       y="415.33771"
-       id="text6041"><tspan
-         sodipodi:role="line"
-         id="tspan6043"
-         x="134.79706"
-         y="415.33771"
-         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    <path
-       inkscape:connection-end="#rect6039"
-       inkscape:connector-type="polyline"
-       id="path6045"
-       d="M 177.38238,372.82195 L 177.38235,389.20303"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <rect
-       y="245.94225"
-       x="447.28412"
-       height="204.51619"
-       width="174.36833"
-       id="rect6140"
-       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6130"
-       transform="translate(152.3254,24.38544)">
-      <rect
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6106"
-         width="134.53746"
-         height="44.537449"
-         x="314.87415"
-         y="257.95059" />
-      <text
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="339.55664"
-         y="283.7113"
-         id="text6108"><tspan
-           sodipodi:role="line"
-           id="tspan6110"
-           x="339.55664"
-           y="283.7113"
-           style="font-family:Courier">ffb20e1701ea</tspan></text>
-    </g>
-    <g
-       id="g6135"
-       transform="translate(153.0396,49.83106)">
-      <rect
-         inkscape:transform-center-y="102.85714"
-         inkscape:transform-center-x="129.28571"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6112"
-         width="134.53746"
-         height="44.537449"
-         x="314.15985"
-         y="326.52203" />
-      <text
-         inkscape:transform-center-y="102.7311"
-         inkscape:transform-center-x="128.69672"
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="338.84335"
-         y="352.28271"
-         id="text6114"><tspan
-           sodipodi:role="line"
-           id="tspan6116"
-           x="338.84335"
-           y="352.28271"
-           style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="466.63208"
-       y="270.479"
-       id="text6118"><tspan
-         sodipodi:role="line"
-         id="tspan6120"
-         x="466.63208"
-         y="270.479">First parent (unchanged)</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="466.07544"
-       y="364.49615"
-       id="text6122"><tspan
-         sodipodi:role="line"
-         id="tspan6124"
-         x="466.07544"
-         y="364.49615">Second parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="446.61743"
-       y="231.36218"
-       id="text6195"><tspan
-         sodipodi:role="line"
-         id="tspan6197"
-         x="446.61743"
-         y="231.36218">Parents of working directory</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 466.82542,300.21999 L 377.00207,294.39744"
-       id="path6266"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g6130"
-       inkscape:connection-end="#rect1925" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 665.12232,418.17579 L 665.12232,418.17579"
-       id="path6270"
-       inkscape:connector-type="polyline" />
-    <g
-       id="g2845">
-      <rect
-         y="266.24374"
-         x="242.09048"
-         height="44.537449"
-         width="134.53746"
-         id="rect1925"
-         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text1927"
-         y="292.00446"
-         x="266.77298"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="292.00446"
-           x="266.77298"
-           id="tspan1929"
-           sodipodi:role="line">ffb20e1701ea</tspan></text>
-    </g>
-    <path
-       inkscape:connector-type="polyline"
-       id="path1933"
-       d="M 260.89978,311.15532 L 225.84185,327.53627"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
-       inkscape:connection-end="#g6976" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="109.45568"
-       y="231.4554"
-       id="text2837"><tspan
-         sodipodi:role="line"
-         id="tspan2839"
-         x="109.45568"
-         y="231.4554">Pre-existing head</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="237.54184"
-       y="231.4554"
-       id="text2841"><tspan
-         sodipodi:role="line"
-         id="tspan2843"
-         x="237.54184"
-         y="231.4554">Newly created head (and tip)</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 148.05048,235.87482 L 149.94915,265.86962"
-       id="path2850"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g1935" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
-       d="M 303.83495,238.08453 L 306.87874,265.86962"
-       id="path2852"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g2845" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 466.82545,379.17944 L 219.0253,307.95488"
-       id="path3016"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g6135"
-       inkscape:connection-end="#g1935" />
-    <g
-       id="g1935">
-      <rect
-         y="266.24374"
-         x="84.113708"
-         height="44.537449"
-         width="134.53746"
-         id="rect5996"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5998"
-         y="292.00446"
-         x="108.7962"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="292.00446"
-           x="108.7962"
-           id="tspan6000"
-           sodipodi:role="line">e7639888bb2f</tspan></text>
-    </g>
-  </g>
-</svg>
--- a/en/wdir-pre-branch.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg5971"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="wdir-branch.svg">
-  <defs
-     id="defs5973">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path4855"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient6049">
-      <stop
-         style="stop-color:#686868;stop-opacity:1;"
-         offset="0"
-         id="stop6051" />
-      <stop
-         style="stop-color:#f0f0f0;stop-opacity:1;"
-         offset="1"
-         id="stop6053" />
-    </linearGradient>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6083"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6142"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-42.00893,-30.49544)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6216"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6232"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6445"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6974"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6996"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.90509668"
-     inkscape:cx="390.0539"
-     inkscape:cy="690.49342"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="0"
-     inkscape:window-y="25">
-    <sodipodi:guide
-       orientation="vertical"
-       position="-1.4285714"
-       id="guide6022" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata5976">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <rect
-       y="245.94225"
-       x="20.198257"
-       height="204.51619"
-       width="174.36833"
-       id="rect6047"
-       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <rect
-       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect5996"
-       width="134.53746"
-       height="44.537449"
-       x="40.113693"
-       y="266.24374" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="64.796204"
-       y="292.00446"
-       id="text5998"><tspan
-         sodipodi:role="line"
-         id="tspan6000"
-         x="64.796204"
-         y="292.00446"
-         style="font-family:Courier">e7639888bb2f</tspan></text>
-    <g
-       id="g6976">
-      <rect
-         y="327.9104"
-         x="40.113693"
-         height="44.537449"
-         width="134.53746"
-         id="rect6004"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text6006"
-         y="353.67111"
-         x="62.654205"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="353.67111"
-           x="62.654205"
-           id="tspan6008"
-           sodipodi:role="line">7b064d8bac5e</tspan></text>
-    </g>
-    <path
-       inkscape:connection-end="#rect6004"
-       inkscape:connector-type="polyline"
-       id="path6020"
-       d="M 107.38242,311.15529 L 107.38242,327.53626"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <rect
-       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-       id="rect6039"
-       width="134.53746"
-       height="44.537449"
-       x="40.113571"
-       y="389.57703" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="64.797073"
-       y="415.33771"
-       id="text6041"><tspan
-         sodipodi:role="line"
-         id="tspan6043"
-         x="64.797073"
-         y="415.33771"
-         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    <path
-       inkscape:connection-end="#rect6039"
-       inkscape:connector-type="polyline"
-       id="path6045"
-       d="M 107.38238,372.82195 L 107.38235,389.20301"
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="19.660461"
-       y="231.36218"
-       id="text6102"><tspan
-         sodipodi:role="line"
-         id="tspan6104"
-         x="19.660461"
-         y="231.36218">History in repository</tspan></text>
-    <rect
-       y="245.94225"
-       x="249.28412"
-       height="204.51619"
-       width="174.36833"
-       id="rect6140"
-       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-    <g
-       id="g6130"
-       transform="translate(-45.67459,24.38544)">
-      <rect
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6106"
-         width="134.53746"
-         height="44.537449"
-         x="314.87415"
-         y="257.95059" />
-      <text
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="339.55664"
-         y="283.7113"
-         id="text6108"><tspan
-           sodipodi:role="line"
-           id="tspan6110"
-           x="339.55664"
-           y="283.7113"
-           style="font-family:Courier">7b064d8bac5e</tspan></text>
-    </g>
-    <g
-       id="g6135"
-       transform="translate(-44.96042,49.83106)">
-      <rect
-         inkscape:transform-center-y="102.85714"
-         inkscape:transform-center-x="129.28571"
-         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6112"
-         width="134.53746"
-         height="44.537449"
-         x="314.15985"
-         y="326.52203" />
-      <text
-         inkscape:transform-center-y="102.7311"
-         inkscape:transform-center-x="128.69672"
-         xml:space="preserve"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         x="338.84335"
-         y="352.28271"
-         id="text6114"><tspan
-           sodipodi:role="line"
-           id="tspan6116"
-           x="338.84335"
-           y="352.28271"
-           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="268.63208"
-       y="270.479"
-       id="text6118"><tspan
-         sodipodi:role="line"
-         id="tspan6120"
-         x="268.63208"
-         y="270.479">First parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="268.07544"
-       y="364.49615"
-       id="text6122"><tspan
-         sodipodi:role="line"
-         id="tspan6124"
-         x="268.07544"
-         y="364.49615">Second parent</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="248.61746"
-       y="231.36218"
-       id="text6195"><tspan
-         sodipodi:role="line"
-         id="tspan6197"
-         x="248.61746"
-         y="231.36218">Parents of working directory</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 268.82543,318.06163 L 175.02528,336.72225"
-       id="path6266"
-       inkscape:connector-type="polyline"
-       inkscape:connection-end="#g6976"
-       inkscape:connection-start="#g6130" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 665.12232,418.17579 L 665.12232,418.17579"
-       id="path6270"
-       inkscape:connector-type="polyline" />
-  </g>
-</svg>
--- a/en/wdir.svg	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="744.09448819"
-   height="1052.3622047"
-   id="svg5971"
-   sodipodi:version="0.32"
-   inkscape:version="0.44.1"
-   sodipodi:docbase="/home/bos/hg/hgbook/en"
-   sodipodi:docname="wdir.svg">
-  <defs
-     id="defs5973">
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible">
-      <path
-         id="path4855"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <linearGradient
-       id="linearGradient6049">
-      <stop
-         style="stop-color:#686868;stop-opacity:1;"
-         offset="0"
-         id="stop6051" />
-      <stop
-         style="stop-color:#f0f0f0;stop-opacity:1;"
-         offset="1"
-         id="stop6053" />
-    </linearGradient>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;">
-      <path
-         id="path4852"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6083"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6142"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-42.00893,-30.49544)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-240.0462,-8.633237e-6)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6216"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6232"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient6049"
-       id="linearGradient6445"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
-       x1="333.91171"
-       y1="488.79077"
-       x2="508.94543"
-       y2="263.79077" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.90509668"
-     inkscape:cx="390.0539"
-     inkscape:cy="690.49342"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="906"
-     inkscape:window-height="620"
-     inkscape:window-x="0"
-     inkscape:window-y="25">
-    <sodipodi:guide
-       orientation="vertical"
-       position="-1.4285714"
-       id="guide6022" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata5976">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1">
-    <g
-       id="g6431"
-       transform="translate(0,-0.137863)">
-      <rect
-         style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6047"
-         width="174.36833"
-         height="204.51619"
-         x="94.198257"
-         y="246.08011" />
-      <rect
-         y="266.38159"
-         x="114.11369"
-         height="44.537449"
-         width="134.53746"
-         id="rect5996"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text5998"
-         y="292.1423"
-         x="138.7962"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="292.1423"
-           x="138.7962"
-           id="tspan6000"
-           sodipodi:role="line">e7639888bb2f</tspan></text>
-      <rect
-         y="328.04825"
-         x="114.11369"
-         height="44.537449"
-         width="134.53746"
-         id="rect6004"
-         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text6006"
-         y="353.80896"
-         x="136.65421"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="font-family:Courier"
-           y="353.80896"
-           x="136.65421"
-           id="tspan6008"
-           sodipodi:role="line">7b064d8bac5e</tspan></text>
-      <path
-         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-         d="M 181.38242,311.29315 L 181.38242,327.67412"
-         id="path6020"
-         inkscape:connector-type="polyline"
-         inkscape:connection-end="#rect6004" />
-      <rect
-         y="389.71487"
-         x="114.11357"
-         height="44.537449"
-         width="134.53746"
-         id="rect6039"
-         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
-      <text
-         id="text6041"
-         y="415.47556"
-         x="138.79707"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           style="fill:#979797;fill-opacity:1;font-family:Courier"
-           y="415.47556"
-           x="138.79707"
-           id="tspan6043"
-           sodipodi:role="line">000000000000</tspan></text>
-      <path
-         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
-         d="M 181.38238,372.95981 L 181.38235,389.34087"
-         id="path6045"
-         inkscape:connector-type="polyline"
-         inkscape:connection-end="#rect6039" />
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="93.660484"
-       y="231.36218"
-       id="text6102"><tspan
-         sodipodi:role="line"
-         id="tspan6104"
-         x="93.660484"
-         y="231.36218">History in repository</tspan></text>
-    <g
-       id="g6416">
-      <rect
-         style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-         id="rect6140"
-         width="174.36833"
-         height="204.51619"
-         x="323.28412"
-         y="245.94225" />
-      <g
-         transform="translate(28.32541,24.38544)"
-         id="g6130">
-        <rect
-           y="257.95059"
-           x="314.87415"
-           height="44.537449"
-           width="134.53746"
-           id="rect6106"
-           style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
-        <text
-           id="text6108"
-           y="283.7113"
-           x="339.55664"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           xml:space="preserve"><tspan
-             style="font-family:Courier"
-             y="283.7113"
-             x="339.55664"
-             id="tspan6110"
-             sodipodi:role="line">e7639888bb2f</tspan></text>
-      </g>
-      <g
-         transform="translate(29.03958,49.83106)"
-         id="g6135">
-        <rect
-           y="326.52203"
-           x="314.15985"
-           height="44.537449"
-           width="134.53746"
-           id="rect6112"
-           style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-           inkscape:transform-center-x="129.28571"
-           inkscape:transform-center-y="102.85714" />
-        <text
-           id="text6114"
-           y="352.28271"
-           x="338.84335"
-           style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-           xml:space="preserve"
-           inkscape:transform-center-x="128.69672"
-           inkscape:transform-center-y="102.7311"><tspan
-             style="fill:#979797;fill-opacity:1;font-family:Courier"
-             y="352.28271"
-             x="338.84335"
-             id="tspan6116"
-             sodipodi:role="line">000000000000</tspan></text>
-      </g>
-      <text
-         id="text6118"
-         y="270.479"
-         x="342.63208"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="270.479"
-           x="342.63208"
-           id="tspan6120"
-           sodipodi:role="line">First parent</tspan></text>
-      <text
-         id="text6122"
-         y="364.49615"
-         x="342.07544"
-         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-         xml:space="preserve"><tspan
-           y="364.49615"
-           x="342.07544"
-           id="tspan6124"
-           sodipodi:role="line">Second parent</tspan></text>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
-       x="322.61746"
-       y="231.36218"
-       id="text6195"><tspan
-         sodipodi:role="line"
-         id="tspan6197"
-         x="322.61746"
-         y="231.36218">Parents of working directory</tspan></text>
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-       d="M 342.82543,299.89384 L 249.02528,293.36123"
-       id="path6266"
-       inkscape:connector-type="polyline"
-       inkscape:connection-start="#g6130"
-       inkscape:connection-end="#rect5996" />
-    <path
-       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       d="M 665.12232,418.17579 L 665.12232,418.17579"
-       id="path6270"
-       inkscape:connector-type="polyline" />
-  </g>
-</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/00book.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,81 @@
+% 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[spanish]{babel}
+\usepackage{enumerate}
+\usepackage{fullpage}
+\usepackage{makeidx}
+\usepackage{ifpdf}
+\usepackage{graphicx}
+\usepackage{pslatex}
+\usepackage{fancyvrb}
+\usepackage[utf8]{inputenc} %accents in spanish
+% leave hyperref until last
+\ifpdf
+\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}
+\fi
+
+\include{99defs}
+
+\title{Control Distribuido de Revisiones con Mercurial} \author{Bryan
+  O'Sullivan}
+\date{Copyright \copyright\ 2006, 2007 Bryan O'Sullivan.\\
+  Este material puede distribuirse únicamente bajo los términos y
+  condiciones establecidos en la versión 1.0 de la Licencia de Publicación
+  Abierta (OPL). Refiérase por favor al apéndice~\ref{cha:opl} para encontrar el
+  texto de la licencia.\\
+  Este libro fue preparado a partir de
+  \href{http://mercurial.intuxication.org/hg/mercurial_book_es}{rev~\input{build_id}}
+  usando Mercurial \href{http://www.selenic.com/hg/}{rev~\input{hg_id}}.}
+
+\makeindex
+
+\begin{document}
+\spanishdeactivate{<>"~}
+\maketitle
+
+\addcontentsline{toc}{chapter}{Índice general}
+\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}{Bibliografía}
+\bibliographystyle{alpha}
+\bibliography{99book}
+
+\addcontentsline{toc}{chapter}{Índice alfabético}
+\printindex
+
+\end{document}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: t
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/99book.bib	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/99book.bib
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/99defs.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,146 @@
+% Bug ID.
+\newcommand{\bug}[1]{\index{Base de datos de fallos de Mercurial
+    !\href{http://www.selenic.com/mercurial/bts/issue#1}{fallo
+      ~#1}}\href{http://www.selenic.com/mercurial/bts/issue#1}{Fallo de
+      Mercurial 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}, fichero}\texttt{#1}}
+
+% Directory name, with index entry.
+\newcommand{\sdirname}[1]{\index{\texttt{#1}, directorio}\texttt{#1}}
+
+% Mercurial extension.
+\newcommand{\hgext}[1]{\index{\texttt{#1}, extensi\'on}\texttt{#1}}
+
+% Command provided by a Mercurial extension.
+\newcommand{\hgxcmd}[2]{\index{\texttt{#2}, comando (extensi\'on
+\texttt{#1})}\index{\texttt{#1}, extensi\'on!comando \texttt{#2}}``\texttt{hg #2}''}
+
+% Mercurial command.
+\newcommand{\hgcmd}[1]{\index{\texttt{#1}, comando}``\texttt{hg #1}''}
+
+% Mercurial command, with arguments.
+\newcommand{\hgcmdargs}[2]{\index{\texttt{#1}, comando}``\texttt{hg #1 #2}''}
+
+\newcommand{\tplkword}[1]{\index{\texttt{#1}, palabra clave de
+plantilla}\index{palabras clave de plantilla!\texttt{#1}}\texttt{#1}}
+
+\newcommand{\tplkwfilt}[2]{\index{\texttt{#1}, palabra clave de plantilla!filtro
+\texttt{#2}}\index{filtros de plantilla!\texttt{#2}}\index{\texttt{#2}, filtro
+de plantilla}\texttt{#2}}
+
+\newcommand{\tplfilter}[1]{\index{filtros de
+plantilla!\texttt{#1}}\index{\texttt{#1}, filtro de plantilla}\texttt{#1}}
+
+% Shell/system command.
+\newcommand{\command}[1]{\index{\texttt{#1}, comando de sistema}\texttt{#1}}
+
+% Shell/system command, with arguments.
+\newcommand{\cmdargs}[2]{\index{\texttt{#1} comando de sistema}``\texttt{#1 #2}''}
+
+% Mercurial command option.
+\newcommand{\hgopt}[2]{\index{\texttt{#1}, comando!opci$BC3(Bn \texttt{#2}}\texttt{#2}}
+
+% Mercurial command option, provided by an extension command.
+\newcommand{\hgxopt}[3]{\index{\texttt{#2}, comando (extensi$BC3(Bn
+\texttt{#1})!opci$BC3(Bn \texttt{#3}}\index{\texttt{#1}, extensi$BC3(Bn!comando
+\texttt{#2}!opci$BC3(Bn\texttt{#3}}\texttt{#3}}
+
+% Mercurial global option.
+\newcommand{\hggopt}[1]{\index{opciones globales!opci$BC3(Bn \texttt{#1}}\texttt{#1}}
+
+% Shell/system command option.
+\newcommand{\cmdopt}[2]{\index{\texttt{#1}, comando!opci$BC3(Bn \texttt{#2}}\texttt{#2}}
+
+% Command option.
+\newcommand{\option}[1]{\texttt{#1}}
+
+% Software package.
+\newcommand{\package}[1]{\index{\texttt{#1}, paquete}\texttt{#1}}
+
+% Section name from a hgrc file.
+\newcommand{\rcsection}[1]{\index{\texttt{hgrc}, fichero!secci$BC3(Bn \texttt{#1}}\texttt{[#1]}}
+
+% Named item in a hgrc file section.
+\newcommand{\rcitem}[2]{\index{\texttt{hgrc}, fichero!secci$BC3(Bn
+\texttt{#1}!entrada \texttt{#2}}\texttt{#2}}
+
+% hgrc file.
+\newcommand{\hgrc}{\index{fichero de configuraci$BC3(Bn!\texttt{hgrc}
+    (Linux/Unix)}\index{\texttt{hgrc}, fichero de configuraci$BC3(Bn}\texttt{hgrc}}
+
+% Mercurial.ini file.
+\newcommand{\hgini}{\index{fichero de configuraci$BC3(Bn!\texttt{Mercurial.ini}
+    (Windows)}\index{\texttt{Mercurial.ini}, fichero de configuraci$BC3(Bn}\texttt{Mercurial.ini}}
+
+% Hook name.
+\newcommand{\hook}[1]{\index{\texttt{#1}, gancho}\index{ganchos!\texttt{#1}}\texttt{#1}}
+
+% Environment variable.
+\newcommand{\envar}[1]{\index{\texttt{#1}, variable de entorno}\index{variables
+de entorno!\texttt{#1}}\texttt{#1}}
+
+% Python module.
+\newcommand{\pymod}[1]{\index{\texttt{#1}, m$BC3(Bdulo}\texttt{#1}}
+
+% Python class in a module.
+\newcommand{\pymodclass}[2]{\index{\texttt{#1}, m$BC3(Bdulo!clase \texttt{#2}}\texttt{#1.#2}}
+
+% Python function in a module.
+\newcommand{\pymodfunc}[2]{\index{\texttt{#1}, m$BC3(Bdulo!funci$BC3(Bn \texttt{#2}}\texttt{#1.#2}}
+
+% Note: blah blah.
+\newsavebox{\notebox}
+\newenvironment{note}%
+  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Nota:}\space}%
+  {\end{minipage}\end{lrbox}\fbox{\usebox{\notebox}}}
+\newenvironment{caution}%
+  {\begin{lrbox}{\notebox}\begin{minipage}{0.7\textwidth}\textbf{Precauci$BC3(Bn:}\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}[2][]{\includegraphics[#1]{#2}}
+\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}, comando}}
+
+% Reference entry for a command option with long and short forms.
+\newcommand{\optref}[3]{\subsubsection{\hgopt{#1}{--#3}, tambi$BC)(Bn \hgopt{#1}{-#2}}}
+
+% Reference entry for a command option with only long form.
+\newcommand{\loptref}[2]{\subsubsection{opci$BC3(Bn \hgopt{#1}{--#2}}}
+
+% 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: yatex
+%%% TeX-master: "00book"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/Leame.1st	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,508 @@
+= Parámetros de Organización =
+
+ * Se mantienen los nombres de los archivos
+ * Se traduce solamente el contenido
+ * Copie los archivos de en a es y tradúzcalos
+ * Las gráficas son tan importantes como los archivos
+ de texto, ya han sido traducidas
+ * Encoding UTF-8 para las tildes, eñes y demás
+ * Ancho de línea de 70 caracteres
+
+= ¿Cómo contribuir? =
+Obtenga la copia :
+hg clone http://mercurial.intuxication.org/hg/mercurial_book_es/
+
+Esto le ofrecerá un clon del repositorio en el directorio recién 
+creado '''mercurial_book_es''':
+
+mercurial_book_es
+|
+|-- en
+|-- es
+|-- examples
+|-- html
+`-- sillybench
+
+El directorio de trabajo es '''es'''.
+
+
+Una vez que haya traducido o aplicado correcciones a los archivos de
+su copia local, haga un commit
+
+ hg commit -m "comentario descriptivo de lo que hizo"
+
+Siempre mantenga actualizado su repositorio local
+ hg pull
+ hg update
+
+Hay dos formas de hacer la contribución, primero envíe un correo a
+igor@tamarapatino.org indicando lo que desea hacer, se le puede
+otorgar permiso de escritura en el repositorio, o si lo prefiere,
+puede enviar un parche (patch).  Describimos a continuación los dos
+procedimientos : Repositorio Público y Parches.   Es preferible el
+repositorio público frente a los parches, puesto que estos segundos
+pueden tardar en propagarse más.
+
+== Repositorio Público ==
+Este sería el método preferido para que los cambios que usted haga
+automáticamente queden en el repositorio y todos los traductores
+podamos contar con la información rápidamente.
+
+Una vez que usted haya recibido la información necesaria, habiendo
+elegido su usuario y su clave podrá "publicar" (push).
+
+Como este es un sistema distribuido, después de hacer la
+consignación (commit), deberá publicarlo.
+
+ hg push
+
+Se le solicitará su usuario y clave.
+
+== Parches ==
+Este método exige que alguien reciba el parche y haga manualmente la
+aplicación del mismo, ese alguien es igor@tamarapatino.org por ahora,
+después de haber hecho commit en su repositorio local, revise su log.
+
+ hg log | head
+
+Esta última orden le permitirá establecer la última revisión que se
+consignó en su repositorio local, su identificador de revisión tendrá
+el formato número:hash.   Generaría el archivo 
+/tmp/patchparahgbook.patch con la orden
+
+ hg -o /tmp/patchparahgbook.patch REV
+
+donde REV es el identificador de revisión que debió haber encontrado.
+
+= Traducción/Revisión =
+
+En esta sección indicamos quienes están traduciendo
+y quienes revisando lo traducido. Coloque su nombre 
+para que los demás colaboradores sepan en dónde 
+enfocar sus esfuerzos.
+
+Indique qué archivos está traduciendo y/o revisando en 
+la lista siguiente. Cada archivo debe ser traducido y
+revisado antes de poder considerarlo terminado. El revisor
+no puede ser la misma persona que hizo la traducción.
+
+Cada traductor puede traducir o revisar el archivo que
+desee, teniendo siempre en cuenta los archivos que ya tengan
+alguien a cargo y escogiendo en la medida de lo posible
+otros que no lo tengan. Los arreglos de 'typos' y problemas
+de ortografía son siempre bienvenidos.
+
+== Archivos en proceso de traducción ==
+||'''archivo'''    ||'''traductor'''||'''Estado'''||'''Inicio'''||  '''Fin'''  ||
+|| 00book.tex      || Igor Támara   ||    100%    || 16/10/2008 ||  16/10/2008 ||
+|| preface.tex     || Javier Rojas  ||    100%    || 18/10/2008 ||  19/10/2008 ||
+|| intro.tex       || Igor Támara   ||	  100%	  || 08/11/2008	||  09/11/2008 ||
+|| tour-basic.tex  || Javier Rojas  ||    100%    || 19/10/2008 ||  27/10/2008 ||
+|| tour-merge.tex  || Javier Rojas  ||    100%    || 28/10/2008 ||  03/11/2008 ||
+|| concepts.tex    || Javier Rojas  ||    100%    || 03/11/2008 ||  23/11/2008 ||
+|| daily.tex       || Igor Támara   ||    100%    || 19/10/2008 ||  26/10/2008 ||
+|| collab.tex      || Igor Támara   ||    100%    || 10/11/2008 ||  06/12/2008 ||
+|| filenames.tex   || Javier Rojas  ||    100%    || 27/11/2008 ||  12/01/2008 ||
+|| branch.tex      || Igor Támara   ||    100%    || 16/10/2008 ||  19/10/2008 ||
+|| undo.tex        || Igor Támara   ||    100%    || 26/10/2008 ||  07/11/2008 ||
+|| hook.tex        || Javier Rojas  ||    100%    || 01/12/2008 ||  04/01/2009 ||
+|| template.tex    || Igor Támara   ||    100%    || 27/12/2008 ||  01/01/2009 ||
+|| mq.tex          || Igor Támara   ||    100%    || 06/12/2008 ||  13/12/2008 ||
+|| mq-collab.tex   || Javier Rojas  ||    100%    || 04/01/2009 ||  08/01/2009 ||
+|| hgext.tex       || Igor Támara   ||    100%    || 13/12/2008 ||  16/12/2008 ||
+|| cmdref.tex      || Igor Támara   ||    100%    || 01/01/2009 ||  01/01/2009 ||
+|| mq-ref.tex      || Igor Támara   ||    100%    || 06/01/2009 ||  10/01/2009 ||
+|| srcinstall.tex  || Igor Támara   ||    100%    || 01/01/2009 ||  01/01/2009 ||
+|| license.tex     || Igor Támara   ||    100%    || 16/12/2008 ||  16/12/2008 ||
+
+== Archivos en proceso de revisión ==
+||'''archivo'''   || '''revisor''' ||'''Estado'''||'''Inicio'''||  '''Fin'''  ||
+|| 00book.tex     || Javier Rojas  ||    100%    || 18/01/2009 ||  18/01/2009 ||
+|| branch.tex     || Javier Rojas  ||    100%    || 25/01/2009 ||  25/01/2009 ||
+|| preface.tex    ||               ||            ||            ||             ||
+|| daily.tex      || Javier Rojas  ||    100%    || 25/01/2009 ||  29/01/2009 ||
+|| tour-basic.tex ||               ||            ||            ||             ||
+|| undo.tex       || Javier Rojas  ||            ||            ||             ||
+|| tour-merge.tex ||               ||            ||            ||             ||
+|| concepts.tex   ||               ||            ||            ||             ||
+|| intro.tex      || Javier Rojas  ||    100%    || 12/01/2009 ||  12/01/2009 ||
+|| collab.tex     || Javier Rojas  ||      0%    || 29/01/2009 ||             ||
+|| mq.tex         ||               ||            ||            ||             ||
+|| hgext.tex      ||               ||            ||            ||             ||
+|| template.tex   ||               ||            ||            ||             ||
+|| mq-collab.tex  ||               ||            ||            ||             ||
+|| mq-ref.tex     ||               ||            ||            ||             ||
+|| cmdref.tex     ||               ||            ||            ||             ||
+|| license.tex    ||               ||            ||            ||             ||
+|| srcinstall.tex ||               ||            ||            ||             ||
+
+== Archivos terminados ==
+||'''archivo'''   ||'''Inicio'''||  '''Fin'''  ||
+|| 00book.tex     || 16/10/2008 ||  18/01/2009 ||
+|| intro.tex      || 08/11/2008 ||  12/01/2009 ||
+|| branch.tex     || 16/10/2008 ||  25/01/2009 ||
+|| daily.tex      || 19/10/2008 ||  29/01/2009 ||
+
+= Unificación de Términos de Traducción =
+Por favor mantenga esta lista en orden alfabético
+
+La mayor parte del texto a continuación fue tomado del glosario de la
+traducción del libro de subversion al idioma español.
+
+Pequeño glosario de términos traducidos. Aquí deben ponerse esos
+"bonitos palabros" que tanto nos ha costado traducir para evitar
+inconsistencias en la traducción por varias personas. Normalmente
+son técnicos, pero puede incluirse cualquier "giro" o expresión que
+consideremos útil mantener y repetir a lo largo de la traducción.
+En el libro final posiblemente se añada una versión de este fichero
+como apéndice.
+
+Para incluir algo, hay que especificar la expresión en inglés, su
+versión traducida, y una pequeña explicación como justificación.
+
+ Alice: Alicia
+ Anne: Ana
+ Back out: Retroceder
+ Binary test: Prueba binaria
+ Bob : Roberto
+ Branch: Rama
+ Bug: Fallo
+ Build Script: Guión de construcción
+ Builtin: integrada/o
+ Bundle: Agrupamiento 
+ Bundled: Incluído o agrupado
+ Changelog: Bitácora de Cambios
+ Changeset: Conjunto de Cambios
+ Command: Orden
+ Commit: Consignar
+ Core: alma
+ Directory: Directorio
+ Escape Sequence: Secuencia de control
+ File: fichero
+ Filelog: fichero de registro
+ Fold: Integrar
+ Fork: Bifurcación
+ Hash: No se traduce
+ Head: Principal. En el contexto de revisiones HEAD se sugiere usar "frente"
+ Hook: Gancho
+ Merge: Fusión
+ Milestone: Etapa
+ Mistake: Equivocación, cometida por un humano
+ Output: salida o despliegue
+ Patch: Parche
+ Path: Ruta de archivo
+ Pointer: apuntador
+ Pop: Sustraer, la contraparte push, será publicar
+ Probe: Sondeo
+ Pull: Jalar
+ Push: Publicar.  En el contexto de parches introducir.
+ Queue: Cola
+ Release: Versión o liberación de versión
+ Revlog: Bitácora de revisiones
+ Roll back: NO se traduce Ver más abajo
+ Snapshot: instantánea
+ Snippet: Recorte de código
+ Stack: pila
+ Stripped: 
+ Sprint: sprint
+ Tarball: paquete de cambios
+ Timestamp : marca de tiempo
+ Tip: punta
+ Update: actualización
+ Upstream: principal, mantenedor principal. De acuerdo al contexto.
+
+abort -> cancelar
+
+ancestry -> ascendencia
+    La traducción literal concuerda con el significado que se le
+    da al mismo término en la jerga de Subversion.
+
+API, GUI -> no se traduce
+    La primera vez que aparecen, poner nota del traductor indicando
+    qué significan las siglas y su traducción al castellano. De
+    hecho, verificar la aparición de las notas de traductor en el
+    sitio correcto debería ser una entrada del fichero TODO...
+
+back-end -> ???
+    Se refiere al término opuesto de front-end. En el octavo
+    capítulo se usa al menos tres veces para referirse al "motor"
+    que hay detrás de la capa de base de datos. Hmmm... pero motor
+    suena raro...
+
+backup -> copia de seguridad
+    Obtenido del glosario ORCA.
+
+Blanket Access Control -> Control de acceso simple
+    Por ahora no se me ocurre mejor traducción. Aquí blanket se
+    refiere a un control muy genérico, con poca granularidad.
+
+branching and merging -> crear ramas y fusionarlas
+    Aunque branch está bien traducido como rama o rama de desarrollo
+    (en su versión "verbose"), no hay forma de hacer de un sustantivo
+    un verbo.  Por lo tanto, se crean, borran y fusionan ramas.
+
+browse -> navegar
+    Usado con frecuencia para navegar por directorios o repositorios.
+
+build -> comodín
+    No es que se traduzca como comodín, sino que en función del
+    contexto es una de esas palabras que significan muchas cosas y
+    no es posible traducirla literalmente. Por ejemplo, cuando se
+    usa como verbo se suele referir a compilar código fuente. En
+    cambio, cuando se usa como sustantivo se suele referir a una
+    versión particular del fichero binario ejecutable de un software,
+    resultado de una compilación previa. Cuidado con esto. Anotar
+    aquí traducciones realizadas para comparar.
+
+        ...using and building Subversion...
+        ...usando y compilando Subversion...
+
+changeset -> ???
+    Aparentemente conjunto de cambios. No puede ser traducido
+    como parche, el libro inglés indica que un "changeset" es un
+    parche con nombre único. Por ahora dejar en "changeset", ya se
+    buscará algo en el futuro. Para ver la descripción del libro,
+    buscar en ch04.xml la frase "Subversion y los changesets".
+
+cheap copy -> copia ligera
+    Otras posibilidades barajadas son copia barata o liviana.
+    Veremos si en el futuro éstas suenan mejor.
+
+click -> haga clic, pulse
+    Traducción obtenida del glosario. Parece ser que click sólo se
+    deja tal cual cuando se refiere a un sonido mecánico. Cuando
+    se refiere a pulsar el botón del ratón se traduce como clic.
+
+CVS -> No se traduce
+
+DAV share -> recurso DAV compartido
+    No tengo ni idea de lo que es un DAV share, así que cuando me
+    entere (o alguien lo haga), que cambie esta entrada del glosario.
+
+directory -> directorio
+    Entre carpeta y directorio se prefiere directorio.
+
+email -> correo electrónico
+    Entre las posibilidades de dejar la palabra tal cual, añadir un
+    guión (e-mail) y poner la traducción, se prefiere la traducción
+    completa.
+
+FAQ -> FAQ
+    Se deja tal cual pues se explica en el primer párrafo del prólogo
+    como una nota del traductor, y porque es muy frecuente ver su
+    uso en español. PyRF, PUFs o PFs son realmente desconcertantes.
+
+file -> fichero
+    Entre archivo y fichero se prefiere fichero.
+
+file path -> ruta del fichero
+    Cuando se ve path a secas, la forma más común de traducirlo
+    es decir ruta a secas igualmente. Bueno, el glosario de ORCA
+    también da como válidos camino y trayectoria. A ser posible
+    usar ruta si el contexto de la frase así lo favorece, en caso
+    contrario probar con camino o trayectoria.
+
+hash table -> tabla hash
+    Sugerido por Miguel Pérez Ibars. También encontrado en el
+    glosario ORCA.
+
+history -> Depende del contexto. Cuando se use en el contexto del repositorio
+    (the history of the repository), debe usarse el término historial. En otro
+    caso, historia. Valga anotar que ambas traducciones son aceptadas (al menos
+    en wordreference.com).
+
+hook, to hook -> gancho, enganchar
+    Usado en terminología de programación para indicar que el usuario
+    tiene un mecanismo estándar para modificar el comportamiento de
+    un dispositivo existente. Un ejemplo a nivel de programación
+    son las funciones "callback" que se pasan como parámetros,
+    o a nivel de sistema, scripts que existen en un directorio
+    concreto y que se ejecutan por el servidor de Subversion para
+    realizar tareas personalizadas por el administrador.
+
+ignore pattern -> ignorar patrones, pero patrones de exclusión
+    Subversion permite que ciertas opciones almacenen patrones
+    con los que se ignoran ficheros no versionados. Cuando la
+    frase original usa el verbo, se puede traducir como ignorar
+    directamente, pero cuando se usa a modo de sustantivo,
+    es mejor traducirlo como "patrón de exclusión" en lugar de
+    "patrón a ignorar".
+
+language -> lenguaje o idioma
+    Precisamente para diferenciar si nos estamos refiriendo a un
+    lenguaje de programación o a un lenguaje hablado por humanos,
+    se usará idioma en este último caso.
+
+language binding, SWIG binding, wrapper -> interfaz, enlace, ligadura, envoltorio...
+    Dependiendo del contexto, y desde un punto de vista personal,
+    se puede traducir esta palabra de muchas maneras. Una manera
+    genérica es decir "Interfaz con el lenguaje X", o "Ligadura con
+    el lenguaje X". Habitualmente, cuando se habla de una interfaz,
+    se está hablando de un binding ligero, o que únicamente permite
+    a hacer llamadas a funciones del lenguaje de programación A
+    desde el lenguaje de programación B.
+
+    En cambio, se suele hablar de wrapper cuando el código entre
+    el lenguaje A y B es algo más complejo, o adapta el estilo de
+    programación del lenguaje A al del lenguaje B. Un ejemplo de esto
+    último sería una librería en C cuyo binding en Perl/Ruby/Python
+    fuese orientado a objetos.
+
+    Aparte, wrapper también se usa cuando se habla de una función
+    o librería que engloba o asimila otra menor, con el propósito
+    de extender su funcionalidad o hacerla más fácil de usar
+    de cara al usuario, sin necesidad de cruzar ninguna barrera
+    "intra-lenguaje".
+
+    Por lo tanto, hay que decidir con cuidado el contexto de la
+    palabra binding o wrapper, y escoger una. En el capítulo octavo
+    hay varios usos, aunque como son relativos a SWIG, se habla de
+    interfaces o envoltorios simplificados, puesto que se generan
+    de manera automática y no hay ninguna "conversión" en el estilo
+    de uso.
+
+lazy copy -> copia vaga
+    Horrible traducción literal. ¿Sugerencias?
+    copia perezosa
+
+location (repository) -> ubicación (del repositorio)
+    Cuidado, no traducir como localización, que es la acción y
+    efecto de localizar.
+
+log, log message -> informe de cambios, mensaje del informe de cambios
+    Traducción extraída del manual de CVS en español. La traducción
+    de "log message" es muy larga, pero únicamente porque no se
+    tiene contexto alguno. Con contexto suele ser posible omitir
+    la palabra informe si se considera apropiado.
+
+memory pool -> área de memoria
+    Traducción temporal hasta que se revise algún libro en castellano
+    de programación que use el mismo término.
+
+merge -> fusionar cambios, fusión
+    Obtenida referencia del manual de CVS en castellano, la otra
+    alternativa obvia para traducir merge es mezclar. No obstante,
+    mezclar tiene una connotación de azar al realizar la mezcla. Se
+    mezclan líquidos, ingredientes, etc. En cambio, un "merge" es
+    cualquier cosa menos un proceso realizado al azar (especialmente
+    si ha habido conflictos). En caso de traducir como sustantivo,
+    fusión vuelve a "sonar mejor" que mezcla, que por alguna razón me
+    suena a un combustible especial usado en vehículos de transporte.
+
+namespace -> espacio de nombrado,
+    Tecnicismo del C++, obtenido de la traducción del libro
+    "Pensar en C++", en concreto la sección 3.2 disponible en
+    http://arco.inf-cr.uclm.es/~dvilla/pensar_en_C++/ch02s03.html#id2589039.
+
+open source -> código fuente abierto
+    Referencia: http://es.tldp.org/ORCA/glosario.html#O
+
+plugins -> módulos
+    El término fue extraído del glosario de ORCA.
+
+repository -> repositorio
+    No hay mucha alternativa, ¿verdad?
+
+roll back -> No se traduce 
+    El significado igual que en los ambientes
+     de sistemas manejadores de bases de datos se refiere a la atomicidad
+     e integridad al devolver un conjunto de acciones que permitan dejar
+     el repositorio en un estado consistente previo.
+
+repository layou t-> estructura del repositorio En referencia a cómo
+    están organizados los directorios.
+
+schedule -> programa o planifica
+    Parece más correcta la opción programa, en el sentido de pensar en
+    hacer algo.
+    schedule foo to be added -> programa la adición de foo
+
+switch -> cambiar
+    Únicamente cuando se habla del comando svn switch, no como la
+    palabra switch aislada, que significa parámetro o interruptor.
+    En el contexto de svn switch, traducirlo como cambiar. Quizás
+    traducir como reubicar una vez haya suficiente material traducido
+    y una lectura final sugiera una u otra traducción.
+
+tag, tagging -> etiqueta, etiquetar
+    Expresión ya común en español.
+
+three-way differencing program -> programa de diferenciación a tres bandas
+    Una diferenciación "normal" es generar las diferencias entre
+    dos ficheros.  Una diferenciación a tres bandas es comparar las
+    diferencias entre tres ficheros, y se usa cuando se intentan
+    fusionar los cambios de una copia local junto con los cambios
+    recibidos del repositorio (por ejemplo, otra persona ha cambiado
+    el fichero sobre el que trabajábamos).
+
+timestamp, datestamp -> marca de tiempo, fecha y hora
+    Esa traducción viene del ORCA. No obstante en muchos casos es
+    más claro traducirla como "fecha de fichero" o "fecha" a secas.
+    Ejemplo: ...will show the modification timestamp. -> mostrará
+    la fecha de modificación. Decir "mostrará la marca de tiempo de
+    la modificación" o algo así es una traducción demasiado literal,
+    así que ojo con el contexto.
+
+track -> seguir, monitorear
+    este término suele ser usado cuando se habla de archivos, y de llevar la 
+    pista o monitorear los cambios en un archivo.
+
+trunk -> tronco
+    Se refiere al nombre que recibe la línea de desarrollo
+    principal del repositorio que no está asociada a ninguna rama
+    en particular. Traducción obtenida del manual de CVS en español.
+
+Unix-like systems -> sistemas tipo unix
+
+URL -> No se traduce
+
+working copy -> copia (de trabajo) local/activa
+    Traducción similar a la de "commit data" (razonamiento
+    cliente-servidor).
+
+= Términos a no-usar =
+Evite el uso de estos términos en la traducción aún si son de uso
+común para usted; el consenso general de la comunidad hispana puede
+ser diferente del que usted tenga ;)
+
+  * "archivo". Use "fichero" en su lugar.
+  * "carpeta". Use "directorio".
+  * "la historia". Use "el historial" (por supuesto, cuando se refiera al
+  historial del repositorio)
+
+= Diferencias de redacción =
+Hay varias expresiones que pueden terminar siendo traducidas de formas
+diferentes por los traductores, y que aún siendo ambas correctas, ponen en
+evidencia que el trabajo fue llevado a cabo por varias personas y que el estilo
+que ellas usan difiere. Una vez terminada la traducción habrá que buscar cuáles
+son éstos términos y decidirse por uno solo de ellos. A continuación se presenta
+una lista de los términos o expresiones encontrados hasta ahora
+
+  * comando - orden. Ambos son la traducción para "command". Parece que la
+  traducción más adecuada es "comando"
+  (http://www.wordreference.com/es/translation.asp?tranword=command)
+  * kernel - núcleo.
+  * Colas de Mercurial - colas de Mercurial. Creo que lo mejor es revisar qué
+  usó el autor (y rogar que él no haya sido inconsistente :P)
+  * armar - compilar - construir. Build, compile. Más que todo "build"
+  * daemonio - demonio. daemon
+  * kernel - núcleo.
+  * la URL - el URL
+
+= Notas del traductor =
+Por favor use el comando \ndt para insertar notas del traductor. Este
+comando requiere un argumento. Por ejemplo: \ndt{Del inglés del original.}
+
+= Para compilar =
+He aquí algunas dependencias para Debian:
+
+apt-get install texlive-latex-extra tex4ht diffstat patchutils \ 
+   inkscape graphviz texlive-pdfetex
+
+= Traductores =
+Por favor mantenga esta lista en orden alfabético de acuerdo al
+apellido.
+
+ * Javier Rojas <jerojasro@devnull.li>
+ * Igor Támara <igor@tamarapatino.org>
+ * Su nombre <su@e.mail>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/Makefile	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,223 @@
+# 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 \
+	../html/index.es.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}, fechado {date|isodate},\n')
+
+hg-version = $(shell hg version -q | \
+		     sed 's,.*(versión \(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 html/onepage/hgbook.html dist/onepage.html
+	ln -s index.es.html dist/index.html
+	cp $(dist-sources) dist
+
+rsync: install
+	rsync -avz --delete dist/ ikks@sulaco.devnull.li:public_html/hgbook/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/bookhtml.cfg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/bookhtml.cfg
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/branch.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,412 @@
+%% vim: tw=70 encoding=utf8
+\chapter{Administración de versiones y desarrollo ramificado}
+\label{chap:branch}
+
+Mercurial ofrece varios mecanismos que le permiten administrar un
+proyecto que avanza en múltiples frentes simultáneamente. Para
+entender estos mecanismos, demos un vistazo a la estructura usual de
+un proyecto de software.
+
+Muchos proyectos de software liberan una versión ``mayor'' que contiene
+nuevas características substanciales.  En paralelo, pueden liberar
+versiones ``menores''.   Usualmente éstas son idénticas a las
+versiones mayores en las cuales están basadas, pero con arreglos para
+algunos fallos.
+
+En este capítulo, comenzaremos hablando de cómo mantener registro de
+etapas del proyecto como las liberaciones de una
+versión. Continuaremos hablando del flujo de trabajo entre las
+diferentes fases de un proyecto, y cómo puede ayudar Mercurial a
+aislar y administrar tal trabajo.
+
+\section{Dar un nombre persistente a una revisión}
+
+Cuando usted decide otorgar a una revisión el nombre particular de una
+``versión'', es buena idea grabar la identidad de tal revisión.
+Esto le permitirá reproducir dicha versión en una fecha posterior,
+para cualquiera que sea el 
+propósito que se tenga en ese momento (reproducir un fallo, portar
+a una nueva plataforma, etc).
+\interaction{tag.init}
+
+Mercurial le permite dar un nombre permanente a cualquier revisión
+usando la orden \hgcmd{tag}.  Sin causa de sorpresa, esos nombres se llaman
+``tags'' (etiquetas).
+\interaction{tag.tag}
+
+Una etiqueta no es más que un ``nombre simbólico'' para una revisión.  Las
+etiquetas existen únicamente para su conveniencia, brindándole una forma
+permanente y sencilla de referirse a una revisión; Mercurial no
+interpreta de ninguna manera los nombres de las etiquetas que usted use.
+Mercurial tampoco impone restricción alguna al nombre de una etiqueta, más
+allá de lo necesario para asegurar que una etiqueta pueda procesarse sin
+ambigüedades. El nombre de una etiqueta no puede tener ninguno de los
+siguientes caracteres:
+\begin{itemize}
+\item Dos puntos (ASCII 58, ``\texttt{:}'')
+\item Retorno de carro (return) (ASCII 13, ``\Verb+\r+'')
+\item Nueva línea (ASCII 10, ``\Verb+\n+'')
+\end{itemize}
+
+Puede usar la orden \hgcmd{tags} para ver las etiquetas presentes en
+su repositorio. Al desplegarse, cada revisión marcada se identifica
+primero con su nombre, después con el número de revisión y finalmente con
+un hash único de la revisión.
+\interaction{tag.tags}
+Note que \texttt{tip} aparece en en listado generado por \hgcmd{tags}. La etiqueta
+\texttt{tip} es una etiqueta ``flotante'' especial, que identifica siempre
+la revisión más reciente en el repositorio.
+
+Al desplegar la orden \hgcmd{tags}, las etiquetas se listan en orden
+inverso, por número de revisión. Lo que significa usualmente que las
+etiquetas más recientes se listan antes que las más antiguas. También
+significa que la etiqueta \texttt{tip} siempre aparecerá como primera
+etiqueta listada al desplegar la orden \hgcmd{tags}.
+
+Cuando usted ejecuta \hgcmd{log}, si se muestra una revisión que tenga 
+etiquetas asociadas a ella, se imprimirán tales etiquetas.
+\interaction{tag.log}
+
+Siempre que requiera indicar un~ID de revisión a una orden de
+Mercurial, aceptará un nombre de etiqueta en su lugar.  Internamente,
+Mercurial traducirá su nombre de etiqueta en el~ID de revisión
+correspondiente, y lo usará.
+\interaction{tag.log.v1.0}
+
+No hay límites en la cantidad de etiquetas por repositorio, o la cantidad
+de etiquetas que una misma revisión pueda tener. Siendo prácticos, no es
+muy buena idea tener ``demasiadas'' (la cantidad variará de un
+proyecto a otro), debido a que la intención es ayudarle a encontrar
+revisiones. Si tiene demasiadas etiquetas, la facilidad de usarlas
+para identificar revisiones disminuirá rápidamente.
+
+Por ejemplo, si su proyecto tiene etapas (milestones) frecuentes, de pocos
+días, es perfectamente razonable asignarle una etiqueta a cada una de
+ellas. Pero si tiene un sistema de construcción automática de binarios
+que asegura que cada revisión puede generarse limpiamente, estaría
+introduciendo mucho ruido si se usara una etiqueta para cada generación
+exitosa. Más bien, podría usar tags para generaciones fallidas
+(\textexclamdown en
+caso de que estas sean raras!), o simplemente evitar las etiquetas para
+llevar cuenta de la posibilidad de generación de binarios.
+
+
+Si quiere eliminar una etiqueta que no desea, use
+\hgcmdargs{tag}{--remove}.  
+\interaction{tag.remove}
+También puede modificar una etiqueta en cualquier momento, para que
+identifique una revisión distinta, simplemente usando una nueva orden
+\hgcmd{tag}. Deberá usar la opción \hgopt{tag}{-f} para indicarle a
+Mercurial que \emph{realmente} desea actualizar la etiqueta.
+\interaction{tag.replace}
+De todas maneras habrá un registro permanente de la antigua identidad
+de la etiqueta, pero Mercurial no la usará. Por lo tanto no hay
+problema al marcar con una etiqueta una revisión incorrecta; lo único
+que debe hacer es mover la etiqueta hacia la revisión correcta tan
+pronto como localice el error.
+
+Mercurial almacena las etiquetas en un fichero controlado por revisiones en
+su repositorio. Si ha creado etiquetas, las encontrará en un fichero
+llamado \sfilename{.hgtags}.  Cuando invoca la orden \hgcmd{tag},
+Mercurial modifica este fichero, y hace la consignación del cambio al
+mismo automáticamente.  Esto significa que cada vez que ejecuta
+\hgcmd{tag}, verá un conjunto de cambios correspondiente en la salida
+de \hgcmd{log}.
+\interaction{tag.tip}
+
+\subsection{Manejo de conflictos entre etiquetas durante una fusión}
+
+Usualmente no tendrá que preocuparse por el fichero \sfilename{.hgtags},
+pero a veces hace su aparición durante una fusión. El formato del
+fichero es sencillo: Consiste de una serie de líneas. Cada línea
+comienza con un hash de conjunto de cambios, seguido por un espacio,
+seguido por el nombre de una etiqueta.
+
+Si está resolviendo un conflicto en el fichero \sfilename{.hgtags}
+durante una fusión, hay un detalle para tener en cuenta al modificar
+el fichero \sfilename{.hgtags}:
+cuando Mercurial procesa las etiquetas en el repositorio, \emph{nunca}
+lee la copia de trabajo del fichero \sfilename{.hgtags}.  En cambio,
+lee la versión \emph{consignada más reciente} del fichero.
+
+Una consecuencia desafortunada de este diseño es que usted no puede
+verificar que su fichero \sfilename{.hgtags} fusionado sea correcto hasta
+\emph{después} de haber consignado un cambio. Así que si se
+encuentra resolviendo un conflicto en \sfilename{.hgtags} durante una
+fusión, asegúrese de ejecutar la orden \hgcmd{tags} después de
+consignar. Si encuentra un error en el fichero \sfilename{.hgtags}, 
+la orden reportará el lugar del error, que podrá arreglar y después
+consignar. Posteriormente ejecute de nuevo la orden \hgcmd{tags} para
+asegurarse de que su arreglo fue aplicado correctamente .
+
+\subsection{Etiquetas y clonado}
+
+Puede haber notado que la orden \hgcmd{clone} tiene la opción
+\hgopt{clone}{-r} que le permite clonar una copia exacta del
+repositorio hasta un conjunto de cambios específico. El nuevo clon no
+tendrá historial posterior a la revisión que usted haya
+especificado. Esto tiene una interacción con etiquetas que puede
+sorprender a los desprevenidos.
+
+Recuerde que una etiqueta se almacena como una revisión al fichero
+\sfilename{.hgtags}, así que cuando usted crea una etiqueta, el
+conjunto de cambios en el cual ésta se almacena necesariamente se
+refiere a un conjunto de cambios anterior. Cuando ejecuta
+\hgcmdargs{clone}{-r foo} para clonar un repositorio hasta la etiqueta
+\texttt{foo}, el nuevo clon \emph{no contendrá el historial que creo
+la etiqueta} que usó para clonar el repositorio. El resultado es que tendrá
+exactamente el subconjunto correcto del historial del proyecto en el
+nuevo repositorio, pero, \emph{no} la etiqueta que podría haber esperado.
+
+\subsection{Cuando las etiquetas permanentes son demasiado}
+
+Dado que las etiquetas de Mercurial están controladas por revisiones y se
+llevan en el historial del proyecto, todas las personas involucradas
+verán las etiquetas que usted haya creado. El hecho de dar nombres a las
+revisiones tiene usos más allá que simplemente hacer notar que la
+revisión \texttt{4237e45506ee} es realmente \texttt{v2.0.2}.  Si está
+tratando de encontrar un fallo sutil, posiblemente desearía colocar una 
+etiqueta recordándole algo como ``Ana vio los síntomas en esta revisión''.
+
+Para estos casos, lo que usted posiblemente desearía serían etiquetas
+\emph{locales}. Puede crear una etiqueta local con la opción~\hgopt{tag}{-l}
+de la orden \hgcmd{tag}.  Esto guardará la etiqueta en un fichero llamado
+\sfilename{.hg/localtags}.  A diferencia de \sfilename{.hgtags},
+\sfilename{.hg/localtags} no está controlado por revisiones.
+Cualquier etiqueta que usted cree usando \hgopt{tag}{-l} se mantendrá
+local al repositorio en el que esté trabajando en ese momento.
+
+\section{El flujo de cambios---El gran cuadro vs. el pequeño}
+
+Retomando lo mencionado en el comienzo de un capítulo, pensemos en el
+hecho de que un proyecto tiene muchas piezas concurrentes de trabajo
+en desarrollo al mismo tiempo.
+
+Puede haber prisa por una nueva versión ``principal''; una nueva
+versión con un arreglo de fallo a la última versión; y una versión de
+``mantenimiento correctivo'' a una versión antigua que ha entrado en
+modo de mantenimiento.
+
+Usualmente la gente se refiere a esas direcciones
+concurrentes de desarrollo como ``ramas''.  Sin embargo, ya hemos visto que
+en varias ocasiones Mercurial trata a \emph{todo el historial} como
+una serie de ramas y fusiones.  Realmente lo que tenemos aquí es dos
+ideas que se relacionan periféricamente, pero que en esencia comparten
+un nombre.
+\begin{itemize}
+\item ``El gran cuadro'' Las ramas representan un barrido de la
+  evolución del proyecto; la gente les da nombres y hablan acerca de
+  ellas en sus conversaciones.
+\item ``El cuadro pequeño'' Las ramas son artefactos de las
+  actividades diarias de desarrollar y fusionar cambios. Exponen la
+  narrativa de cómo se desarrolló el código.
+\end{itemize}
+
+\section{Administrar ramas en repositorios estilo gran cuadro}
+
+En Mercurial la forma más sencilla de aislar una rama del ``gran
+cuadro'' es a través de un repositorio dedicado.  Si cuenta con un
+repositorio compartido existente ---llamémoslo
+\texttt{myproject}---que alcanzó la etapa ``1.0'', puede comenzar a
+prepararse para versiones de mantenimiento futuras a partir de la
+versión~1.0 marcando con una etiqueta la revisión con la cual preparó la versión~1.0.
+\interaction{branch-repo.tag}
+Ahora puede clonar un repositorio compartido nuevo
+\texttt{myproject-1.0.1} con tal etiqueta.
+\interaction{branch-repo.clone}
+
+Posteriormente, si alguien necesita trabajar en la reparación de un
+fallo debería dirigirse a la liberación de versión~1.0.1 que viene en
+camino, ellos clonarían el repositorio \texttt{myproject-1.0.1},
+harían sus cambios y los empujarían de vuelta.
+\interaction{branch-repo.bugfix}
+Mientras tanto, el desarrollo para la siguiente versión mayor puede
+continuar aislado e incólume, en el repositorio \texttt{myproject}.
+\interaction{branch-repo.new}
+
+\section{No repita trabajo: fusión entre ramas}
+
+En muchos casos, cuando tiene un fallo para arreglar en una rama de
+mantenimiento, es muy probable que el fallo también esté en la rama
+principal (y posiblemente en otras ramas de mantenimiento
+también). Solamente un desarrollador extraño desearía corregir el
+mismo fallo muchas veces, por tanto, veremos varias alternativas con
+las que Mercurial puede ayudarle a administrar tales arreglos de fallo
+sin duplicar su trabajo.
+
+En el caso más sencillo, basta con jalar los cambios de la rama de
+mantenimiento a la rama objetivo en su clon local.
+\interaction{branch-repo.pull}
+A continuación deberá mezclar las cabezas de las dos ramas, y empujar
+de nuevo a la rama principal.
+\interaction{branch-repo.merge}
+
+\section{Nombrar ramas dentro de un repositorio}
+
+La aproximación correcta en casi todas las oportunidades es aislar las
+ramas en los repositorios.  Es fácil de entender gracias a su
+simplicidad; y es difícil cometer errores. Hay una relación uno a uno
+entre las ramas y los directorios con los que está trabajando en su
+sistema. Esto le permite usar emplear herramientas usuales (que no son
+conscientes de Mercurial) para trabajar con los ficheros dentro de una
+rama/repositorio.
+
+Si se encuentra más en la categoría ``usuario diestro'' (\emph{y} sus
+colaboradores también), puede considerar otra alternativa para
+administrar las ramas. He mencionado con anterioridad la distinción a
+nivel humano entre las ramas estilo ``cuadro pequeño'' y ``gran
+cuadro''.  Mientras que Mercurial trabaja con muchas ramas del estilo
+``cuadro pequeño'' en el repositorio todo el tiempo (por ejemplo cuando
+usted jala cambios, pero antes de fusionarlos), \emph{también} puede
+trabajar con varias ramas del ``cuadro grande''.
+
+El truco para trabajar de esta forma en Mercurial se logra gracias a
+que puede asignar un \emph{nombre} persistente a una rama.  Siempre
+existe una rama llamada \texttt{default}.  Incluso antes de que
+empiece a nombrar ramas por su cuenta, puede encontrar indicios de la
+rama \texttt{default} si los busca.
+
+Por ejemplo, cuando invoca la orden \hgcmd{commit}, y se lanza su
+editor para introducir el mensaje de la consignación, busque la línea
+que contiene el texto ``\texttt{HG: branch default}'' al final. Le
+está indicando que su consignación ocurrirá en la rama llamada 
+\texttt{default}.
+
+Use la orden \hgcmd{branches} para empezar a trabajar con ramas
+nombradas. Esta orden mostrará las ramas presentes en su repositorio,
+indicándole qué conjunto de cambios es la punta de cada una.
+\interaction{branch-named.branches}
+Dado que todavía no ha creado ramas nombradas, la única que verá será
+\texttt{default}.
+
+Para hallar cuál es la rama ``actual'', invoque la orden
+\hgcmd{branch}, sin argumento alguno. Le informará en qué rama se
+encuentra el padre del conjunto de cambios actual.
+\interaction{branch-named.branch}
+
+Para crear una nueva rama, invoque la orden \hgcmd{branch} de
+nuevo. En esta oportunidad, ofrezca un argumento: el nombre de la rama
+que desea crear.
+\interaction{branch-named.create}
+
+Después de crear la rama, usted podría desear ver el efecto que tuvo
+la orden \hgcmd{branch}.  ¿Qué reportan las ordenes \hgcmd{status} y
+\hgcmd{tip}?
+\interaction{branch-named.status}
+Nada cambia en el directorio actual, y no se ha añadido nada al
+historial. Esto sugiere que al ejecutar la orden \hgcmd{branch} no hay
+un efecto permanente; solamente le indica a que nombre de rama usará
+la \emph{próxima} vez que consigne un conjunto de cambios.
+
+Cuando consigna un cambio, Mercurial almacena el nombre de la rama en
+la cual consignó.  Una vez que haya cambiado de la rama \texttt{default}
+y haya consignado, verá que el nombre de la nueva rama se mostrará
+cuando use la orden \hgcmd{log}, \hgcmd{tip}, y otras órdenes que
+desplieguen la misma clase de información.
+\interaction{branch-named.commit}
+Las órdenes del tipo \hgcmd{log} imprimirán el nombre de la rama de
+cualquier conjunto de cambios que no esté en la rama
+\texttt{default}. Como resultado, si nunca usa ramas nombradas, nunca
+verá esta información.
+
+Una vez que haya nombrado una rama y consignado un cambio con ese
+nombre, todas las consignaciones subsecuentes que desciendan de ese
+cambio heredarán el mismo nombre de rama. Puede cambiar el nombre de
+una rama en cualquier momento con la orden \hgcmd{branch}.  
+\interaction{branch-named.rebranch}
+Esto es algo que no hará muy seguido en la práctica, debido que los
+nombres de las ramas tienden a tener vidas largas.  (Esto no es una
+regla, solamente una observación.)
+
+\section{Tratamiento de varias ramas nombradas en un repositorio}
+
+Si tiene más de una rama nombrada en un repositorio, Mercurial
+recordará la rama en la cual está su directorio de trabajo cuando
+invoque una orden como \hgcmd{update} o \hgcmdargs{pull}{-u}.  Se
+actualizará su directorio de trabajo actual a la punta de esta rama, sin
+importar cuál sea la punta ``a lo largo del repositorio''.  Para
+actualizar a una revisión que está en una rama con distinto nombre,
+puede necesitar la opción \hgopt{update}{-C} de \hgcmd{update}.
+
+Este comportamiento puede ser sutil, así que veámoslo en acción.  Primero,
+recordemos en qué rama estamos trabajando, y qué ramas están en
+nuestro repositorio.
+\interaction{branch-named.parents}
+Estamos en la rama \texttt{bar}, pero existe otra rama más antigua
+llamada \hgcmd{foo}.
+
+Podemos hacer \hgcmd{update} entre los tipos de las ramas \texttt{foo}
+y \texttt{bar} sin necesidad de usar la opción \hgopt{update}{-C},
+puesto que esto solamente implica ir linealmente hacia adelante y
+atrás en nuestro historial de cambios.
+\interaction{branch-named.update-switchy}
+
+Si volvemos a la rama \texttt{foo} e invocamos la orden \hgcmd{update},
+nos mantendrá en \texttt{foo}, sin movernos a la punta de \texttt{bar}.
+\interaction{branch-named.update-nothing}
+
+Al consignar un cambio a la rama \texttt{foo} se introducirá una nueva
+cabeza.
+\interaction{branch-named.foo-commit}
+
+\section{Nombres de ramas y fusiones}
+
+Posiblemente ha notado que las fusiones en Mercurial no son simétricas.
+Supongamos que su repositorio tiene dos cabezas, 17 y 23.  Si yo invoco
+\hgcmd{update} a 17 y aplico \hgcmd{merge} a 23, Mercurial almacena 17
+como el primer padre de la fusión, y 23 como el segundo. Mientras que
+si hago \hgcmd{update} a 23 y después aplico \hgcmd{merge} con 17,
+grabará a 23 como el primer padre, y 17 como el segundo.
+
+Esto afecta el cómo elige Mercurial el nombre de la rama cuando usted
+hace la fusión.  Después de una fusión, Mercurial mantendrá el nombre de la
+rama del primer padre cuando consigne el resultado de la fusión.  Si
+el primer nombre de su padre es \texttt{foo}, y fusiona con
+\texttt{bar}, el nombre de la rama continuará siendo \texttt{foo}
+después de fusionar.
+
+No es inusual que un repositorio contenga varias cabezas, cada una con
+el mismo nombre de rama.  Digamos que estoy trabajando en la rama
+\texttt{foo}, y usted también.  Consignamos cambios distintos; yo jalo
+sus cambios; Ahora tengo dos cabezas, cada una afirmando estar en la
+rama \texttt{foo}.  El resultado de una fusión será una única cabeza
+en la rama \texttt{foo} como usted esperaría.
+
+Pero si estoy trabajando en la rama \texttt{bar}, y fusiono el trabajo
+de la rama \texttt{foo}, el resultado permanecerá en la rama
+\texttt{bar}.
+\interaction{branch-named.merge}
+
+En un ejemplo más concreto, si yo estoy trabajando en la rama
+\texttt{bleeding-edge}, y deseo traer los arreglos más recientes de la
+rama \texttt{estable}, Mercurial elegirá el nombre de rama ``correcto''
+(\texttt{bleeding-edge}) cuando yo jale una fusión desde \texttt{estable}.
+
+\section{Normalmente es útil nombrar ramas}
+
+No debería considerar que las ramas nombradas son aplicables
+únicamente en situaciones con muchas ramas de larga vida cohabitando
+en un mismo repositorio.  Son muy útiles incluso en los casos de
+una rama por repositorio.
+
+En el caso más sencillo, dar un nombre a cada rama ofrece un registro
+permanente acerca de en qué conjunto de cambios se generó la rama.
+Esto le ofrece más contexto cuando esté tratando de seguir el
+historial de un proyecto ramificado de larga vida.
+
+Si está trabajando con repositorios compartidos, puede configurar el gancho
+\hook{pretxnchangegroup} para que cada uno bloquee los cambios con
+nombres de rama ``incorrectos'' que están por adicionarse.  Este
+provee una defensa sencilla, pero efectiva, para evitar que la gente
+publique accidentalmente cambios de una rama ``super nueva'' a la rama
+``estable''.  Tal gancho podría verse de la siguiente forma dentro de
+un repositorio compartido de \hgrc.
+\begin{codesample2}
+  [hooks]
+  pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
+\end{codesample2}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/cmdref.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/cmdref.py
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/cmdref.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,186 @@
+\chapter{Referencia de Órdenes}
+\label{cmdref}
+
+\cmdref{add}{Añade ficheros en la próxima consignación}
+\optref{add}{I}{include}
+\optref{add}{X}{exclude}
+\optref{add}{n}{dry-run}
+
+\cmdref{diff}{imprime los cambios en el historial o el directorio actual}
+
+Mostrar las diferencias entre revisiones para ficheros especificados o
+directorios, con el formato unificado diff.  Si desea ver una
+descripción del formato unificado diff, ver la sección~\ref{sec:mq:patch}.
+
+De forma predeterminada, esta orden no imprime las diferencias para
+los ficheros binarios que Mercurial esté siguiendo.  Para controlar
+este comportamiento, vea las opciones \hgopt{diff}{-a} y
+\hgopt{diff}{--git}.
+
+\subsection{Options}
+
+\loptref{diff}{nodates}
+
+Omite la fecha y hora cuando se muestran los encabezados de las
+diferencias.
+
+\optref{diff}{B}{ignore-blank-lines}
+
+No imprime los cambios que solamente insertan o eliminan líneas en
+blanco.  Una línea que contiene espacios en blanco no se considera
+como una línea en blanco.
+
+\optref{diff}{I}{include}
+
+Incluye ficheros y directorios cuyos nombres coinciden con los
+patrones elegidos.
+
+\optref{diff}{X}{exclude}
+
+Excluye los ficheros y directorios cuyos nombres coinciden con los
+patrones elegidos.
+
+\optref{diff}{a}{text}
+
+Si no especifica esta opción, \hgcmd{diff} no mostrará las diferencias
+de los ficheros que detecte como binarios.  Al especificar \hgopt{diff}{-a}
+se forza a \hgcmd{diff} a tratar los ficheros como texto, y generar
+diferencias para todos.
+
+Esta opción es útil para los ficherso que son ``texto en mayor
+medida'' pero que tienen caracteres NUL.  Si lo usa en ficheros que
+contienen muchos datos binarios, la salida será incomprensible.
+
+\optref{diff}{b}{ignore-space-change}
+
+No imprime si el único cambio que en la línea es la cantidad de
+espacio en blanco.
+
+\optref{diff}{g}{git}
+
+Mostrar diferencias compatibles con \command{git}.  XXX reference a format
+description.
+
+\optref{diff}{p}{show-function}
+
+Mostrar el nombre de la función que contiene el código en una porción
+del encabzado usando una heurística simple.  Esta funcionalidad se
+habilita de forma predeterminada, así que la opción \hgopt{diff}{-p}
+no tiene efectos a menos que cambie el valor de
+\rcitem{diff}{showfunc} en la configuración, como en el ejemplo
+siguiente.
+\interaction{cmdref.diff-p}
+
+\optref{diff}{r}{rev}
+
+Especifique una o más revisiones para comparar.  La orden \hgcmd{diff}
+acepta hasta dos opciones \hgopt{diff}{-r} para especificar las
+revisiones a comparar.
+
+\begin{enumerate}
+\setcounter{enumi}{0}
+\item Despliega las diferencias entre la revisión padre y del directorio
+  de trabajo.
+\item Despliega las diferencias entre el conjunto de cambios
+  especificados y el directorio de trabajo.
+\item Despliega las diferencias entre dos conjuntos de cambios
+  especificados.
+\end{enumerate}
+
+Puede especificar dos revisiones usando o bien sea las opciones
+\hgopt{diff}{-r} o la notación de rango.  Por ejemplo, las dos
+especificaciones de revisiones a continuación son equivalentes:
+\begin{codesample2}
+  hg diff -r 10 -r 20
+  hg diff -r10:20
+\end{codesample2}
+
+Cuando especifica dos revisiones, esto tiene significado para
+Mercurial.  Esto significa que \hgcmdargs{diff}{-r10:20} producirá un
+diff que transformará los ficheros desde los contenidos en la revisión
+10 a los contenidos de la revisión 20, mientras que
+\hgcmdargs{diff}{-r20:10} significa lo opuesto:  el diff que
+transformaría los contenidos de los ficheros de la revisión 20 a los
+contenidos de la revisión 10.  No puede invertir el orden de esta
+forma si está haciendo un diff frente al directorio de trabajo.
+
+\optref{diff}{w}{ignore-all-space}
+
+\cmdref{version}{imprime la información de versión y derechos de reproducción}
+
+Esta orden despliega la versión de Mercurial que está usando, y su
+nota de derechos de reproducción.  Hay cuatro clases de cadenas de
+versión posibles:
+\begin{itemize}
+\item La cadena ``\texttt{unknown}''. Esta versión de Mercurial no fue
+  construida en un repositorio de Mercurial, y no puede determinar su
+  propia versión.
+\item Una cadena numérica corta, tal como ``\texttt{1.1}''. Esta es
+  una construcción de una versión de Mercurial que se identifica con
+  una etiqueta específica en el repositorio en el cual fue
+  armada (Esto no significa necesariamente que está ejecutando una
+  versión oficial; alguien pudo haber añadido tal etiqueta a cualquier
+  versión del repositorio en el cual armaron Mercurial).
+\item Una cadena hexadecimal, tal como ``\texttt{875489e31abe}''.
+  Esta es una construcción de una revisión dada de Mercurial.
+\item Una cadena hexadecimal seguida por una fecha, tal como
+  ``\texttt{875489e31abe+20070205}''.  Esta construcción de la
+  revisión de Mercurial fue la construcción de un repositorio que tuvo
+  cambios locales que no han sido consignados.
+\end{itemize}
+
+\subsection{Consejos y trucos}
+
+\subsubsection{¿Por qué difieren los resultados de \hgcmd{diff} y
+  \hgcmd{status}?}
+\label{cmdref:diff-vs-status}
+
+Cuando ejecuta la orden \hgcmd{status}, verá una lista de ficheros
+para los cuales Mercurial almacenará cambios la próxima vez que
+consigne.  Si ejecuta la orden \hgcmd{diff}, verá que imprime
+diferencias solamente para un \emph{subconjunto} de los ficheros que
+\hgcmd{status} liste.  Hay dos posibles razones para este comportamiento:
+
+La primera es que \hgcmd{status} imprime cierta clase de
+modificaciones que \hgcmd{diff} no despliega normalmente.  La orden
+\hgcmd{diff} usualmente despliega diferencias unificadas, las cuales
+no tienen la habilidad de representar algunos cambios que Mercurial
+puede seguir.  Lo más notable es que las diferencias tradicionales no
+pueden representar un cambio acerca de la ejecutabilidad de un
+fichero, pero Mercurial sí almacena esta información.
+
+Si usa la opción \hgopt{diff}{--git} de \hgcmd{diff}, mostrará
+diferencias compatibles con \command{git} que \emph{pueden} desplegar
+esta información adicional.
+
+La segunda razón posible para que \hgcmd{diff} esté imprimiendo
+diferencias para un subconjunto de ficheros de lo que muestra
+\hgcmd{status} es que si usted le invoca sin argumento alguno,
+\hgcmd{diff} imprime diferencias frente al primer padre del directorio
+de trabajo.  Si ha ejecutado \hgcmd{merge} para fusionar dos conjuntos
+de cambios, pero no ha consignado aún los resultados de la fusión,  su
+directorio de trabajo tiene dos padres (use \hgcmd{parents} para
+verlos).  Mientras que \hgcmd{status} imprime modificaciones relativas
+a \emph{ambos} padres después de una fusión que no se ha consignado,
+\hgcmd{diff} opera aún relativo solamente al primer padre.  Puede
+lograr que imprima las diferencias relativas al segundo padre
+especificando tal padre con la opción \hgopt{diff}{-r}.  No hay forma
+de hacer que imprima las diferencias relativas a los dos padres.
+
+\subsubsection{Generar diferencias seguras en binarios}
+
+Si usa la opción \hgopt{diff}{-a} para forzar que Mercurial imprima
+las diferencias de los ficheros que so o bien ``casi completamente
+texto'' o contienen muchos datos binarios, tales diferencias no pueden
+aplicarse subsecuentemente a la orden \hgcmd{import} de Mercurial o a
+la orden \command{patch} del sistema.
+
+Si desea generar una diferencia de un fichero binario que es seguro
+para usarlo como entrada a la orden \hgcmd{import}, use la opción
+\hgcmd{diff}{--git} cuando genere el parche.  La orden \command{patch}
+del sistema no puede tratar con parches binarios.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/collab.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1059 @@
+\chapter{Colaborar con otros}
+\label{cha:collab}
+
+Debido a su naturaleza descentralizada, Mercurial no impone política
+alguna de cómo deben trabajar los grupos de personas. Sin embargo, si
+usted es nuevo al control distribuido de versiones, es bueno tener
+herramientas y ejemplos a la mano al pensar en posibles modelos de
+flujo de trabajo.
+
+\section{La interfaz web de Mercurial}
+
+Mercurial tiene una poderosa interfaz web que provee bastantes
+capacidades útiles.
+
+Para uso interactivo, la interfaz le permite visualizar uno o varios
+repositorios. Puede ver el historial de un repositorio, examinar cada
+cambio (comentarios y diferencias), y ver los contenidos de cada
+directorio y fichero.
+
+Adicionalmente la interfaz provee notificaciones RSS de los cambios de los
+repositorios. Que le permite ``subscribirse''a un repositorio usando
+su herramienta de lectura de notificaciones favorita, y ser notificado
+automáticamente de la actividad en el repositorio tan pronto como
+sucede. Me gusta mucho más este modelo que el estar suscrito a una
+lista de correo a la cual se envían las notificaciones, dado que no
+requiere configuración adicional de parte de quien sea que está
+administrando el repositorio.
+
+La interfaz web también permite clonar repositorios a los usuarios
+remotos, jalar cambios, y (cuando el servidor está configurado para
+permitirlo) publicar cambios en el mismo.  El protocolo de entunelamiento
+de Mercurial comprime datos agresivamente, de forma que trabaja
+eficientemente incluso con conexiones de red con poco ancho de banda.
+
+La forma más sencilla de iniciarse con la interfaz web es usar su
+navegador para visitar un repositorio existente, como por ejemplo el
+repositorio principal de Mercurial \url{http://www.selenic.com/repo/hg?style=gitweb}.
+
+Si está interesado en proveer una interfaz web a sus propios
+repositorios, Mercurial provee dos formas de hacerlo.  La primera es
+usando la orden \hgcmd{serve}, que está enfocada a servir ``de forma
+liviana'' y por intervalos cortos.  Para más detalles de cómo usar
+esta orden vea la sección~\ref{sec:collab:serve} más adelante. Si
+tiene un repositorio que desea hacer permanente, Mercurial tiene
+soporte embebido del \command{ssh} para publicar cambios con seguridad
+al repositorio central, como se documenta en la
+sección~\ref{sec:collab:ssh}.  Es muy usual que se publique una copia
+de sólo lectura en el repositorio que está corriendo sobre HTTP usando
+CGI, como en la sección~\ref{sec:collab:cgi}.  Publicar sobre HTTP
+satisface las necesidades de la gente que no tiene permisos de
+publicación y de aquellos que quieren usar navegadores web para
+visualizar el historial del repositorio.
+
+\subsection{Trabajo con muchas ramas}
+
+Los proyectos de cierta talla tienden naturalmente a progresar de
+forma simultánea en varios frentes. En el caso del software, es común
+que un proyecto tenga versiones periódicas oficiales. Una versión
+puede entrar a ``modo mantenimiento'' por un tiempo después de su
+primera publicación; las versiones de mantenimiento tienden a contener
+solamente arreglos de fallos, pero no nuevas características. En
+paralelo con las versiones de mantenimiento puede haber una o muchas
+versiones futuras pueden estar en desarrollo. La gente usa normalmente
+la palabra ``rama'' para referirse a una de las direcciones
+ligeramente distintas en las cuales procede el desarrollo.
+
+Mercurial está especialmente preparado para administrar un buen número
+de ramas simultáneas pero no idénticas. Cada ``dirección de
+desarrollo'' puede vivir en su propio repositorio central, y puede
+mezclar los cambios de una a otra de acuerdo con las necesidades. Dado
+que los repositorios son independientes, uno del otro, los cambios
+inestables de una rama de desarrollo nunca afectarán una rama estable
+a menos que alguien explícitamente mezcle los cambios.
+
+A continuación un ejemplo de cómo podría hacerse esto en la
+práctica. Digamos que tiene una ``rama principal'' en un servidor
+central.
+\interaction{branching.init}
+Alguien lo clona, hace cambios locales, los prueba, y los publica allí
+mismo.
+
+Una vez que la rama principal alcanza una estado de versión se puede
+usar la orden \hgcmd{tag} para dar un nombre permanente a la revisión.
+\interaction{branching.tag}
+Digamos que en la rama principal ocurre más desarrollo.
+\interaction{branching.main}
+Cuando se usa la etiqueta con que se identificó la versión, la gente
+puede clonar el repositorio en cualquier momento en el futuro
+empleando \hgcmd{update} para obtener una copia del directorio de
+trabajo exacta como cuando se creó la etiqueta de la revisión que se
+consignó.
+\interaction{branching.update}
+
+Adicionalmente, justo después de que la rama principal se etiquete,
+alguien puede clonarla en el servidor a una nueva rama ``estable'',
+también en el servidor.
+\interaction{branching.clone}
+
+Alguien que requiera hacer un cambio en la rama estable puede clonar
+\emph{ese} repositorio, hacer sus cambios, consignar y publicarlos
+posteriormente al inicial.
+\interaction{branching.stable}
+Puesto que los repositorios de Mercurial son independientes, y que
+Mercurial no mueve los cambios de un lado a otro automáticamente, las
+ramas estable y principal están \emph{aisladas} la una de la otra.
+Los cambios que haga en la rama principal no ``se filtran'' a la rama
+estable o vice versa.
+
+Es usual que los arreglos de fallos de la rama estable deban hacerse
+aparecer en la rama principal también.  En lugar de reescribir el
+arreglo del fallo en la rama principal, puede jalar y mezclar los
+cambios de la rama estable a la principal, Mercurial traerá tales
+arreglos por usted.
+\interaction{branching.merge}
+La rama principal contendrá aún los cambios que no están en la
+estable y contendrá además todos los arreglos de fallos de la rama
+estable.  La rama estable permanece incólume a tales cambios.
+
+\subsection{Ramas de Características}
+
+En proyectos grandes, una forma efectiva de administrar los cambios es
+dividir el equipo en grupos más pequeños. Cada grupo tiene una rama
+compartida, clonada de una rama ``principal'' que conforma el proyecto
+completo.   Aquellos que trabajan en ramas individuales típicamente
+están aislados de los desarrollos de otras ramas.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{feature-branches}
+  \caption{Ramas de Características}
+  \label{fig:collab:feature-branches}
+\end{figure}
+
+Cuando una rama particular alcanza un estado deseado, alguien del
+equipo de características jala y fusiona de la rama principal hacia
+la rama de características y publica posteriormente a la rama principal.
+
+\subsection{El tren de publicación}
+
+Algunos proyectos se organizan al estilo``tren'': Una versión se
+planifica para ser liberada cada cierto tiempo, y las características
+que estén listas cuando ha llegado el momento ``tren'', se incorporan.
+
+Este modelo tiene cierta similitud a las ramas de características. La
+diferencia es que cuando una característica pierde el tren, alguien en
+el equipo de características jala y fusiona los cambios que se fueron
+en la versión liberada hacia la rama de característica, y el trabajo
+continúa sobre lo fusionado para que la característica logre estar en
+la próxima versión.
+
+\subsection{El modelo del kernel linux}
+
+El desarrollo del Kernel Linux tiene una estructura jerárquica
+bastante horizontal, rodeada de una nube de caos aparente. Dado que la
+mayoría de desarrolladores usan \command{git}, una herramienta distribuida
+de control de versiones con capacidades similares a Mercurial, resulta
+de utilidad describir la forma en que el trabajo fluye en tal
+ambiente; si le gustan las ideas, la aproximación se traduce bien
+entre Git y Mercurial.
+
+En el centro de la comunidad está Linus Torvalds, el creador de Linux.
+Él publica un único repositorio que es considerado el árbol
+``oficial'' actual por la comunidad completa de
+desarrolladores. Cualquiera puede clonar el árbol de Linus, pero él es
+muy selectivo acerca de los árboles de los cuales jala.
+
+Linus tiene varios ``lugartenientes confiables''.  Como regla, él jala
+todos los cambios que ellos publican, en la mayoría de los casos sin
+siquiera revisarlos.  Algunos de sus lugartenientes generalmente
+aceptan ser los ``mantenedores'', responsables de subsistemas
+específicos dentro del kernel.  Si un hacker cualquiera desea hacer un
+cambio a un subsistema y busca que termine en el árbol de Linus, debe
+encontrar quién es el mantenedor del subsistema y solicitarle que
+tenga en cuenta su cambio.  Si el mantenedor revisa los cambios y está
+de acuerdo en tomarlos, estos pasarán al árbol de Linus de acuerdo a
+lo expuesto.
+
+Cada lugarteniente tiene su forma particular de revisar, aceptar y
+publicar los cambios; y para decidir cuando hacerlos presentes a
+Linus.  Adicionalmente existen varias ramas conocidas que mucha gente
+usa para propósitos distintos. Por ejemplo, pocas personas mantienen
+repositorios ``estables'' de versiones anteriores del kernel, a los
+cuales aplican arreglos de fallos críticos necesarios. Algunos
+mantenedores publican varios árboles: uno para cambios
+experimentales; uno para cambios que van a ofrecer al mantenedor
+principal; y así sucesivamente. Otros publican un solo árbol.
+
+Este modelo tiene dos características notables. La primera es que son
+de ``jalar exclusivamente''.  Usted debe solicitar, convencer o
+incluso rogar a otro desarrollador para que tome sus cambios, porque
+casi no hay árboles en los cuales más de una persona pueda publicar, y
+no hay forma de publicar cambios en un árbol que otra persona controla.
+
+El segundo está basado en reputación y meritocracia.  Si usted es un
+desconocido, Linus probablemente ignorará sus cambios, sin siquiera
+responderle.  Pero un mantenedor de un subsistema probablemente los
+revisara, y los acogerá en caso de que aprueben su criterio de
+aplicabilidad.  A medida que usted ofrezca ``mejores'' cambios a un
+mantenedor, habrá más posibilidad de que se confíe en su juicio y se
+acepten los cambios.   Si usted es reconocido y mantiene una rama
+durante bastante tiempo para algo que Linus no ha aceptado, personas
+con intereses similares pueden jalar sus cambios regularmente para
+estar al día con su trabajo.
+
+La reputación y meritocracia no necesariamente es transversal entre
+``personas'' de diferentes subsistemas.  Si usted es respetado pero es
+un hacker en almacenamiento y trata de arreglar un fallo de redes,
+tal cambio puede recibir un nivel de escrutinio de un mantenedor de
+redes comparable con el que se le haría a un completo extraño.
+
+Personas que vienen de proyectos con un ordenamiento distinto, sienten
+que el proceso comparativamente caótico del Kernel Linux es
+completamente lunático.  Es objeto de los caprichos individuales; la
+gente desecha cambios cuando lo desean; y la fase de desarrollo es
+alucinante. A pesar de eso Linux es una pieza de software exitosa y
+bien reconocida.
+
+\subsection{Solamente jalar frente a colaboración pública}
+
+Una fuente perpetua de discusiones en la comunidad de código abierto
+yace en el modelo de desarrollo en el cual la gente solamente jala
+cambios de otros ``es mejor que'' uno  en el cual muchas personas
+pueden publicar cambios a un repositorio compartido.
+
+Típicamente los partidarios del modelo de publicar usan las herramientas
+que se apegan a este modelo.  Si usted usa una herramienta
+centralizada de control de versiones como Subversion, no hay forma de
+elegir qué modelo va a usar: La herramienta le ofrece publicación
+compartida, y si desea hacer cualquier otra cosa, va a tener que
+aplicar una aproximación artificial (tal como aplicar parches a mano).
+
+Una buena herramienta distribuida de control de versiones, tal como
+Mercurial soportará los dos modelos.   Usted y sus colaboradores
+pueden estructurar cómo trabajarán juntos basados en sus propias
+necesidades y preferencias,  sin depender de las peripecias que la
+herramienta les obligue a hacer.
+
+\subsection{Cuando la colaboración encuentra la administración ramificada}
+
+Una vez que usted y su equipo configurar algunos repositorios
+compartidos y comienzan a propagar cambios entre sus repositorios
+locales y compartidos, comenzará a encarar un reto relacionado, pero
+un poco distinto:  Administrar las direcciones en las cuales su equipo
+puede moverse.   A pesar de que está íntimamente ligado acerca de cómo
+interactúa su equipo, es lo suficientemente denso para ameritar un
+tratamiento en el capítulo~\ref{chap:branch}.
+
+\section{Aspectos técnicos de la colaboración}
+
+Lo que resta del capítulo lo dedicamos a las cuestiones de servir
+datos a sus colaboradores.
+
+\section{Compartir informalmente con \hgcmd{serve}}
+\label{sec:collab:serve}
+
+La orden \hgcmd{serve} de Mercurial satisface de forma espectacular
+las necesidades de un grupo pequeño, acoplado y de corto
+tiempo.  Se constituye en una demostración de cómo se siente usar los
+comandos usando la red.
+
+Ejecute \hgcmd{serve} dentro de un repositorio, y en pocos segundos
+iniciará un servidor HTTP especializado; aceptará conexiones desde
+cualquier cliente y servirá datos de este repositorio mientrs lo
+mantenga funcionando. Todo el que sepa el URL del servidor que ha
+iniciado, y que puede comunicarse con su computador por la red, puede
+usar un navegador web o Mercurial para leer datos del repositorio. Un
+URL para una instancia de \hgcmd{serve} ejecutándose en un portátil
+debería lucir algo \Verb|http://my-laptop.local:8000/|.
+
+La orden \hgcmd{serve} \emph{no} es un servidor web de propósito
+general. Solamente puede hacer dos cosas:
+\begin{itemize}
+\item Permitir que se pueda visualizar el historial del repositorio que
+  está sirviendo desde navegadores web.
+\item Hablar el protocolo de conexión de Mercurial para que puedan hacer
+  \hgcmd{clone} o \hgcmd{pull} (jalar) cambios de tal repositorio.
+\end{itemize}
+En particular, \hgcmd{serve} no permitirá que los usuarios remotos
+puedan \emph{modificar} su repositorio.  Es de tipo solo lectura.
+
+Si está comenzando con Mercurial, no hay nada que le impida usar
+\hgcmd{serve} para servir un repositorio en su propio computador, y
+usar posteriormente órdenes como \hgcmd{clone}, \hgcmd{incoming}, para
+comunicarse con el servidor como si el repositorio estuviera alojado
+remotamente. Lo que además puede ayudarle a adecuarse rápidamente para
+usar comandos en repositorios alojados en la red.
+
+\subsection{Cuestiones adicionales para tener en cuenta}
+
+Dado que permite lectura sin autenticación a todos sus clientes,
+debería usar \hgcmd{serve} exclusivamente en ambientes en los cuáles
+no tenga problema en que otros vean, o en los cuales tenga control
+completo acerca de quien puede acceder a su red y jalar cambios de su
+repositorio.
+
+La orden \hgcmd{serve} no tiene conocimiento acerca de programas
+cortafuegos que puedan estar instalados en su sistema o en su red. No
+puede detectar o controlar sus cortafuegos.  Si otras personas no
+pueden acceder a su instancia \hgcmd{serve}, lo siguiente que debería hacer
+(\emph{después} de asegurarse que tienen el URL correcto) es verificar
+su configuración de cortafuegos.
+
+De forma predeterminada, \hgcmd{serve} escucha conexiones entrantes en
+el puerto~8000.  Si otro proceso está escuchando en tal puerto, usted
+podrá especificar un puerto distinto para escuchar con la opción
+\hgopt{serve}{-p}.
+
+Normalmente, cuando se inicia \hgcmd{serve}, no imprime nada, lo cual
+puede ser desconcertante.  Si desea confirmar que en efecto está
+ejecutándose correctamente, y darse cuenta qué URL debería enviar a
+sus colaboradores, inícielo con la opción \hggopt{-v}.
+
+\section{Uso del protocolo Secure Shell (ssh)}
+\label{sec:collab:ssh}
+
+Usted puede publicar y jalar cambios en la red de forma segura usando
+el protocolo Secure Shell (\texttt{ssh}).  Para usarlo satisfactoriamente,
+tendrá que hacer algo de configuración a nivel de cliente o el
+servidor.
+
+Si no está familiarizado con ssh, es un protocolo de red que le permite
+comunicarse con seguridad con otro computador.  Para usarlo con
+Mercurial, estará estableciendo una o más cuentas de usuario en un
+servidor de forma tal que los usuarios remotos puedan entrar y
+ejecutar órdenes.
+
+(Si ssh le \emph{es} familiar, encontrará probablemente elemental una
+porción del material a continuación.)
+
+\subsection{Cómo leer y escribir URLs de ssh}
+
+Los URLs de ssh tienden a lucir de la siguiente forma:
+\begin{codesample2}
+  ssh://bos@hg.serpentine.com:22/hg/hgbook
+\end{codesample2}
+\begin{enumerate}
+\item La parte ``\texttt{ssh://}'' indica a Mercurial que use el
+  protocolo ssh.
+\item El componente ``\texttt{bos@}'' indica el nombre del usuario que
+  está entrando al servidor.  Puede omitirlo si el usuario remoto
+  coincide con el usuario local.
+\item ``\texttt{hg.serpentine.com}'' es el nombre del servidor al cual
+  se desea entrar.
+\item El ``:22'' identifica el número del puerto en el servidor al cual
+  se conectará.  El predeterminado es el~22, así que solamente
+  necesitará especificar esa porción si \emph{no} está usando el
+  puerto~22.
+\item La última porción del URL es la ruta local al repositorio en el
+  servidor.
+\end{enumerate}
+
+El componente de la ruta del URL para ssh es una fuente de confusión,
+puesto que no hay una forma estándar para que las herramientas puedan
+interpretarlo.  Algunos programas se comportan de manera distinta a
+otros cuando manipulan estas rutas.  No es la situación ideal, pero
+es muy poco probable que vaya a cambiar.  Por favor lea los párrafos
+siguientes cuidadosamente.
+
+Mercurial trata la ruta al repositorio en el servidor como relativo al
+directorio personal del usuario remoto.  Por ejemplo, si el usuario
+\texttt{foo} en el servidor tiene el directorio casa
+\dirname{/home/foo},
+entonces un URL ssh que contenga en su ruta a \dirname{bar}
+\emph{realmente} se refiere al directorio \dirname{/home/foo/bar}.
+
+Si desea especificar una ruta relativa a otro directorio de usuario,
+puede usar una ruta que comience con un caracter tildado, seguido del
+nombre del usuario (llamémosle \texttt{otrousuario}, así
+\begin{codesample2}
+  ssh://server/~otrousuario/hg/repo
+\end{codesample2}
+
+Y si realmente desea especifica una ruta \emph{absoluta} en el
+servidor, comience con el componente de la ruta con dos barras como
+en el siguiente ejemplo:
+\begin{codesample2}
+  ssh://server//absolute/path
+\end{codesample2}
+
+\subsection{Encontrar un cliente ssh para su sistema}
+
+Casi todos los sistemas tipo Unix vienen con OpenSSH preinstalado.  Si
+usted está usando un sistema de estos, ejecute \Verb|which ssh| para
+identificar dónde está instalada la orden \command{ssh} (usualmente
+estará en \dirname{/usr/bin}).  Si por casualidad no está presente,
+vea la documentación de sus sistema para lograr instalarlo.
+
+En Windows, tendrá que escoger primero un cliente adecuado para
+descargarlo.  Hay dos alternativas:
+\begin{itemize}
+\item El excelente paquete PuTTY~\cite{web:putty} de Simon Tatham, que
+  ofrece un suite completo de órdenes de cliente ssh.
+\item Si tiene alta tolerancia al dolor, puede usar el porte de Cygwin
+  para OpenSSH.
+\end{itemize}
+En cualquier caso, tendrá que editar su fichero \hgini\ para indicarle
+a Mercurial dónde encontrar la orden real del cliente.  Por ejemplo, si
+está usando PuTTY, tendrá que usar la orden \command{plink} como un
+cliente de línea de órdenes.
+\begin{codesample2}
+  [ui]
+  ssh = C:/ruta/a/plink.exe -ssh -i "C:/ruta/a/mi/llave/privada"
+\end{codesample2}
+
+\begin{note}
+  La ruta a \command{plink} no debería contener espacios o caracteres
+  en blanco, o Mercurial no podrá encontrarlo correctamente (por lo
+  tanto, probablemente no sería buena idea colocarlo en 
+  \dirname{C:\\Program Files}
+\end{note}
+
+\subsection{Generar un par de llaves}
+
+Para evitar la necesidad de teclear una clave de forma repetitiva cada
+vez que necesita usar el cliente, recomiendo generar un par de llaves.
+En un sistema tipo Unix, la orden \command{ssh-keygen} también se
+comportará bien. En Windows, si está usando PuTTY, la orden
+\command{puttygen} es la que necesitará.
+
+Cuando genera un par de llaves, se aconseja \emph{comedidamente} 
+protegerlas con una frase de clave.  (La única oportunidad en la cual
+usted querría identificarse una única vez, es cuando está usando
+el protocolo ssh para tareas automatizadas en una red segura.)
+
+No basta con generar un par de llaves.  Se requiere adicionar una llave
+pública al conjunto de llaves autorizadas para todos los usuarios
+remotos que se vayan a autenticar.  Para aquellos servidores que usen
+OpenSSH (la gran mayoría), significará añadir la llave pública a la
+lista en el fichero llamado \sfilename{authorized\_keys} en su
+directorio \sdirname{.ssh}.
+
+En sistemas tipo Unix, su llave pública tendrá la extensión
+\filename{.pub}.  Si usa \command{puttygen} en Windows, puede
+guardar la llave pública en un fichero de su elección, o pegarla desde
+la ventana en la cual se despliega directamente en el fichero
+\sfilename{authorized\_keys}.
+
+\subsection{Uso de un agente de autenticación}
+
+Un agente de autenticación es un demonio que almacena frases clave en
+memoria (olvidará las frases clave si sale y vuelve a entrar).  Un cliente
+ssh notará si está corriendo, y solicitará una frase clave.  Si no hay
+un agente de autenticación corriendo, o el agente no almacena la frase
+clave necesaria, tendrá que teclear su frase clave cada vez que 
+Mercurial intente comunicarse con un servidor para usted (p.e.~cada vez
+que jale o publique cambios).
+
+El problema de almacenar frases claves en un agente es que es posible
+para un atacante bien preparado recuperar el texto plano de su frase
+clave, en algunos casos incluso si su sistema sea muy alternante.
+Es su decisión si es un riesgo aceptable.  Lo que si es seguro es que
+evita reteclear.
+
+En sistemas tipo Unix, el agente se llama \command{ssh-agent}, y
+usualmente se ejecuta automáticamente cuando usted entra.  Tendrá que
+usar la orden \command{ssh-add} para añadir frases claves al agente.  En
+Windows, si está usando PuTTY, la orden \command{pageant} actúa como
+el agente.  Añade un icono a su barra del sistema que le permitirá
+almacenar frases clave.
+
+\subsection{Configurar el lado del servidor apropiadamente}
+
+Dado que puede ser dispendioso configurar ssh si usted es nuevo, hay 
+una variedad de cosas que podrían ir mal.  Añada piense primero en
+Mercurial y hay mucho más en qué pensar.  La mayor parte de estos
+problemas potenciales ocurren en el lado del servidor, no en el cliente.
+Las buenas noticias es que una vez tiene una configuración funcional,
+usualmente continuará trabajando indefinidamente.
+
+Antes de intentar que Mercurial hable con un servidor ssh, es mejor
+asegurarse que puede usar la orden normal \command{ssh} o \command{putty}
+para comunicarse con el servidor primero.  Si tiene problemas usando
+estas órdenes directamente, de seguro Mercurial no funcionará.  Pero aún,
+esconderá el problema subyacente.  Cuando desee revisar un problema
+relacionado con ssh y Mercurial, debería asegurarse primero que las
+órdenes de ssh en el lado del cliente funcionan primero, \emph{antes}
+de preocuparse por si existe un problema con Mercurial.
+
+Lo primero para asegurar en el lado del servidor es que puede entrar
+desde otra máquina.  Si no puede entrar con \command{ssh} o 
+\command{putty}, el mensaje de error que obtenga le puede dar pistas
+de qué ha ido mal.  Los problemas más comunes son los siguientes:
+\begin{itemize}
+\item Si obtiene un error de ``conexión rehusada'', es posible que no 
+  haya un demonio SSH corriendo en el servidor o que no pueda accederse
+  a él por configuraciones de cortafuegos.
+\item Si obtiene un error de ``no hay ruta hasta el servidor'', puede
+  tener la dirección del servidor incorrecta o un cortafuegos con
+  bloqueo agresivo que no permitirá su existencia.
+\item Si obtiene un mensaje de ``permiso denegado'', puede que haya
+  tecleado mal el usuario en el servidor, o que haya tecleado
+  incorrectamente la frase clave o la clave del usuario remoto.
+\end{itemize}
+En resumen, si tiene problemas al comunicarse con el demonio ssh del
+servidor, primero asegúrese de que está corriendo.  En muchos sistemas
+estará instalado, pero deshabilitado de forma predeterminada.  Una vez
+que haya hecho este paso tendrá que revisar si el cortafuegos del
+servidor está configurado para recibir conexiones entrantes en el
+puerto en el cual el demonio de ssh está escuchando (usualmente el~22).
+No trate de buscar otras posibilidades exóticas o configuraciones
+erradas hasta que haya revisado primero estas dos.
+
+Si está usando un agente de autenticación en el lado del cliente para
+almacenar las frase claves de sus contraseñas, debería poder entrar al
+servidor sin necesidad de que se le solicite frases claves o
+contraseñas.  Si se le pregunta alguna, a continuación algunas
+posibilidades:
+\begin{itemize}
+\item Puede haber olvidado usar \command{ssh-add} o
+  \command{pageant} para guardar la frase clave.
+\item Puede haber almacenado una frase clave errónea para la llave.
+\end{itemize}
+Si se le solicita la clave del usuario remoto, hay otras posibilidades
+que deben revisarse:
+\begin{itemize}
+\item O bien el directorio del usuario o su directorio \sdirname{.ssh}
+  tiene permisos excesivamente abiertos.  Como resultado el daemonio
+  ssh no creerá o leerá su fichero \sfilename{authorized\_keys}.  
+  Por ejemplo, un directorio casa o \sdirname{.ssh} causará aveces
+  este síntoma.
+\item El fichero de usuario \sfilename{authorized\_keys} puede tener
+  un problema.  Si alguien distinto al usuario es dueño o puede
+  escribir el fichero, el demonio ssh no confiará o lo leerá.
+\end{itemize}
+
+En un mundo ideal, debería poder ejecutar la siguiente orden
+exitosamente, y debería imprimir exactamente una línea de salida,
+la fecha y hora actual.
+\begin{codesample2}
+  ssh miservidor fecha
+\end{codesample2}
+
+Si en su servidor tiene guión que se ejecuta a la entrada e imprime
+letreros o cualquier otra cosa, incluso cuando se ejecutan órdenes no
+interactivas como esta, debería arreglarlo antes de continuar, de
+forma que solamente imprima algo si se ejecuta interactivamente.  De
+otra forma estos letreros al menos llenarán la salida de Mercurial. 
+Incluso podrían causar problemas potenciales cuando se ejecuten
+órdenes de forma remota.  Mercurial intenta detectar e ignorar los
+letreros en sesiones no interactivas de \command{ssh}, pero no es
+a prueba de tontos.  (Si edita sus guiones de entrada en el servidor,
+la forma usual de ver si un guión de línea de comandos se ejecuta en un intérprete
+interactivo, es verificar el código de retorno de la orden
+\Verb|tty -s|.)
+
+Cuando verifique que el venerado ssh funciona en su servidor, el
+paso siguiente es asegurar que Mercurial corre en el servidor.  La
+orden siguiente debería ejecutarse satisfactoriamente:
+\begin{codesample2}
+  ssh miservidor hg version
+\end{codesample2}
+Si ve un mensaje de error en lugar de la salida usual de 
+\hgcmd{version}, será porque no ha instalado Mercurial en
+\dirname{/usr/bin}.  No se preocupe si este es el caso; no necesita
+hacerlo.  Pero debería revisar los posibles problemas presentados a
+continuación:
+\begin{itemize}
+\item Está instalado Mercurial en el servidor?  Se que suena trivial
+  pero es mejor revisar!
+\item Tal vez la ruta de búsqueda de la interfaz de órdenes
+  (normalmente vía la variable de ambiente \envar{PATH}) simplemente
+  está mal configurada.
+\item Puede ser que su variable de ambiente \envar{PATH} soalamente
+  apunte al lugar en el cual está el ejecutable \command{hg} si la
+  sesión de entrada es interactiva.  Puede suceder si establece la
+  ruta en el guión de línea de comandos de entrada incorrecto.  Consulte la
+  documentación de su línea de órdenes.
+\item La variable de ambiente \envar{PYTHONPATH} puede requerir la
+  ruta a los módulos de Mercurial en Python.  Puede que ni siquiera
+  está establecida; podría estar incorrecta; o puede ser que se
+  establezca únicamente cuando hay entradas interactivas.
+\end{itemize}
+
+Si puede ejecutar \hgcmd{version} sobre una conexión ssh,
+felicitaciones!  Ha logrado la interacción entre el cliente y el 
+servidor.  Ahora debería poder acceder a los repositorios de
+Mercurial que tiene el usuario en el servidor.  Si tiene problemas
+con Mercurial y ssh en este punto, intente usar la opción
+\hggopt{--debug} para tener información más clara de lo que está
+sucediendo.
+
+\subsection{Compresión con ssh}
+
+Mercurial no comprime datos cuando usa el protocolo ssh, dado que
+el protocolo puede comprimir datos transparentemente.  Pero el
+comportamiento predeterminado del cliente ssh es \emph{no}
+solicitar compresión.
+
+Sobre cualquier red distinta a una LAN rápida (incluso con una red
+inalámbrica), hacer uso de compresión puede mejorar el rendimiento
+de las operaciones de Mercurial que involucren la red.  Por ejemplo,
+sobre WAN, alguien ha medido la compresión reduciendo la cantidad
+de tiempo requerido para clonar un repositorio particularmente
+grande de~51 minutos a~17 minutos.
+
+Tanto \command{ssh} como \command{plink} aceptan la opción
+\cmdopt{ssh}{-C} que activa la compresión.  Puede editar fácilmente
+su \hgrc\ para habilitar la compresión para todos los usos de
+Mercurial sobre el protocolo ssh.
+\begin{codesample2}
+  [ui]
+  ssh = ssh -C
+\end{codesample2}
+
+Si usa \command{ssh}, puede reconfigurarlo para que siempre use
+compresión cuando se comunique con su servidor.  Para hacerlo,
+edite su fichero \sfilename{.ssh/config} (que puede no existir
+aún), de la siguiente forma:
+\begin{codesample2}
+  Host hg
+    Compression yes
+    HostName hg.ejemplo.com
+\end{codesample2}
+Que define un alias, \texttt{hg}.  Cuando lo usa con la orden
+\command{ssh} o con una URL de Mercurial con protocolo\texttt{ssh},
+logrará que \command{ssh} se conecte a \texttt{hg.ejemplo.com}
+con compresión.  Que le dará un nombre más corto para teclear y
+compresión, los cuales por derecho propio son buenos.
+
+\section{Uso de CGI a través de HTTP}
+\label{sec:collab:cgi}
+
+Dependiendo de qué tan ambicioso sea, configurar la interfaz CGI
+de Mercurial puede tomar desde unos minutos hasta varias horas.
+
+Comenzaremos con el ejemplo más sencillo, y nos dirigiremos hacia
+configuraciones más complejas.  Incluso para el caso más básico
+necesitará leer y modificar su configuración del servidor web.
+
+\begin{note}
+  Configurar un servidor web es una actividad compleja, engorrosa y
+  altamente dependiente del sistema.  De ninguna manera podremos
+  cubrir todos los casos posibles con los cuales pueda encontrarse.
+  Use su discreción y juicio respecto a las secciones siguientes.
+  Esté preparado para cometer muchas equivocaciones, y emplear
+  bastante tiempo leyendo sus bitácoras de error del servidor.
+\end{note}
+
+\subsection{Lista de chequeo de la configuración del servidor web}
+
+Antes de continuar, tómese un tiempo para revisar ciertos aspectos de
+la configuración de su sistema:
+
+\begin{enumerate}
+\item ¿Tiene un servidor web?  Mac OS X viene con Apache, pero otros
+  sistemas pueden no tener un servidor web instalado.
+\item Si tiene un servidor web instalado, ¿Está ejecutándose?  En la
+  mayoría de sistemas, aunque esté presente, puede no estar habilitado
+  de forma predeterminada.
+\item ¿u servidor está configurado para permitir ejecutar programas
+  CGI en el directorio donde planea hacerlo?  Casi todos los
+  servidores de forma predeterminada explícitamente inhiben la
+  habilidad de ejecutar programas CGI.
+\end{enumerate}
+
+Si no tiene un servidor web instalado, y no tiene cierta experiencia
+configurando  Apache, debería considerar usar el servidor web
+\texttt{lighttpd} en lugar de Apache.  Apache tiene una reputación
+bien ganada por su configuración barroca y confusa.
+A pesar de que \texttt{lighttpd} tiene menos características que
+Apache en ciertas áreas, las mismas no son relevantes para servir
+repositorios de Mercurial.  Definitivamente es mucho más sencillo
+comenzar con \texttt{lighttpd} que con Apache.
+
+\subsection{Configuración básica de CGI}
+
+En sistemas tipo Unix es común que los usuarios tengan un subdirectorio
+con un nombre como \dirname{public\_html} en su directorio personal,
+desde el cual pueden servir páginas web.  Un fichero llamado \filename{foo}
+en este directorio será visible en una URL de la forma
+\texttt{http://www.example.com/\~username/foo}.
+
+Para comenzar, encuentre el guión \sfilename{hgweb.cgi} que debería
+estar presente en su instalación de Mercurial.  Si no puede
+encontrarlo rápidamente una copia local en su sistema, puede
+descargarlo del repositorio principal de Mercurial en
+\url{http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi}.
+
+Tendrá que copiar este guión en su directorio \dirname{public\_html},
+y asegurarse que sea ejecutable.
+\begin{codesample2}
+  cp .../hgweb.cgi ~/public_html
+  chmod 755 ~/public_html/hgweb.cgi
+\end{codesample2}
+El argumento \texttt{755} de la orden \command{chmod} es un poco más
+general que hacerlo ejecutable: Asegura que el guión sea ejecutable
+por cualquiera, y que el ``grupo'' y los ``otros'' \emph{no}  tengan
+permiso de escritura.  Si dejara los permisos de escritura abiertos,
+, el subsistema \texttt{suexec} de  Apache probablemente se negaría
+a ejecutar el guión.  De hecho, \texttt{suexec} también insiste en que
+el \emph{directorio} en el cual reside el guión no tenga permiso de
+escritura para otros.
+\begin{codesample2}
+  chmod 755 ~/public_html
+\end{codesample2}
+
+\subsubsection{¿Qué \emph{podría} resultar mal?}
+\label{sec:collab:wtf}
+
+Cuando haya ubicado el CGI en el sitio correspondiente con un navegador
+intente visitar el URL \url{http://myhostname/~myuser/hgweb.cgi},
+\emph{sin} dejarse abatir por un error.  Hay una alta probabilidad de
+que esta primera visita al URL sea fallida, y hay muchas razones posibles
+para este comportamiento.  De hecho, podría toparse con cada uno de los
+errores que describimos a continuación, así que no deje de leerlos
+cuidadosamente.   A continuación presento los problemas que yo tuve en
+un sistema con Fedora~7, con una instalación nueva de Apache, y una
+cuenta de usuario que creé específicamente para desarrollar este
+ejercicio.
+
+Su servidor web puede tener directorios por usuario deshabilitados. Si
+usa Apache, busque el fichero de configuración que contenga la
+directiva \texttt{UserDir}.  Si no está presente en sitio alguno, los
+directorios por usuario están deshabilitados.  Si la hay, pero su
+valor es \texttt{disabled}, los directorios por usuario estarán
+deshabilitados. La directiva \texttt{UserDir} en caso contrario tendrá
+el nombre del subdirectorio bajo el cual Apache mirará en el
+directorio de cada usuario, por ejemplo \dirname{public\_html}.
+
+Los permisos de sus ficheros pueden ser demasiado restrictivos.  El
+servidor web debe poder recorrer su directorio personal y los
+directorios que estén bajo \dirname{public\_html}, además de tener
+permiso para leer aquellos que estén adentro.  A continuación una
+receta rápida para hacer que sus permisos estén acordes con las
+necesidades básicas.
+\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}
+
+Otra posibilidad con los permisos es que obtenga una ventana
+completamente en blanco cuando trata de cargar el guión. En cuyo
+caso, es posible que los permisos que tiene son \emph{demasiado
+ permisivos}.  El subsistema \texttt{suexec} de Apache no ejecutará un
+guión que tenga permisos de escritura para el grupo o el planeta, por
+ejemplo.
+
+Su servidor web puede estar configurado para evitar la ejecución de
+programas CGI en los directorios de usuario.  A continuación presento
+una configuración predeterminada por usuario en mi sistema Fedora.
+
+\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}
+Si encuentra un grupo de instrucciones de \texttt{Directory} similares
+en su configuración de Apache,  la directiva a revisar es \texttt{Options}.
+Adicione \texttt{ExecCGI} al final de esta lista en caso de que haga
+falta y reinicie su servidor web.
+
+Si resulta que Apache le muestra el texto del guión CGI en lugar de
+ejecutarlo, necesitará o bien descomentar (si se encuentra presente) o
+adicionar una directiva como la siguiente:
+\begin{codesample2}
+  AddHandler cgi-script .cgi
+\end{codesample2}
+
+Otra posibilidad es que observe una traza de Python en colores
+informando que no puede importar un módulo relacionado con
+\texttt{mercurial}.  Esto es un gran progreso!  El servidor es capaz
+de ejecutar su guión CGI.  Este error solamente ocurrirá si está
+ejecutando una instalación privada de Mercurial en lugar de una
+instalación para todo el sistema.  Recuerde que el servidor que
+ejecuta el programa CGI no cuenta con variables de ambiente de las
+cuales usted si dispone en una sesión interactiva.  Si este error le
+ocurre, edite su copia de \sfilename{hgweb.cgi} y siga las indicaciones
+dentro del mismo para establecer de forma adecuada su variable de
+ambiente \envar{PYTHONPATH}.
+
+Finalmente, si encuentra \emph{otra} traza a todo color de Python al visitar
+el URL: Esta seguramente se referirá a que no puede encontrar
+\dirname{/path/to/repository}.  Edite su script \sfilename{hgweb.cgi}
+y reemplace la cadena \dirname{/path/to/repository} con la ruta
+completa al repositorio que desea servir.
+
+En este punto, cuando trate de recargar la página, deberá visualizar
+una linda vista HTML del historial de su repositorio. Uff!
+
+\subsubsection{Configuración de lighttpd}
+
+En mi intención de ser exhaustivo, intenté configurar
+\texttt{lighttpd}, un servidor web con creciente aceptación, para
+servir los repositorios de la misma forma como lo describí
+anteriormente con Apache. Después de superar los problemas que mostré
+con Apache, muchos de los cuáles no son específicos del servidor.  Por
+lo tanto estaba seguro de que mis permisos para directorios y ficheros
+eran correctos y que mi guión \sfilename{hgweb.cgi} también lo era.
+
+Dado que ya Apache estaba en ejecución correctamente, lograr que
+\texttt{lighttpd} sirviera mi repositorio fue rápido (en otras
+palabras, si está tratando de usar \texttt{lighttpd}, debe leer la
+sección de Apache).  Primero tuve que editar la sección
+\texttt{mod\_access} para habilitar \texttt{mod\_cgi} y
+\texttt{mod\_userdir}, los cuales estaban inhabilitados en mi
+instalación predeterminada.  Añadí posteriormente unas líneas al final
+del fichero de configuración, para hacer lo propio con los módulos.
+\begin{codesample2}
+  userdir.path = "public_html"
+  cgi.assign = ( ".cgi" => "" )
+\end{codesample2}
+Hecho esto, \texttt{lighttpd} funcionó inmediatamente para
+mí. Configuré \texttt{lighttpd} antes que Apache, tuve casi los mismos
+reparos a nivel de configuración del sistema que con Apache.  De todas
+maneras, considero que \texttt{lighttpd} es bastante más sencillo de
+configurar que Apache, a pesar de haber usado Apache por lo menos por
+una década, y esta fue mi primera experiencia con \texttt{lighttpd}.
+
+\subsection{Compartir varios repositorios con un guión CGI}
+
+El guión \sfilename{hgweb.cgi} permite publicar únicamente un
+repositorio, una restricción frustrante.  Si desea publicar más de uno
+sin complicarse con varias copias del mismo guión, cada una con un
+nombre distinto, resulta mucho mejor usar el guión
+\sfilename{hgwebdir.cgi}.
+
+El procedimiento para configurar \sfilename{hgwebdir.cgi} tiene una
+porción adicional frente al trabajo requerido con
+\sfilename{hgweb.cgi}.  Primero se debe obtener una copia del
+guión. Si no tiene una a mano, puede descargar una copia del ftp
+principal del repositorio de Mercurial en
+\url{http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi}.
+
+Necesitará una copia del guión en su directorio \dirname{public\_html},
+y asegurarse de que sea ejecutable.
+\begin{codesample2}
+  cp .../hgwebdir.cgi ~/public_html
+  chmod 755 ~/public_html ~/public_html/hgwebdir.cgi
+\end{codesample2}
+Con la configuración básica, intente visitar en su navegador
+\url{http://myhostname/~myuser/hgwebdir.cgi}.  Debería mostrar una
+lista vacía de repositorios.  Si obtiene una ventana en blanco o un
+mensaje de error, verifique la lista de problemas potenciales en la 
+sección~\ref{sec:collab:wtf}.
+
+El guión \sfilename{hgwebdir.cgi} se apoya en un fichero externo de
+configuración.  En principio, busca un fichero llamado
+\sfilename{hgweb.config} en el mismo directorio.  Tendrá que crear el
+fichero, y permitir lectura de todo el mundo.  El formato del fichero
+es similar a un fichero ``ini'' de Windows, que puede interpretar el módulo
+\texttt{ConfigParser}~\cite{web:configparser} de Python.
+
+La forma más sencilla de configurar \sfilename{hgwebdir.cgi} es con
+una sección llamada \texttt{collections}.  Esta publicará automáticamente
+\emph{todos} los repositorios en los directorios que usted
+especifique.  La sección debería lucir así:
+\begin{codesample2}
+  [collections]
+  /mi/ruta = /mi/ruta
+\end{codesample2}
+Mercurial lo interpreta buscando el nombre del directorio que esté a la
+\emph{derecha} del símbolo ``\texttt{=}''; encontrando repositorios en
+la jerarquía de directorios; y usando el texto a la \emph{izquierda}
+para eliminar el texto de los nombres que mostrará en la interfaz
+web.  El componente restante de la ruta después de esta eliminación
+usualmente se llama ``ruta virtual''.
+
+Dado el ejemplo de arriba, si tenemos un repositorio cuya ruta local es
+\dirname{/mi/ruta/este/repo}, el guión CGI eliminará la porción inicial
+\dirname{/mi/ruta} del nombre y publicará el repositorio con una ruta
+virtual \dirname{este/repo}.  Si el URL base de nuestro guión CGI es
+\url{http://myhostname/~myuser/hgwebdir.cgi}, el URL completo al
+repositorio será
+\url{http://myhostname/~myuser/hgwebdir.cgi/this/repo}.
+
+Si reemplazamos \dirname{/mi/ruta} en el lado izquierdo de este
+ejemplo con \dirname{/mi}, \sfilename{hgwebdir.cgi} eliminará solamente
+\dirname{/mi} del nombre del repositorio, y nos ofrecerá la ruta
+virtual \dirname{ruta/este/repo} en lugar de \dirname{este/repo}.
+
+El guión \sfilename{hgwebdir.cgi} buscará recursivamente en cada
+directorio listado en la sección \texttt{collections} de su fichero de
+configuración, pero \texttt{no} hará el recorrido recursivo dentro de
+los repositorios que encuentre.
+
+El mecanismo de \texttt{collections} permite publicar fácilmente
+repositorios de una forma ``hacer y olvidar''.  Solamente requiere
+configurar el guión CGI y el fichero de configuración una vez.
+Después de eso puede publicar y sacar de publicación un repositorio en
+cualquier momento incluyéndolo o excluyéndolo de la jerarquía de
+directorios en la cual le haya indicado a \sfilename{hgwebdir.cgi} que
+mirase.
+
+\subsubsection{Especificación explícita de los repositorios a publicar}
+
+Además del mecanismo \texttt{collections}, el guión
+\sfilename{hgwebdir.cgi} le permite publicar una lista específica de
+repositorios.  Para hacerlo, cree una sección \texttt{paths}, con los
+contenidos de la siguiente forma:
+\begin{codesample2}
+  [paths]
+  repo1 = /mi/ruta/a/un/repo
+  repo2 = /ruta/a/otro/repo
+\end{codesample2}
+En este caso, la ruta virtual (el componente que aparecerá en el URL)
+está en el lado derecho de cada definición, mientras que la ruta al
+repositorio está a la derecha.  Note que no tiene que haber relación
+alguna entre la ruta virtual que elija y el lugar del repositorio en
+su sistema de ficheros.
+
+Si lo desea, puede usar los dos mecanismos \texttt{collections} y
+\texttt{paths} simultáneamente en un sólo fichero de configuración.
+
+\begin{note}
+  Si varios repositorios tienen la misma ruta virtual,
+  \sfilename{hgwebdir.cgi} no reportará error.  Pero se comportará
+  impredeciblemente.
+\end{note}
+
+\subsection{Descarga de ficheros fuente}
+
+La interfaz web de Mercurial permite a los usuarios descargar
+un conjunto de cualquier revisión.  Este fichero contendrá una réplica
+del directorio de trabajo en la revisión en cuestión, pero no
+contendrá una copia de los datos del repositorio.
+
+De forma predeterminada esta característica no está habilitada.  Para
+lograrlo adicione un \rcitem{web}{allow\_archive} a la sección \rcsection{web}
+de su fichero \hgrc.
+
+\subsection{Opciones de configuración en Web}
+
+Las interfaces web de Mercurial (la orden \hgcmd{serve}, y los guiones
+\sfilename{hgweb.cgi} y \sfilename{hgwebdir.cgi}) tienen varias
+opciones de configuración para establecer. Todas ellas en la sección
+\rcsection{web}.
+\begin{itemize}
+\item[\rcitem{web}{allow\_archive}] Determina cuáles tipos de ficheros
+  de descarga soportará Mercurial.  Si habilita esta característica,
+  los usuarios de la interfaz web podrán descargar una copia de la
+  revisión del repositorio que estén viendo. Para activar la
+  característica de descarga de fichero, el valor tendrá una secuencia
+  de palabras extraídas de la lista de abajo.
+  \begin{itemize}
+  \item[\texttt{bz2}] Un fichero \command{tar} con el método de
+    compresión \texttt{bzip2}.  Tiene la mejor tasa de compresión,
+    pero usa más tiempo de procesamiento en el servidor.
+  \item[\texttt{gz}] Un fichero \command{tar}, comprimido con
+    \texttt{gzip}.
+  \item[\texttt{zip}] Un fichero \command{zip}, comprimido con LZW.
+    Este formato posee la peor tasa de compresión, pero es muy usado en
+    el mundo Windows.
+  \end{itemize}
+  Si da una lista vacía o no tiene la entrada
+  \rcitem{web}{allow\_archive}, esta característica se deshabilitará.
+  A continuación un ejemplo de cómo habilitar los tres formatos soportados.
+  \begin{codesample4}
+    [web]
+    allow_archive = bz2 gz zip
+  \end{codesample4}
+\item[\rcitem{web}{allowpull}] Booleano.  Determina si la interfaz web
+  permite a los usuarios remotos emplear \hgcmd{pull} y \hgcmd{clone}
+  sobre el repositorio~HTTP.  Si se coloca \texttt{no} o
+  \texttt{false}, solamente la porción de los procesos
+  ``orientados-a-humanos'' se habilita de la interfaz web.
+\item[\rcitem{web}{contact}] Cadena.  Una cadena en forma libre (pero
+  preferiblemente corta) que identifica a la persona o grupo a cargo
+  del repositorio.  Usualmente contiene el nombre y la dirección de
+  correo electrónico de una persona o de una lista de correo.  Aveces
+  tiene sentido colocar esta opción en el fichero \sfilename{.hg/hgrc}
+  del repositorio, pero en otras oportunidades en el \hgrc\ global si
+  todos los repositorios tienen un único mantenedor.
+\item[\rcitem{web}{maxchanges}] Entero.  La cantidad máxima de
+  conjuntos de cambios a mostrar de forma predeterminada en cada página.
+\item[\rcitem{web}{maxfiles}] Entero.  La cantidad máxima
+  predeterminada de ficheros modificados a desplegar en una página.
+\item[\rcitem{web}{stripes}] Entero.  Si la interfaz web despliega
+  ``franjas'' para facilitar la visualización alineada de filas cuando
+  se ve una tabla, este valor controla la cantidad de filas en cada
+  franja.
+\item[\rcitem{web}{style}] Controla la plantilla que Mercurial usa para
+  desplegar la interfaz web.  Mercurial viene con dos plantillas web,
+  llamadas \texttt{default} y \texttt{gitweb} (La primera es
+  visualmente más atractiva).  Puede especificar una plantilla propia;
+  consulte el capítulo~\ref{chap:template}.  A continuación mostramos
+  cómo habilitar el estilo \texttt{gitweb}.
+  \begin{codesample4}
+    [web]
+    style = gitweb
+  \end{codesample4}
+\item[\rcitem{web}{templates}] Ruta.  Directorio en el que se buscarán
+  los ficheros plantilla.  De forma predeterminada, busca en el
+  directorio en el cual fue instalado.
+\end{itemize}
+Si usa \sfilename{hgwebdir.cgi}, puede añadir otras opciones de
+configuración en una sección \section{web} del fichero
+\sfilename{hgweb.config} en lugar del fichero \hgrc\, si lo considera
+más conveniente.  Estas opciones son \rcitem{web}{motd} y
+\rcitem{web}{style}.
+
+\subsubsection{Opciones específicas para repositorios individuales}
+
+Ciertas opciones de configuración de \rcsection{web} deben estar
+ubicadas en el \sfilename{.hg/hgrc} de un repositorio en lugar del
+fichero del usuario o el \hgrc global.
+\begin{itemize}
+\item[\rcitem{web}{description}] Cadena.  Una cadena de forma
+  libre (preferiblemente corta) que describa los contenidos o el
+  propósito del repositorio.
+\item[\rcitem{web}{name}] Cadena.  El nombre para visualizar en la
+  interfaz web del repositorio. Sustituye el nombre predeterminado, el
+  cual es el último componente de la ruta del repositorio.
+\end{itemize}
+
+\subsubsection{Opciones específicas a la orden \hgcmd{serve}}
+
+Algunas opciones en la sección \rcsection{web} de un fichero \hgrc\
+son de uso exclusivo para la orden \hgcmd{serve}.
+\begin{itemize}
+\item[\rcitem{web}{accesslog}] Ruta.  El nombre del fichero en el cual
+  se escribe la bitácora de acceso.  En principio, la orden
+  \hgcmd{serve} escribe esta información a la salida estándar, no a un
+  fichero. Las líneas de la bitácora se escriben en un formato de
+  fichero ``combinado'' estándar, usado por casi todos los servidores
+  web.
+\item[\rcitem{web}{address}] Cadena.  La dirección local en la cual el
+  servidor debe escuchar peticiones entrantes.  En principio, el
+  servidor escucha en todas las direcciones.
+\item[\rcitem{web}{errorlog}] Ruta.  El nombre de un fichero en el
+  cual escribir la bitácora de error.  En principio, la orden
+  \hgcmd{serve} escribe esta información en la salida de error
+  estándar, no a un fichero.
+\item[\rcitem{web}{ipv6}] Booleano.  Si se usa o no el protocolo
+  IPv6. En principio, IPv6 no se usa.
+\item[\rcitem{web}{port}] Entero.  El número del puerto~TCP en el cuál
+  el servidor escuchará.  El puerto predeterminado es el~8000.
+\end{itemize}
+
+\subsubsection{Elegir el fichero \hgrc\ correcto para las
+  configuraciones de \rcsection{web}}
+
+Es importante recordar que un servidor web como Apache o
+\texttt{lighttpd} se ejecutarán bajo el usuario~ID que generalmente no
+es el suyo  Los guiones CGI ejecutados por su servidor, tales como
+\sfilename{hgweb.cgi}, se ejecutarán también con el usuario~ID.
+
+Si añade opciones \rcsection{web} a su fichero personal \hgrc\, Los
+guiones CGI no leerán tal fichero \hgrc\.  Tales configuraciones
+solamente afectarán el comportamiento de la orden \hgcmd{serve} cuando
+usted lo ejecuta.  Para logar que los guiones CGI vean sus
+configuraciones, o bien cree un fichero \hgrc\ en el directorio hogar
+del usuario ID que ejecuta su servidor web, o añada tales
+configuraciones al fichero global \hgrc.
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/concepts.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,650 @@
+\chapter{Tras bambalinas}
+\label{chap:concepts}
+
+A diferencia de varios sistemas de control de revisiones, los
+conceptos en los que se fundamenta Mercurial son lo suficientemente
+simples como para entender fácilmente cómo funciona el software. 
+Saber esto no es necesario, pero considero útil tener un ``modelo
+mental'' de qué es lo que sucede.
+
+Comprender esto me da la confianza de que Mercurial ha sido
+cuidadosamente diseñado para ser tanto \emph{seguro} como
+\emph{eficiente}.  Y tal vez con la misma importancia, si es fácil
+para mí hacerme a una idea adecuada de qué está haciendo el software
+cuando llevo a cabo una tarea relacionada con control de revisiones,
+es menos probable que me sosprenda su comportamiento.
+
+En este capítulo, cubriremos inicialmente los conceptos centrales
+del diseño de Mercurial, y luego discutiremos algunos detalles
+interesantes de su implementación.
+
+\section{Registro del historial de Mercurial}
+
+\subsection{Seguir el historial de un único fichero}
+
+Cuando Mercurial sigue las modificaciones a un fichero, guarda el
+historial de dicho fichero en un objeto de metadatos llamado
+\emph{filelog}\ndt{Fichero de registro}.  Cada entrada en el fichero
+de registro contiene suficiente información para reconstruir una
+revisión del fichero que se está siguiendo. Los ficheros de registro
+son almacenados como ficheros el el directorio
+\sdirname{.hg/store/data}. Un fichero de registro contiene dos tipos
+de información: datos de revisiones, y un índice para ayudar a
+Mercurial a buscar revisiones eficientemente.
+
+El fichero de registro de un fichero grande, o con un historial muy
+largo, es guardado como ficheros separados para datos (sufijo
+``\texttt{.d}'') y para el índice (sufijo ``\texttt{.i}''). Para
+ficheros pequeños con un historial pequeño, los datos de revisiones y
+el índice son combinados en un único fichero ``\texttt{.i}''. La
+correspondencia entre un fichero en el directorio de trabajo y el
+fichero de registro que hace seguimiento a su historial en el
+repositorio se ilustra en la figura~\ref{fig:concepts:filelog}.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{filelog}
+  \caption{Relación entre ficheros en el directorio de trabajo y
+  ficheros de registro en el repositorio}
+  \label{fig:concepts:filelog}
+\end{figure}
+
+\subsection{Administración de ficheros monitoreados}
+
+Mercurial usa una estructura llamada \emph{manifiesto} para
+% TODO collect together => centralizar
+centralizar la información que maneja acerca de los ficheros que
+monitorea. Cada entrada en el manifiesto contiene información acerca
+de los ficheros involucrados en un único conjunto de cambios. Una
+entrada registra qué ficheros están presentes en el conjunto de
+cambios, la revisión de cada fichero, y otros cuantos metadatos del
+mismo.
+
+\subsection{Registro de información del conjunto de cambios}
+
+La \emph{bitácora de cambios} contiene información acerca de cada
+conjunto de cambios. Cada revisión indica quién consignó un cambio, el
+comentario para el conjunto de cambios, otros datos relacionados con
+el conjunto de cambios, y la revisión del manifiesto a usar.
+
+\subsection{Relaciones entre revisiones}
+
+Dentro de una bitácora de cambios, un manifiesto, o un fichero de
+registro, cada revisión conserva un apuntador a su padre inmediato
+(o sus dos padres, si es la revisión de una fusión). Como menciońe
+anteriormente, también hay relaciones entre revisiones \emph{a través}
+de estas estructuras, y tienen naturaleza jerárquica.
+
+Por cada conjunto de cambios en un repositorio, hay exactamente una
+revisión almacenada en la bitácora de cambios. Cada revisión de la
+bitácora de cambios contiene un apuntador a una única revisión del
+manifiesto. Una revisión del manifiesto almacena un apuntador a una
+única revisión de cada fichero de registro al que se le hacía
+seguimiento cuando fue creado el conjunto de cambios. Estas relaciones
+se ilustran en la figura~\ref{fig:concepts:metadata}.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{metadata}
+  \caption{Relaciones entre metadatos}
+  \label{fig:concepts:metadata}
+\end{figure}
+
+Como lo muestra la figura, \emph{no} hay una relación ``uno a uno''
+entre las revisiones en el conjunto de cambios, el manifiesto, o el
+fichero de registro. Si el manifiesto no ha sido modificado de un
+conjunto de cambios a otro, las entradas en la bitácora de cambios
+para esos conjuntos de cambios apuntarán a la misma revisión del
+manifiesto. Si un fichero monitoreado por Mercurial no sufre ningún
+cambio de un conjunto de cambios a otro, la entrada para dicho fichero
+en las dos revisiones del manifiesto apuntará a la misma revisión de
+su fichero de registro.
+
+\section{Almacenamiento seguro y eficiente}
+
+La base común de las bitácoras de cambios, los manifiestos, y los
+ficheros de registros es provista por una única estructura llamada el
+\emph{revlog}\ndt{Contracción de \emph{revision log}, registro de
+revisión.}.
+
+\subsection{Almacenamiento eficiente}
+
+El revlog provee almacenamiento eficiente de revisiones por medio del
+mecanismo de \emph{deltas}\ndt{Diferencias.}.  En vez de almacenar una
+copia completa del fichero por cada revisión, almacena los cambios
+necesarios para transformar una revisión anterior en la nueva
+revisión. Para muchos tipos de fichero, estos deltas son típicamente
+de una fracción porcentual del tamaño de una copia completa del
+fichero.
+
+Algunos sistemas de control de revisiones obsoletos sólo pueden
+manipular deltas de ficheros de texto plano. Ellos o bien almacenan
+los ficheros binarios como instantáneas completas, o codificados en
+alguna representación de texto plano adecuada, y ambas alternativas
+son enfoques que desperdician bastantes recursos. Mercurial puede
+manejar deltas de ficheros con contenido binario arbitrario; no
+necesita tratar el texto plano como un caso especial.
+
+\subsection{Operación segura}
+\label{sec:concepts:txn}
+
+Mercurial sólo \emph{añade} datos al final de los ficheros de revlog. Nunca
+modifica ninguna sección de un fichero una vez ha sido escrita. Esto es más
+robusto y eficiente que otros esquemas que requieren modificar o reescribir
+datos.
+
+Adicionalmente, Mercurial trata cada escritura como parte de una
+\emph{transacción}, que puede cubrir varios ficheros. Una transacción es
+\emph{atómica}: o bien la transacción tiene éxito y entonces todos sus efectos
+son visibles para todos los lectores, o la operación completa es cancelada.
+% TODO atomicidad no existe de acuerdo a DRAE, reemplazar
+Esta garantía de atomicidad implica que, si usted está ejecutando dos copias de
+Mercurial, donde una de ellas está leyendo datos y la otra los está escribiendo,
+el lector nunca verá un resultado escrito parcialmente que podría confundirlo.
+
+El hecho de que Mercurial sólo hace adiciones a los ficheros hace más fácil
+proveer esta garantía transaccional. A medida que sea más fácil hacer
+operaciones como ésta, más confianza tendrá usted en que sean hechas
+correctamente.
+
+\subsection{Recuperación rápida de datos}
+
+Mercurial evita ingeniosamente un problema común a todos los sistemas de control
+de revisiones anteriores> el problema de la
+\emph{recuperación\ndt{\emph{Retrieval}. Recuperación en el sentido de traer los
+datos, o reconstruirlos a partir de otros datos, pero no debido a una falla o
+calamidad, sino a la operación normal del sistema.} ineficiente de datos}.
+Muchos sistemas de control de revisiones almacenan los contenidos de una
+revisión como una serie incremental de modificaciones a una ``instantánea''.
+Para reconstruir una versión cualquiera, primero usted debe leer la instantánea,
+y luego cada una de las revisiones entre la instantánea y su versión objetivo.
+Entre más largo sea el historial de un fichero, más revisiones deben ser leídas,
+y por tanto toma más tiempo reconstruir una versión particular.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{snapshot}
+  \caption{Instantánea de un revlog, con deltas incrementales}
+  \label{fig:concepts:snapshot}
+\end{figure}
+
+La innovación que aplica Mercurial a este problema es simple pero efectiva.
+Una vez la cantidad de información de deltas acumulada desde la última
+instantánea excede un umbral fijado de antemano, se almacena una nueva
+instantánea (comprimida, por supuesto), en lugar de otro delta. Esto hace
+posible reconstruir \emph{cualquier} versión de un fichero rápidamente. Este
+enfoque funciona tan bien que desde entonces ha sido copiado por otros sistemas
+de control de revisiones.
+
+La figura~\ref{fig:concepts:snapshot} ilustra la idea. En una entrada en el
+fichero índice de un revlog, Mercurial almacena el rango de entradas (deltas)
+del fichero de datos que se deben leer para reconstruir una revisión en
+particular.
+
+\subsubsection{Nota al margen: la influencia de la compresión de vídeo}
+
+Si le es familiar la compresión de vídeo, o ha mirado alguna vez una emisión de
+TV a través de cable digital o un servicio de satélite, puede que sepa que la 
+mayor parte de los esquemas de compresión de vídeo almacenan cada cuadro del
+mismo como un delta contra el cuadro predecesor. Adicionalmente, estos esquemas
+usan técnicas de compresión ``con pérdida'' para aumentar la tasa de
+compresión, por lo que los errores visuales se acumulan a lo largo de una
+cantidad de deltas inter-cuadros.
+
+Ya que existe la posibilidad de que un flujo de vídeo se ``pierda''
+ocasionalmente debido a fallas en la señal, y para limitar la acumulación de
+errores introducida por la compresión con pérdidas, los codificadores de vídeo
+insertan periódicamente un cuadro completo (también llamado ``cuadro clave'') en
+el flujo de vídeo; el siguiente delta es generado con respecto a dicho cuadro.
+Esto quiere decir que si la señal de vídeo se interrumpe, se reanudará una vez
+se reciba el siguiente cuadro clave. Además, la acumulación de errores de
+codificación se reinicia con cada cuadro clave.
+
+\subsection{Identificación e integridad fuerte}
+
+Además de la información de deltas e instantáneas, una entrada en un
+% TODO de pronto aclarar qué diablos es un hash?
+revlog contiene un hash criptográfico de los datos que representa.
+Esto hace difícil falsificar el contenido de una revisión, y hace
+fácil detectar una corrupción accidental.
+
+Los hashes proveen más que una simple revisión de corrupción: son
+usados como los identificadores para las revisiones. 
+% TODO no entendí completamente la frase a continuación
+Los hashes de
+identificación de conjuntos de cambios que usted ve como usuario final
+son de las revisiones de la bitácora de cambios. Aunque los ficheros
+de registro y el manifiesto también usan hashes, Mercurial sólo los
+usa tras bambalinas.
+
+Mercurial verifica que los hashes sean correctos cuando recupera
+revisiones de ficheros y cuando jala cambios desde otro repositorio.
+Si se encuentra un problema de integridad, Mercurial se quejará y
+detendrá cualquier operación que esté haciendo.
+
+Además del efecto que tiene en la eficiencia en la recuperación, el
+uso periódico de instantáneas de Mercurial lo hace más robusto frente
+a la corrupción parcial de datos. Si un fichero de registro se
+corrompe parcialmente debido a un error de hardware o del sistema, a
+menudo es posible reconstruir algunas o la mayoría de las revisiones a
+partir de las secciones no corrompidas del fichero de registro, tanto
+antes como después de la sección corrompida. Esto no sería posible con
+un sistema de almacenamiento basado únicamente en deltas.
+
+\section{Historial de revisiones, ramas y fusiones}
+
+Cada entrada en el revlog de Mercurial conoce la identidad de la
+revisión de su ancestro inmediato, al que se conoce usualmente como su
+\emph{padre}. De hecho, una revisión contiene sitio no sólo para un
+padre, sino para dos. Mercurial usa un hash especial, llamado el
+``ID nulo'', para representar la idea de ``no hay padre aquí''. Este
+hash es simplemente una cadena de ceros.
+
+En la figura~\ref{fig:concepts:revlog} usted puede ver un ejemplo de
+la estructura conceptual de un revlog. Los ficheros de registro,
+manifiestos, y bitácoras de cambios comparten la misma estructura;
+sólo difieren en el tipo de datos almacenados en cada delta o
+instantánea.
+
+La primera revisión en un revlog (al final de la imagen) tiene como
+padre al ID nulo, en las dos ranuras disponibles para padres. En una
+revisión normal, la primera ranura para padres contiene el ID de la
+revisión padre, y la segunda contiene el ID nulo, señalando así que la
+revisión sólo tiene un padre real. Un par de revisiones que tenga el
+mismo ID padre son ramas. Una revisión que representa una fusión entre
+ramas tiene dos IDs de revisión normales en sus ranuras para padres.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{revlog}
+  \caption{}
+  \label{fig:concepts:revlog}
+\end{figure}
+
+\section{El directorio de trabajo}
+
+% TODO revisar párrafo, no me convence la traducción
+En el directorio de trabajo, Mercurial almacena una instantánea de los
+ficheros  del repositorio como si fueran los de un conjunto de cambios
+particular.
+
+El directorio de trabajo ``sabe'' qué conjunto de cambios contiene.
+Cuando usted actualiza el directorio de trabajo para que contenga un
+conjunto de cambios particular, Mercurial busca la revisión adecuada
+del manifiesto para averiguar qué ficheros estaba monitoreando cuando
+se hizo la consignación del conjunto de cambios, y qué revisión de
+cada fichero era la actual en ese momento. Luego de eso, recrea una
+copia de cada uno de esos ficheros, con los mismos contenidos que
+tenían cuando fue consignado el conjunto de cambios.
+
+El \emph{estado de directorio}\ndt{dirstate, en inglés en el
+original.} contiene el conocimiento de Mercurial acerca del directorio
+de trabajo. Allí se detalla a qué conjunto de cambios es actualizado
+el directorio de trabajo, y todos los ficheros que Mercurial está
+monitoreando en este directorio.
+
+Tal como la revisión de un revlog tiene espacio para dos padres, para
+que pueda representar tanto una revisión normal (con un solo padre) o
+una fusión de dos revisiones anteriores, el estado de directorio tiene
+espacio para dos padres. Cuando usted usa el comando \hgcmd{update},
+el conjunto de cambios al que usted se actualiza es almacenado en la
+casilla destinada al ``primer padre'', y un ID nulo es almacenado en
+la segunda. Cuando usted hace una fusión (\hgcmd{merge}) con otro
+conjunto de cambios, la casilla para el primer padre permanece sin
+cambios, y la casilla para el segundo es actualizada con el conjunto
+de cambios con el que usted acaba de hacer la fusión. El comando
+\hgcmd{parents} le indica cuáles son los padres del estado de
+directorio.
+
+\subsection{Qué pasa en una consignación}
+
+El estado de directorio almacena información sobre los padres para
+algo más que mero registro. Mercurial usa los padres del estado de
+directorio como \emph{los padres de un nuevo conjunto de cambios}
+cuando usted hace una consignación.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{wdir}
+  \caption{El directorio de trabajo puede tener dos padres}
+  \label{fig:concepts:wdir}
+\end{figure}
+
+La figura~\ref{fig:concepts:wdir} muestra el estado normal del
+directorio de trabajo, que tiene un único conjunto de cambios como
+padre. Dicho conjunto de cambios es la \emph{punta}, el conjunto de
+cambios más reciente en el repositorio que no tiene hijos.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{wdir-after-commit}
+  \caption{El directorio de trabajo obtiene nuevos padres luego de una
+  consignación}
+  \label{fig:concepts:wdir-after-commit}
+\end{figure}
+
+Es útil pensar en el directorio de trabajo como en ``el conjunto de
+cambios que estoy a punto de enviar''. Cualquier fichero que usted le
+diga a Mercurial que fue añadido, borrado, renombrado o copiado, se
+verá reflejado en ese conjunto de cambios, como también se verán las
+modificaciones a cualquiera de los ficheros que Mercurial ya esté
+monitoreando; el nuevo conjunto de cambios dentrá los padres del
+directorio de trabajo como propios.
+
+Luego de una consignación, Mercurial actualizará los padres del
+directorio de trabajo, de tal manera que el primer padre sea el ID del
+nuevo conjunto de cambios, y el segundo sea el ID nulo. Esto puede
+verse en la figura~\ref{fig:concepts:wdir-after-commit}.  Mercurial no
+toca ninguno de los ficheros del directorio de trabajo cuando usted
+hace la consignación; sólo modifica el estado de directorio para
+anotar sus nuevos padres.
+
+\subsection{Creación de un nuevo frente}
+
+Es perfectamente normal actualizar el directorio de trabajo a un
+conjunto de cambios diferente a la punta actual. Por ejemplo, usted
+podría desear saber en qué estado se encontraba su proyecto el martes
+pasado, o podría estar buscando en todos los conjuntos de cambios para
+saber cuándo se introdujo un fallo. En casos como éstos, la acción
+natural es actualizar el directorio de trabajo al conjunto de cambios
+de su interés, y examinar directamente los ficheros en el directorio
+de trabajo para ver sus contenidos tal como estaban en el momento de
+hacer la consignación. El efecto que tiene esto se muestra en la
+figura~\ref{fig:concepts:wdir-pre-branch}.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{wdir-pre-branch}
+  \caption{El directorio de trabajo, actualizado a un conjunto de
+  cambios anterior}
+  \label{fig:concepts:wdir-pre-branch}
+\end{figure}
+
+Una vez se ha actualizado el directorio de trabajo a un conjunto de
+cambios anterior, qué pasa si se hacen cambios, y luego se hace una
+consignación? Mercurial se comporta en la misma forma que describí
+anteriormente. Los padres del directorio de trabajo se convierten en
+los padres del nuevo conjunto de cambios. Este nuevo conjunto de
+cambios no tiene hijos, así que se convierte en la nueva punta. Y el
+repositorio tiene ahora dos conjuntos de cambios que no tienen hijos;
+a éstos los llamamos \emph{frentes}. Usted puede apreciar la
+estructura que esto crea en la figura~\ref{fig:concepts:wdir-branch}.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{wdir-branch}
+  \caption{Después de una consignación hecha mientras se usaba un
+  conjunto de cambios anterior}
+  \label{fig:concepts:wdir-branch}
+\end{figure}
+
+\begin{note}
+    Si usted es nuevo en Mercurial, debería tener en mente un
+    ``error'' común, que es usar el comando \hgcmd{pull} sin ninguna
+    opción. Por defecto, el comando \hgcmd{pull} \emph{no} actualiza
+    el directorio de trabajo, así que usted termina trayendo nuevos
+    conjuntos de cambios a su repositorio, pero el directorio de
+    trabajo sigue usando el mismo conjunto de cambios que tenía antes
+    de jalar. Si usted hace algunos cambios, y luego hace una
+    consignación, estará creando un nuevo frente, porque su directorio
+    de trabajo no es sincronizado a cualquiera que sea la nueva punta.
+
+    Pongo la palabra ``error'' en comillas porque todo lo que usted
+    debe hacer para rectificar la situación es hacer una fusión
+    (\hgcmd{merge}), y luego una consignación (\hgcmd{commit}). En
+    otras palabras, esto casi nunca tiene consecuencias negativas;
+    sólo sorprende a la gente. Discutiré otras formas de evitar este
+    comportamiento, y porqué Mercurial se comporta de esta forma,
+    inicialmente sorprendente, más adelante.
+\end{note}
+
+\subsection{Fusión de frentes}
+
+Cuando usted ejecuta el comando \hgcmd{merge}, Mercurial deja el
+primer padre del directorio de trabajo intacto, y escribe como segundo
+padre el conjunto de cambios contra el cual usted está haciendo la
+fusión, como se muestra en la figura~\ref{fig:concepts:wdir-merge}.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{wdir-merge}
+  \caption{Fusión de dos frentes}
+  \label{fig:concepts:wdir-merge}
+\end{figure}
+
+Mercurial también debe modificar el directorio de trabajo, para
+fusionar los ficheros que él monitorea en los dos conjuntos de
+cambios. Con algunas simplificaciones, el proceso es el siguiente, por
+cada fichero en los manifiestos de ambos conjuntos de cambios.
+\begin{itemize}
+\item Si ningún conjunto de cambios ha modificado un fichero, no se
+    hace nada con el mismo.
+\item Si un conjunto de cambios ha modificado un fichero, y el otro no
+    lo ha hecho, se crea una copia del fichero con las modificaciones
+    pertinentes en el directorio de trabajo.
+\item Si un conjunto de cambios borra un fichero, y el otro no lo ha
+    hecho (o también lo borró), se borra dicho fichero del directorio
+    de trabajo.
+\item Si un conjunto de cambios ha borrado un fichero, pero el otro lo ha
+    modificado, se le pregunta al usuario qué hacer: conservar el
+    fichero modificado, o borrarlo?
+\item Si ambos conjuntos de cambios han modificado un fichero, se
+    invoca el programa externo de fusión para definir el nuevo
+    contenido del fichero fusionado. Esto puede requerir interacción
+    directa de parte del usuario.
+\item Si un conjunto de cambios ha modificado un fichero, y el otro ha
+    renombrado o copiado el mismo, asegurarse de que los cambios sigan
+    al nuevo nombre de fichero.
+\end{itemize}
+Hay más detalles---hacer una fusión tiene una gran cantidad de casos
+especiales---pero éstas son las elecciones más comunes que se ven
+involucradas en una fusión. Como usted puede ver, muchos de los casos
+son completamente automáticos, y de hecho la mayoría de las fusiones
+terminan automáticamente, sin requerir la interacción del usuario para
+resolver ningún conflicto.
+
+Cuando considere qué pasa cuando usted hace una consignación después
+de una fusión, de nuevo el directorio de trabajo es ``el conjunto de
+cambios que estoy a punto de consignar''. Una vez termina su trabajo
+el comando \hgcmd{merge}, el directorio de trabajo tiene dos padre;
+éstos se convertirán en los padres del nuevo conjunto de cambios.
+
+Mercurial le permite hacer múltiples fusiones, pero usted debe
+consignar los resultados de cada fusión sucesivamente. Esto es
+necesario porque Mercurial sólo monitorea dos padres, tanto para las
+revisiones como para los directorios de trabajo. Aunque técnicamente
+es posible fusionar varios conjuntos de trabajo en una sola operación,
+la posibilidad de confundir al usuario y crear un desorden terrible en
+la fusión se hace incontenible de inmediato.
+
+\section{Otras características de diseño interesantes}
+
+En las secciones anteriores, he tratado de resaltar algunos de los
+aspectos más importantes del diseño de Mercurial, para mostrar que se
+presta gran cuidado y atención a la confiabilidad y el desempeño. Sin
+embargo, la atención a los detalles no para ahí. Hay una cantidad de
+aspectos de la construcción de Mercurial que encuentro interesantes
+personalmente. Detallaré unos cuantos de ellos aquí, aparte de los
+elementos ``importantes'' de arriba, para que, si usted está
+% TODO the amount of thinking => (la cantidad de) esfuerzo mental
+interesado, pueda obetener una idea mejor de la cantidad de esfuerzo
+mental invertido en el diseño de un sistema bien diseñado.
+
+
+\subsection{Compresión ingeniosa}
+
+Cuando es adecuado, Mercurial almacenará tanto las instantáneas como
+los deltas en formato comprimido. Lo hace \emph{tratando} siempre de
+comprimir una instantánea o delta, y conservando la versión comprimida
+sólo si es más pequeña que la versión sin compresión.
+
+Esto implica que Mercurial hace ``lo correcto'' cuando almacena un
+fichero cuyo formato original está comprimido, como un fichero
+\texttt{zip} o una imagen JPEG.  Cuando estos tipos de ficheros son
+comprimidos por segunda vez, el fichero resultante usualmente es más
+grande que la versión comprimida una sola vez, por lo que Mercurial
+almacenará el fichero \texttt{zip} o JPEG original.
+
+Los deltas entre revisiones de un fichero comprimido usualmente son
+más grandes que las instantáneas del mismo fichero, y Mercurial de
+nuevo hace ``lo correcto'' en estos casos. Él encuentra que dicho
+delta excede el umbral respecto al cual se debería almacenar una
+instantánea completa del fichero, así que almacena la instantánea,
+ahorrando espacio de nuevo respecto al enfoque simplista de usar
+únicamente deltas.
+
+\subsubsection{Recompresión de red}
+
+Cuando almacena las revisiones en disco, Mercurial usa el algoritmo de
+compresión ``deflación'' (el mismo usado en el popular formato de
+fichero \texttt{zip}), que provee una buena velocidad con una tasa de
+compresión respetable. Sin embargo, cuando se transmiten datos de
+revisiones a través de una conexión de red, Mercurial descomprime los
+datos comprimidos de las revisiones.
+
+Si la conexión es hecha a través de HTTP, Mercurial recomprime el
+flujo completo de datos usando un algoritmo de compresión que brinda
+una mejor tasa de compresión (el algoritmo Burrows-Wheeler del
+ampliamente usado paquete de compresión \texttt{bzip2}). Esta
+combinación de algoritmo y compresión del flujo completo de datos
+(en vez de una revisión a la vez) reduce sustancialmente la cantidad
+de bytes a transferir, brindando así un mejor desempeño de red sobre
+casi todo tipo de redes.
+
+(Si la conexión se hace sobre \command{ssh}, Mercurial \emph{no}
+recomprmime el flujo, porque \command{ssh} puede hacer esto por sí
+mismo.)
+
+\subsection{Reordenado de lectura/escritura y atomicidad}
+
+Añadir datos al final de un fichero no es todo lo que hace falta para
+garantizar que un lector no verá una escritura parcial. Si recuerda la
+figura~\ref{fig:concepts:metadata}, las revisiones en la bitácora de
+cambios apuntan a revisiones en el manifiesto, y las revisiones en el
+manifiesto apuntan a revisiones en ficheros de registro. Esta
+jerarquía es deliberada.
+
+Un escritor inicia una transacción al escribir los datos del ficheros
+del fichero de registro y el manifiesto, y no escribe nada en la
+bitácora de cambios hasta que dichas escrituras hayan terminado. Un
+lector empieza leyendo datos de la bitácora de cambios, luego del
+manifiesto, y finalmente del fichero de registro.
+
+%TODO revisar párrafo completo, no me gusta el resultado
+Como el escritor siempre termina de escribir los datos en el fichero
+de registro y en el manifiesto antes de escribir a la bitácora de
+cambios, un lector nunca verá un apuntador a una versión parcialmente
+escrita de revisiones del manifiesto desde la bitácora de cambios, y
+nunca leerá un apuntador a una revisión parcialmente escrita del
+fichero de registro desde el manifiesto.
+
+\subsection{Acceso concurrente}
+
+El reordenado de lectura/escritura y la atomicidad garantizan que
+Mercurial nunca necesita \emph{bloquear} un repositorio cuando está
+leyendo datos, aún si se está escribiendo al repositorio mientras se
+hace la lectura. Esto tiene un gran efecto en la escalabilidad; usted
+puede tener cualquier cantidad de procesos Mercurial leyendo datos de
+un repositorio de manera segura al mismo tiempo, sin importar si se
+está escribiendo al mismo o no.
+
+La naturaleza carente de bloqueos de la lectura significa que si usted
+está compartiendo un repositorio en un sistema multiusuario, no
+necesita dar a los usuarios locales permisos de \emph{escritura} a su
+repositorio para que ellos puedan clonarlo o jalar cambios; sólo
+necesitan permisos de \emph{lectura}. (Esta \emph{no} es una
+%TODO signo de admiración de apertura
+característica común entre los sistemas de control de revisiones, así
+que no la dé por hecha! Muchos de ellos requieren que los lectores
+sean capaces de bloquear el repositorio antes de poder leerlo, y esto
+requiere acceso de escritura en al menos un directorio, lo que por
+supuesto se convierte en una fuente de todo tipo de problemas
+administrativos y de seguridad bastante molestos.)
+
+Mercurial usar bloqueos para asegurarse de que sólo un proceso pueda
+escribir a un repositorio al mismo tiempo (el mecanismo de bloqueo es
+seguro incluso sobre sistemas de ficheros notoriamente hostiles al
+bloqueo, como NFS). Si un repositorio está bloqueado, los escritores
+esperarán un buen rato para revisar si el repositorio ya ha sido
+desbloqueado, pero si el repositorio sique bloqueado por mucho tiempo,
+el proceso que intenta escribir fallará por tiempo de espera máximo.
+Esto significa que sus guiones automáticos diarios no se quedarán
+esperando para siempre, apilándose si el sistema se cayó sin que nadie
+se diera cuenta, por ejemplo. (Sí, el tiempo de espera máximo es
+configurable, de cero a infinito).
+
+
+\subsubsection{Acceso seguro al estado de directorio}
+
+Al igual que con los datos de revisión, Mercurial no requiere un
+bloqueo para leer el fichero de estado de directorio; sí se usa un
+bloqueo para escribir a él. Para evitar la posibilidad de leer una
+copia parcialmente escrita del fichero de estado de directorio,
+Mercurial escribe a un fichero con un nombre único en el mismo
+directorio del fichero de estado de directorio, y luego renombra
+atómicamente este fichero temporal a \filename{dirstate}\ndt{Estado de
+directorio.}. Así se garantiza que el fichero llamado
+\filename{dirstate} esté completo, y no parcialmente escrito.
+
+\subsection{Evitar movimientos de brazo}
+
+Un aspecto crítico para el desempeño de Mercurial es evitar los
+movimientos del brazo de lectura del disco duro, ya que cualquier
+movimiento de brazo es mucho más costoso que incluso una operación de
+lectura relativamente grande.
+
+Es por esto que, por ejemplo, el estado de directorio es almacenado
+como un solo fichero. Si hubiera un estado de directorio por cada
+directorio que Mercurial monitorea, el disco haría un movimiento de
+brazo por cada directorio. En cambio, Mercurial lee el estado de
+directorio completo en un solo paso.
+
+Mercurial también usa un esquema de ``copiar al escribir'' cuando
+clona un repositorio en un mismo medio de almacenamiento local. En vez
+de copiar cada fichero de revlog del repositorio viejo al nuevo, se
+crea un ``enlace duro'', que es una manera sucinta de decir
+``estos dos nombres apuntan al mismo fichero''. Cuando Mercurial está
+a punto de escribir a uno de los ficheros de revlog, revisa si la
+cantidad de nombres apuntando al fichero es de más de uno. Si lo es,
+más de un repositorio está usando el fichero, así que Mercurial hace
+una nueva copia del fichero, privada para este repositorio.
+
+Algunos desarrolladores de control de revisiones han indicado que la
+idea de hacer una copia privada completa de un fichero no es eficiente
+desde el punto de vista de almacenamiento. Aunque esto es cierto, el
+almacenamiento es barato, y este método brinda el máximo rendimiento
+al tiempo que delega la mayor parte del trabajo de manejo de ficheros
+al sistema operativo. Un esquema alternativo seguramente reduciría el
+desempeño y aumentaría la complejidad del software, cada uno de los
+cuales es mucho más importante para la ``sensación'' que se tiene del
+software en el trabajo día a día.
+
+\subsection{Otros contenidos del estado de directorio}
+
+Debido a que Mercurial no lo fuerza a indicar si usted está
+modificando un fichero, se usa el estado de directorio para almacenar
+información extra para poder determinar efecientemente si usted ha
+modificado un fichero. Por cada fichero en el directorio de trabajo,
+se almacena el momento en que Mercurial modificó por última vez el
+fichero, y el tamaño del fichero en ese momento.
+
+Cuando usted añade (\hgcmd{add}), remueve (\hgcmd{remove}), renombra
+(\hgcmd{rename}) o copia (\hgcmd{copy}) ficheros, Mercurial actualiza
+el estado de directorio para saber qué hacer con dichos ficheros
+cuando usted haga la consignación.
+
+Cuando Mercurial está revisando el estado de los ficheros en el
+directorio de trabajo, revisa primero la fecha de modificación del
+fichero. Si no ha cambiado, el fichero no ha sido modificado. Si el
+tamaño del fichero ha cambiado, el fichero ha sido modificado. Sólo en
+el caso en que el tiempo de modificación ha cambiado, pero el tamaño
+no, es necesario leer el contenido del fichero para revisar si ha
+cambiado. Almacenar estos pocos datos reduce dramáticamente la
+cantidad de datos que Mercurial debe leer, lo que brinda una mejora en
+el rendimiento grande, comparado con otros sistemas de control de
+revisiones.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/daily.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,404 @@
+\chapter{Mercurial día a día}
+\label{chap:daily}
+
+\section{Cómo indicarle a Mercurial qué ficheros seguir}
+
+Mercurial no trabaja con ficheros en su repositorio a menos que usted
+se lo indique explícitamente.  La orden \hgcmd{status} le mostrará
+cuáles ficheros son desconocidos para Mercurial; se emplea un
+``\texttt{?}'' para mostrar tales ficheros.
+
+Para indicarle a Mercurial que tenga en cuenta un fichero, emplee la
+orden \hgcmd{add}. Una vez que haya adicionado el fichero, la línea
+referente al fichero al aplicar la orden \hgcmd{status} para tal
+fichero cambia de ``\texttt{?}'' a ``\texttt{A}''.
+\interaction{daily.files.add}
+
+Después de invocar \hgcmd{commit}, los ficheros que haya adicionado
+antes de consignar no se listarán en la salida de \hgcmd{status}.  La
+razón para esto es que \hgcmd{status} solamente le muestra aquellos
+ficheros ``interesantes'' ---~los que usted haya modificado o a aquellos
+sobre los que usted haya indicado a Mercurial hacer algo--- de forma
+predeterminada. Si tiene un repositorio que contiene miles de
+ficheros, rara vez deseará saber cuáles de ellos están siendo
+seguidos por Mercurial, pero que no han cambiado.  (De todas maneras,
+puede obtener tal información; más adelante hablaremos de ello.)
+
+
+Cuando usted añade un fichero, Mercurial no hace nada con él inmediatamente.
+En cambio, tomará una instantánea del estado del fichero la próxima vez
+que usted consigne. Continuará haciendo seguimiento a los cambios que
+haga sobre el fichero cada vez que consigne, hasta que usted lo elimine.
+
+\subsection{Nombramiento explícito e implícito de ficheros}
+
+Mercurial tiene un comportamiento útil en el cual si a una orden,
+le pasa el nombre de un directorio, todas las órdenes lo interpretarán como
+``Deseo operar en cada fichero de este directorio y sus 
+subdirectorios''.
+\interaction{daily.files.add-dir}
+Tenga en cuenta que en este ejemplo Mercurial imprimió los nombres de
+los ficheros que se adicionaron, mientras que no lo hizo en el ejemplo
+anterior cuando adicionamos el fichero con nombre \filename{a}.
+
+En el último caso hicimos explícito el nombre del fichero que
+deseábamos adicionar en la línea de órdenes, y Mercurial asume en
+tales casos que usted sabe lo que está haciendo y no imprime
+información alguna.
+
+Cuando hacemos \emph{implícitos} los nombres de los ficheros dando el
+nombre de un directorio, Mercurial efectúa el paso extra de imprimir
+el nombre de cada fichero con el que va a hacer algo.  Esto para
+aclarar lo que está sucediendo, y reducir en lo posible una sorpresa
+silenciosa pero fatal.  Este comportamiento es común a la mayoría de
+órdenes en Mercurial.
+
+\subsection{Nota al margen: Mercurial trata ficheros, no directorios}
+
+Mercurial no da seguimiento a la información de los directorios.  En
+lugar de eso tiene en cuenta las rutas de los ficheros.  Antes  de
+crear un fichero, primero crea todos los directorios que hagan falta
+para completar la ruta del mismo. Después de borrar un fichero,
+borra todos los directorios vacíos que estuvieran en la ruta del
+fichero borrado. Suena como una diferencia trivial, pero tiene una
+consecuencia práctica menor: no es posible representar un directorio
+completamente vacío en Mercurial.
+
+Los directorios vacíos rara vez son útiles, y hay soluciones
+alternativas no intrusivas que usted puede emplear para obtener el efecto
+apropiado. Los desarrolladores de Mercurial pensaron que la
+complejidad necesaria para administrar directorios vacíos no valía la
+pena frente al beneficio limitado que esta característica podría traer.
+
+Si necesita un directorio vacío en su repositorio, hay algunas formas
+de lograrlo. Una es crear un directorio, después hacer \hgcmd{add} a
+un fichero ``oculto'' dentro de ese directorio. En sistemas tipo
+Unix, cualquier fichero cuyo nombre comience con un punto
+(``\texttt{.}'') es tratado como oculto por la mayoría de
+comandos y herramientas GUI. Esta aproximación se ilustra en la figura~\ref{ex:daily:hidden}.
+
+\begin{figure}[ht]
+  \interaction{daily.files.hidden}
+  \caption{Simular un directorio vacío con un fichero oculto}
+  \label{ex:daily:hidden}
+\end{figure}
+
+Otra forma de abordar la necesidad de un directorio vacío es
+simplemente crear uno en sus guiones de construcción antes de que lo
+necesiten.
+
+\section{Cómo dejar de hacer seguimiento a un fichero}
+
+Si decide que un fichero no pertenece a su repositorio, use la orden
+\hgcmd{remove}; se borrará el fichero y le indicará a Mercurial que
+deje de hacerle seguimiento.  Los ficheros eliminados se representan
+con ``\texttt{R}'' al usar \hgcmd{status}.
+\interaction{daily.files.remove}
+
+Después de hacer \hgcmd{remove} a un fichero, Mercurial dejará de
+hacer seguimiento al mismo, incluso si recrea el fichero con el mismo
+nombre en su directorio de trabajo. Si decide recrear un fichero con
+el mismo nombre y desea que Mercurial le haga seguimiento, basta con
+hacerle \hgcmd{add}. Mercurial sabrá que el fichero recientemente
+adicionado no está relacionado con el fichero anterior que tenía el
+mismo nombre.
+
+\subsection{Al eliminar un fichero no se afecta su historial}
+
+Es preciso tener en cuenta que eliminar un fichero tiene sólo dos
+efectos.
+\begin{itemize}
+\item Se elimina la versión actual del fichero del directorio de 
+trabajo.
+\item Mercurial deja de hacer seguimiento a los cambios del fichero
+  desde la próxima consignación.
+\end{itemize}
+Al eliminar un fichero \emph{no} se altera de ninguna manera el
+\emph{historial} del mismo.
+
+Si actualiza su directorio de trabajo a un conjunto de cambios en el
+cual el fichero que eliminó aún era tenido en cuenta, éste reaparecerá en
+el directorio de trabajo, con los contenidos que este tenía cuando se
+consignó tal conjunto de cambios.  Si usted actualiza el directorio de
+trabajo a un conjunto de cambios posterior en el cual el fichero había
+sido eliminado, Mercurial lo eliminará de nuevo del directorio de
+trabajo.
+
+\subsection{Ficheros perdidos}
+
+Mercurial considera como \emph{perdido} un fichero que usted borró,
+pero para el que no se usó \hgcmd{remove}.  Los ficheros perdidos se
+representan con ``\texttt{!}'' al visualizar \hgcmd{status}.
+Las órdenes de Mercurial generalmente no harán nada con los ficheros
+perdidos.
+\interaction{daily.files.missing}
+
+Si su repositorio contiene un fichero que \hgcmd{status} reporta como
+perdido, y desea que el mismo se vaya, se puede usar 
+\hgcmdargs{remove}{\hgopt{remove}{--after}} posteriormente para
+indicarle a Mercurial que usted deseaba borrar tal fichero.
+\interaction{daily.files.remove-after}
+
+Por otro lado, si borró un fichero perdido por accidente, puede usar
+\hgcmdargs{revert}{\emph{nombre de fichero}} para recuperar el
+fichero. Reaparecerá, sin modificaciones.
+\interaction{daily.files.recover-missing}
+
+\subsection{Nota al margen: ¿Por qué decirle explícitamente a Mercurial
+  que elimine un fichero?}
+
+Es posible que se haya preguntado por qué Mercurial exige que usted le
+indique explícitamente que está borrando un fichero. Al principio del
+desarrollo de Mercurial, este permitía que usted borrara el fichero
+sin más; Mercurial se daría cuenta de la ausencia del fichero
+automáticamente después de la ejecución de \hgcmd{commit}, y dejaría de
+hacer seguimiento al fichero.  En la práctica, resultaba muy sencillo
+borrar un fichero accidentalmente sin darse cuenta.
+
+\subsection{Atajo útil---agregar y eliminar ficheros en un solo paso}
+
+Mercurial ofrece una orden combinada, \hgcmd{addremove}, que agrega
+los ficheros que no tienen seguimiento y marca los ficheros faltantes
+como eliminados.
+\interaction{daily.files.addremove}
+La orden \hgcmd{commit} se puede usar con la opción \hgopt{commit}{-A} 
+que aplica el mismo agregar-eliminar, seguido inmediatamente de una
+consignación.
+\interaction{daily.files.commit-addremove}
+
+\section{Copiar ficheros}
+
+Mercurial ofrece la orden \hgcmd{copy} para hacer una copia nueva de
+un fichero.  Cuando se copia un fichero con esta orden, Mercurial
+lleva un registro indicando que el nuevo fichero es una copia del
+fichero original. Los ficheros copiados se tratan de forma especial  cuando
+usted hace una fusión con el trabajo de alguien más.
+
+\subsection{Resultados de copiar un fichero durante una fusión}
+
+Durante una fusión los cambios ``siguen'' una copia.  Para ilustrar
+lo que esto significa, haremos un ejemplo.  Comenzaremos con el mini
+repositorio usual que contiene un solo fichero
+\interaction{daily.copy.init}
+Debemos hacer algo de trabajo en paralelo, de forma que tengamos algo para
+fusionar. Aquí clonamos el repositorio.
+\interaction{daily.copy.clone}
+De vuelta en el repositorio inicial, usemos la orden \hgcmd{copy} para hacer
+una copia del primer fichero que creamos.
+\interaction{daily.copy.copy}
+
+Si vemos la salida de la orden \hgcmd{status}, el fichero copiado luce
+tal como un fichero que se ha añadido normalmente.
+\interaction{daily.copy.status}
+Pero si usamos la opción \hgopt{status}{-C} de la orden
+\hgcmd{status}, se imprimirá otra línea: el fichero \emph{desde} el
+cual fue copiado nuestro fichero recién añadido.
+\interaction{daily.copy.status-copy}
+
+Ahora, en el repositorio que clonamos, hagamos un cambio en
+paralelo. Adicionaremos una línea de contenido al fichero original que
+creamos.
+\interaction{daily.copy.other}
+Hemos modificado el fichero \filename{file} en este
+repositorio. Cuando jalemos los cambios del primer repositorio y
+fusionemos las dos cabezas, Mercurial propagará los cambios que hemos
+hecho localmente en \filename{file} a su copia, \filename{new-file}.
+\interaction{daily.copy.merge}
+
+\subsection{¿Por qué los cambios se reflejan en las copias?}
+\label{sec:daily:why-copy}
+
+Este comportamiento de cambios en ficheros que se propagan a las
+copias de los ficheros parecería esotérico, pero en la mayoría de
+casos es absolutamente deseable.
+Es indispensable recordar que esta propagación \emph{solamente} sucede
+cuando fusionamos.  Por lo tanto si sobre un fichero se usa
+\hgcmd{copy}, y se modifica el fichero original durante el curso
+normal de su trabajo, nada pasará.
+
+Lo segundo a tener en cuenta es que las modificaciones solamente se
+propagarán en las copias únicamente si los repositorios de los cuales
+está jalando los cambios \emph{no saben} de la copia.
+
+Explicaremos a continuación la razón de este comportamiento de
+Mercurial. Digamos que yo he aplicado un arreglo de un fallo importante a un
+fichero fuente y consigné los cambios.  Por otro lado, usted decidió hacer
+\hgcmd{copy} sobre el fichero en su repositorio, sin saber acerca del
+fallo o sin ver el arreglo, y ha comenzado a trabajar sobre su copia
+del fichero.
+
+Si jala y fusiona mis cambios y Mercurial \emph{no hubiera} propagado
+los cambios en las copias, su fichero fuente tendría el fallo, a menos
+que usted haya recordado propagar el arreglo del fallo a mano, el
+mismo \emph{permanecería} en su copia del fichero.
+
+Mercurial previene esta clase de problemas, gracias a la propagación
+automática del cambio que arregló el fallo del fichero original. Hasta
+donde sé, Mercurial es el \emph{único} sistema de control de
+revisiones que propaga los cambios en las copias de esta forma.
+
+Cuando su historial de cambios tiene un registro de la copia y la
+subsecuente fusión, usualmente no es necesario propagar los cambios el
+fichero original a las copias del mismo, y por esta razón Mercurial
+propaga únicamente los cambios en las copias hasta este punto y no más
+allá.
+
+
+\subsection{Cómo hacer que los cambios \emph{no} sigan a la copia?}
+
+Si por algún motivo usted decide que esta característica de
+propagación automática de cambios en las copias no es para usted,
+simplemente use
+la orden usual de su sistema para copiar ficheros (en sistemas tipo
+Unix, es \command{cp}), y posteriormente use \hgcmd{add} sobre la nueva
+copia hecha a mano.  Antes de hacerlo, de todas maneras, relea la
+sección~\ref{sec:daily:why-copy}, y tome una decisión asegurándose que
+este comportamiento no es el apropiado para su caso específico.
+
+\subsection{Comportamiento de la orden \hgcmd{copy}}
+
+Cuando usa la orden \hgcmd{copy}, Mercurial hace una copia de cada
+fichero fuente tal como se encuentra en el directorio actual. Esto
+significa que si usted hace
+modificaciones a un fichero, y le aplica \hgcmd{copy} sin haber
+consignado primero los cambios, la nueva copia contendrá también las
+modificaciones que haya hecho hasta ese punto. (Este comportamiento me
+parece poco intuitivo, y por tal motivo lo menciono.)
+
+La orden \hgcmd{copy} actúa de forma parecida a la orden \command{cp}
+de Unix (puede usar el alias \hgcmd{cp} si le es más cómodo).  El
+último argumento es el \emph{destino}, y todos los argumentos previos
+son las \emph{fuentes}.  Si solamente indica un fichero como la
+fuente, y el destino no existe, se crea un fichero nuevo con ese nombre.
+\interaction{daily.copy.simple}
+Si el destino es un directorio, Mercurial copia las fuentes en éste.
+\interaction{daily.copy.dir-dest}
+La copia de un directorio es recursiva, y preserva la estructura del
+directorio fuente.
+\interaction{daily.copy.dir-src}
+Si tanto la fuente como el destino son directorios, la estructura de
+la fuente se recrea en el directorio destino.
+\interaction{daily.copy.dir-src-dest}
+
+De la misma forma que la orden \hgcmd{rename}, si copia un fichero
+manualmente y desea que Mercurial sepa que ha copiado un fichero,
+basta con aplicar la opción \hgopt{copy}{--after} a la orden 
+\hgcmd{copy}.
+\interaction{daily.copy.after}
+
+\section{Renombrar ficheros}
+
+La necesidad de renombrar un fichero es más común que hacer una copia
+del mismo.  La razón por la cual discutí la orden \hgcmd{copy} antes
+de hablar acerca de cambiar el nombre de los ficheros, es que
+Mercurial trata el renombrar un fichero de la misma forma que una
+copia.  Por lo tanto, saber lo que hace Mercurial cuando usted copia
+un fichero le indica qué esperar cuando renombra un fichero.
+
+Cuando usa la orden \hgcmd{rename}, Mercurial hace una copia de cada
+fichero fuente, lo borra y lo marca como fichero eliminado.
+\interaction{daily.rename.rename}
+La orden \hgcmd{status} muestra la nueva copia del fichero como
+añadida y el fichero inicial de la copia, como eliminado.
+\interaction{daily.rename.status}
+De la misma forma en que se usa la orden \hgcmd{copy}, debemos usar la
+opción \hgopt{status}{-C} de la orden \hgcmd{status} para verificar
+que el fichero añadido realmente comienza a  ser seguido por Mercurial
+como una copia del fichero original, ahora eliminado.
+\interaction{daily.rename.status-copy}
+
+Igual que con \hgcmd{remove} y \hgcmd{copy}, puede indicársele a
+Mercurial acerca de un renombramiento inmediato con la opción
+\hgopt{rename}{--after}.   El comportamiento de la orden
+\hgcmd{rename} y las opciones que acepta, son similares a la orden
+\hgcmd{copy} en casi todo.
+
+\subsection{Renombrar ficheros y fusionar cambios}
+
+Dado que el renombrado de Mercurial se implementa como un
+copiar-y-eliminar, la misma propagación de cambios ocurre cuando usted
+fusiona después de renombrar como después de hacer una copia.
+
+Si yo modifico un fichero y usted lo renombra a un nuevo fichero, y
+posteriormente fusionamos nuestros respectivos cambios, mi
+modificación al fichero bajo su nombre original se propagará en el
+fichero con el nuevo nombre. (Es lo que se esperaría que ``simplemente
+funcione,''
+pero, no todos los sistemas de control de revisiones hacen esto.)
+
+Aunque el hecho de que los cambios sigan la copia es una característica
+respecto a la cual usted puede estar de acuerdo y decir ``si, puede
+ser útil,'' debería ser claro
+que el seguimiento de cambios de un renombramiento es definitivamente
+importante.  Sin esto, sería muy sencillo que los cambios se
+quedaran atrás cuando los ficheros se renombran.
+
+\subsection{Cambios de nombre divergentes y fusión}
+
+El caso de renombramiento con nombres divergentes ocurre cuando dos
+desarrolladores comienzan  con un fichero---llamémoslo
+\filename{foo}---en sus repositorios respectivos.
+
+\interaction{rename.divergent.clone}
+%TODO we must either change the example's names, and these names, or
+%use the original names. as of now, we keep the old names
+Anne renombra el fichero a \filename{bar}.
+\interaction{rename.divergent.rename.anne}
+Mientras que Bob lo renombra como \filename{quux}.
+\interaction{rename.divergent.rename.bob}
+
+Veo esto como un conflicto porque cada desarrollador ha expresado
+intenciones diferentes acerca de cómo considera debería haberse
+nombrado el fichero.
+
+¿Qué cree que debería pasar cuando fusionen su trabajo?
+El comportamiento de Mercurial es que siempre preserva \emph{ambos}
+nombres cuando fusiona  los conjuntos de cambios que contienen nombres
+divergentes.
+%TODO traducir texto interaccion
+\interaction{rename.divergent.merge}
+
+Tenga en cuenta que Mercurial le advierte acerca de nombres
+divergentes, pero deja que usted decida qué hacer con la divergencia
+después de la fusión.
+
+\subsection{Cambios de nombre convergentes y fusión}
+
+Otra clase de conflicto al cambiar el nombre de ficheros ocurre cuando dos
+personas eligen renombrar diferentes ficheros \emph{fuente} al mismo
+\emph{destino}. En este caso Mercurial aplica su maquinaria de fusión
+usual, y le permite a usted guiar la situación a una resolución adecuada.
+
+\subsection{Otros casos límite relacionados con renombramientos}
+
+Mercurial tiene un fallo de mucho tiempo en el cual no es capaz de
+fusionar cuando por un lado hay un fichero con un nombre dado,
+mientras que en otro hay un directorio con el mismo nombre. Esto está
+documentado como~\bug{29}.
+\interaction{issue29.go}
+
+\section{Recuperarse de equivocaciones}
+
+Mercurial tiene unas órdenes poderosas que le ayudarán a recuperarse
+de equivocaciones comunes.
+
+La orden \hgcmd{revert} le permite deshacer cambios que haya hecho a
+su directorio de trabajo. Por ejemplo, si aplicó \hgcmd{add} a un
+fichero por accidente, ejecute \hgcmd{revert} con el nombre del
+fichero que añadió, y en tanto que el fichero no haya sido tocado de
+forma alguna, no será adicionado, ni seguido por Mercurial.  También
+puede usar \hgcmd{revert} para deshacerse de cambios erróneos a un
+fichero.
+
+Tenga en cuenta que la orden \hgcmd{revert} se usa para cambios que no
+han sido consignados. Cuando haya consignado un cambio, si decide que
+era un error, puede hacer algo todavía, pero sus opciones pueden estar
+más limitadas.
+
+Para obtener información acerca de la orden \hgcmd{revert} y detalles
+de cómo tratar con cambios consignados, vea el capítulo~\ref{chap:undo}.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/backout	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+# We have to fake the merges here, because they cause conflicts with
+# three-way command-line merge, and kdiff3 may not be available.
+
+export HGMERGE=$(mktemp)
+echo '#!/bin/sh' >> $HGMERGE
+echo 'echo first change > "$1"' >> $HGMERGE
+echo 'echo third change >> "$1"' >> $HGMERGE
+chmod 700 $HGMERGE
+
+#$ name: init
+
+hg init myrepo
+cd myrepo
+echo first change >> myfile
+hg add myfile
+hg commit -m 'first change'
+echo second change >> myfile
+hg commit -m 'second change'
+
+#$ name: simple
+
+hg backout -m 'back out second change' tip
+cat myfile
+
+#$ name: simple.log
+#$ ignore: \s+200[78]-.*
+
+hg log --style compact
+
+#$ name: non-tip.clone
+
+cd ..
+hg clone -r1 myrepo non-tip-repo
+cd non-tip-repo
+
+#$ name: non-tip.backout
+
+echo third change >> myfile
+hg commit -m 'third change'
+hg backout --merge -m 'back out second change' 1
+
+#$ name: non-tip.cat
+cat myfile
+
+#$ name: manual.clone
+
+cd ..
+hg clone -r1 myrepo newrepo
+cd newrepo
+
+#$ name: manual.backout
+
+echo third change >> myfile
+hg commit -m 'third change'
+hg backout -m 'back out second change' 1
+
+#$ name: manual.log
+
+hg log --style compact
+
+#$ name: manual.parents
+
+hg parents
+
+#$ name: manual.heads
+
+hg heads
+
+#$ name: manual.cat
+
+cat myfile
+
+#$ name: manual.merge
+
+hg merge
+hg commit -m 'merged backout with previous tip'
+cat myfile
+
+#$ name:
+
+rm $HGMERGE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/bisect	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+if  hg -v | head -1 | grep -e "version 0.*"
+then
+#On mercurial 1.0 and later bisect is a builtin
+echo '[extensions]' >> $HGRC
+echo 'hbisect =' >> $HGRC
+fi
+
+# XXX There's some kind of horrible nondeterminism in the execution of
+# bisect at the moment.  Ugh.
+
+#$ ignore: .*
+
+#$ name: init
+
+hg init mybug
+cd mybug
+
+#$ name: commits
+
+buggy_change=22
+
+for (( i = 0; i < 35; i++ )); do
+  if [[ $i = $buggy_change ]]; then
+    echo 'i have a gub' > myfile$i
+    hg commit -q -A -m 'buggy changeset'
+  else
+    echo 'nothing to see here, move along' > myfile$i
+    hg commit -q -A -m 'normal changeset'
+  fi
+done
+
+#$ name: help
+
+hg help bisect
+
+#$ name: search.init
+
+if  hg -v | head -1 | grep -e "version 0.*"
+then
+#On mercurial 1.0 --init disappeared
+hg bisect --init
+fi
+
+#$ name: search.bad-init
+
+hg bisect --bad
+
+#$ name: search.good-init
+
+hg bisect --good 10
+
+#$ name: search.step1
+
+if grep -q 'i have a gub' *
+then
+  result=bad
+else
+  result=good
+fi
+
+echo this revision is $result
+hg bisect --$result
+
+#$ name: search.mytest
+
+mytest() {
+  if grep -q 'i have a gub' *
+  then
+    result=bad
+  else
+    result=good
+  fi
+
+  echo this revision is $result
+  hg bisect --$result
+}
+  
+#$ name: search.step2
+
+mytest
+
+#$ name: search.rest
+
+mytest
+mytest
+mytest
+
+#$ name: search.reset
+
+hg bisect --reset
+
+#$ name:
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/branch-named	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+hg init a
+cd a
+echo hello > myfile
+hg commit -A -m 'Initial commit'
+
+#$ name: branches
+
+hg tip
+hg branches
+
+#$ name: branch
+
+hg branch
+
+#$ name: create
+
+hg branch foo
+hg branch
+
+#$ name: status
+
+hg status
+hg tip
+
+#$ name: commit
+
+echo 'hello again' >> myfile
+hg commit -m 'Second commit'
+hg tip
+
+#$ name: rebranch
+
+hg branch
+hg branch bar
+echo new file > newfile
+hg commit -A -m 'Third commit'
+hg tip
+
+#$ name: parents
+
+hg parents
+hg branches
+
+#$ name: update-switchy
+
+hg update foo
+hg parents
+hg update bar
+hg parents
+
+#$ name: update-nothing
+
+hg update foo
+hg update
+
+#$ name: foo-commit
+
+echo something > somefile
+hg commit -A -m 'New file'
+hg heads
+
+#$ name: update-bar
+
+hg update bar
+
+#$ name: merge
+
+hg branch
+hg merge foo
+hg commit -m 'Merge'
+hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/branch-repo	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+hg init myproject
+cd myproject
+echo hello > myfile
+hg commit -A -m 'Initial commit'
+cd ..
+
+#$ name: tag
+
+cd myproject
+hg tag v1.0
+
+#$ name: clone
+
+cd ..
+hg clone myproject myproject-1.0.1
+
+#$ name: bugfix
+
+hg clone myproject-1.0.1 my-1.0.1-bugfix
+cd my-1.0.1-bugfix
+echo 'I fixed a bug using only echo!' >> myfile
+hg commit -m 'Important fix for 1.0.1'
+#$ ignore: /tmp/branch-repo.*
+hg push
+
+#$ name: new
+
+cd ..
+hg clone myproject my-feature
+cd my-feature
+echo 'This sure is an exciting new feature!' > mynewfile
+hg commit -A -m 'New feature'
+hg push
+
+#$ name: pull
+
+cd ..
+hg clone myproject myproject-merge
+cd myproject-merge
+hg pull ../myproject-1.0.1
+
+#$ name: merge
+
+hg merge
+hg commit -m 'Merge bugfix from 1.0.1 branch'
+hg push
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/branching	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+#$ name: init
+
+hg init main
+cd main
+echo 'This is a boring feature.' > myfile
+hg commit -A -m 'We have reached an important milestone!'
+
+#$ name: tag
+
+hg tag v1.0
+hg tip
+hg tags
+
+#$ name: main
+
+cd ../main
+echo 'This is exciting and new!' >> myfile
+hg commit -m 'Add a new feature'
+cat myfile
+
+#$ name: update
+
+cd ..
+hg clone -U main main-old
+cd main-old
+hg update v1.0
+cat myfile
+
+#$ name: clone
+
+cd ..
+hg clone -rv1.0 main stable
+
+#$ name: stable
+
+hg clone stable stable-fix
+cd stable-fix
+echo 'This is a fix to a boring feature.' > myfile
+hg commit -m 'Fix a bug'
+#$ ignore: /tmp/branching.*
+hg push
+
+#$ name:
+
+export HGMERGE=$(mktemp)
+echo '#!/bin/sh' > $HGMERGE
+echo 'echo "This is a fix to a boring feature." > "$1"' >> $HGMERGE
+echo 'echo "This is exciting and new!" >> "$1"' >> $HGMERGE
+chmod 700 $HGMERGE
+
+#$ name: merge
+
+cd ../main
+hg pull ../stable
+hg merge
+hg commit -m 'Bring in bugfix from stable branch'
+cat myfile
+
+#$ name:
+
+rm $HGMERGE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/cmdref	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+hg init diff
+cd diff
+cat > myfile.c <<EOF
+int myfunc()
+{
+    return 1;
+}
+EOF
+hg ci -Ama
+
+sed -ie 's/return 1/return 10/' myfile.c
+
+#$ name: diff-p
+
+echo '[diff]' >> $HGRC
+echo 'showfunc = False' >> $HGRC
+
+hg diff
+
+hg diff -p
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/daily.copy	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+#$ name: init
+
+hg init my-copy
+cd my-copy
+echo line > file
+hg add file
+hg commit -m 'Added a file'
+
+#$ name: clone
+
+cd ..
+hg clone my-copy your-copy
+
+#$ name: copy
+
+cd my-copy
+hg copy file new-file
+
+#$ name: status
+
+hg status
+
+#$ name: status-copy
+
+hg status -C
+hg commit -m 'Copied file'
+
+#$ name: other
+
+cd ../your-copy
+echo 'new contents' >> file
+hg commit -m 'Changed file'
+
+#$ name: cat
+
+cat file
+cat ../my-copy/new-file
+
+#$ name: merge
+
+hg pull ../my-copy
+hg merge
+cat new-file
+
+#$ name:
+
+cd ..
+hg init copy-example
+cd copy-example
+echo a > a
+echo b > b
+mkdir c
+mkdir c/a
+echo c > c/a/c
+hg ci -Ama
+
+#$ name: simple
+
+mkdir k
+hg copy a k
+ls k
+
+#$ name: dir-dest
+
+mkdir d
+hg copy a b d
+ls d
+
+#$ name: dir-src
+
+hg copy c e
+
+#$ name: dir-src-dest
+
+hg copy c d
+
+#$ name: after
+
+cp a z
+hg copy --after a z
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/daily.files	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+#$ name: add
+
+hg init add-example
+cd add-example
+echo a > a
+hg status
+hg add a
+hg status
+hg commit -m 'Added one file'
+hg status
+
+#$ name: add-dir
+
+mkdir b
+echo b > b/b
+echo c > b/c
+mkdir b/d
+echo d > b/d/d
+hg add b
+hg commit -m 'Added all files in subdirectory'
+
+#$ name:
+
+cd ..
+
+#$ name: hidden
+
+hg init hidden-example
+cd hidden-example
+mkdir empty
+touch empty/.hidden
+hg add empty/.hidden
+hg commit -m 'Manage an empty-looking directory'
+ls empty
+cd ..
+hg clone hidden-example tmp
+ls tmp
+ls tmp/empty
+
+#$ name: remove
+
+hg init remove-example
+cd remove-example
+echo a > a
+mkdir b
+echo b > b/b
+hg add a b
+hg commit -m 'Small example for file removal'
+hg remove a
+hg status
+hg remove b
+
+#$ name:
+
+cd ..
+
+#$ name: missing
+hg init missing-example
+cd missing-example
+echo a > a
+hg add a
+hg commit -m 'File about to be missing'
+rm a
+hg status
+
+#$ name: remove-after
+
+hg remove --after a
+hg status
+
+#$ name: recover-missing
+hg revert a
+cat a
+hg status
+
+#$ name:
+
+cd ..
+
+#$ name: addremove
+
+hg init addremove-example
+cd addremove-example
+echo a > a
+echo b > b
+hg addremove
+
+#$ name: commit-addremove
+
+echo c > c
+hg commit -A -m 'Commit with addremove'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/daily.rename	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+hg init a
+cd a
+echo a > a
+hg ci -Ama
+
+#$ name: rename
+
+hg rename a b
+
+#$ name: status
+
+hg status
+
+#$ name: status-copy
+
+hg status -C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/daily.revert	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+hg init a
+cd a
+echo 'original content' > file
+hg ci -Ama
+
+#$ name: modify
+
+cat file
+echo unwanted change >> file
+hg diff file
+
+#$ name: unmodify
+
+hg status
+hg revert file
+cat file
+
+#$ name: status
+
+hg status
+cat file.orig
+
+#$ name:
+
+rm file.orig
+
+#$ name: add
+
+echo oops > oops
+hg add oops
+hg status oops
+hg revert oops
+hg status
+
+#$ name:
+
+rm oops
+
+#$ name: remove
+
+hg remove file
+hg status
+hg revert file
+hg status
+ls file
+
+#$ name: missing
+
+rm file
+hg status
+hg revert file
+ls file
+
+#$ name: copy
+
+hg copy file new-file
+hg revert new-file
+hg status
+
+#$ name:
+
+rm new-file
+
+#$ name: rename
+
+hg rename file new-file
+hg revert new-file
+hg status
+
+#$ name: rename-orig
+hg revert file
+hg status
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/data/check_whitespace.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+import re
+
+def trailing_whitespace(difflines):
+    added, linenum, header = [], 0, False
+
+    for line in difflines:
+        if header:
+            # remember the name of the file that this diff affects
+            m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)
+            if m and m.group(1) != '/dev/null':
+                filename = m.group(1).split('/', 1)[-1]
+            if line.startswith('+++ '):
+                header = False
+            continue
+        if line.startswith('diff '):
+            header = True
+            continue
+        # hunk header - save the line number
+        m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)
+        if m:
+            linenum = int(m.group(1))
+            continue
+        # hunk body - check for an added line with trailing whitespace
+        m = re.match(r'\+.*\s$', line)
+        if m:
+            added.append((filename, linenum))
+        if line and line[0] in ' +':
+            linenum += 1
+    return added
+
+if __name__ == '__main__':
+    import os, sys
+    
+    added = trailing_whitespace(os.popen('hg export tip'))
+    if added:
+        for filename, linenum in added:
+            print >> sys.stderr, ('%s, line %d: trailing whitespace added' %
+                                  (filename, linenum))
+        # save the commit message so we don't need to retype it
+        os.system('hg tip --template "{desc}" > .hg/commit.save')
+        print >> sys.stderr, 'commit message saved to .hg/commit.save'
+        sys.exit(1)
Binary file es/examples/data/netplug-1.2.5.tar.bz2 has changed
Binary file es/examples/data/netplug-1.2.8.tar.bz2 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/data/remove-redundant-null-checks.patch	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,190 @@
+
+From: Jesper Juhl <jesper.juhl@gmail.com>
+
+Remove redundant NULL chck before kfree + tiny CodingStyle cleanup for
+drivers/
+
+Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+---
+
+ drivers/char/agp/sgi-agp.c        |    5 ++---
+ drivers/char/hvcs.c               |   11 +++++------
+ drivers/message/fusion/mptfc.c    |    6 ++----
+ drivers/message/fusion/mptsas.c   |    3 +--
+ drivers/net/fs_enet/fs_enet-mii.c |    3 +--
+ drivers/net/wireless/ipw2200.c    |   22 ++++++----------------
+ drivers/scsi/libata-scsi.c        |    4 +---
+ drivers/video/au1100fb.c          |    3 +--
+ 8 files changed, 19 insertions(+), 38 deletions(-)
+
+diff -puN drivers/char/agp/sgi-agp.c~remove-redundant-null-checks-before-free-in-drivers drivers/char/agp/sgi-agp.c
+--- a/drivers/char/agp/sgi-agp.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/char/agp/sgi-agp.c
+@@ -329,9 +329,8 @@ static int __devinit agp_sgi_init(void)
+ 
+ static void __devexit agp_sgi_cleanup(void)
+ {
+-	if (sgi_tioca_agp_bridges)
+-		kfree(sgi_tioca_agp_bridges);
+-	sgi_tioca_agp_bridges=NULL;
++	kfree(sgi_tioca_agp_bridges);
++	sgi_tioca_agp_bridges = NULL;
+ }
+ 
+ module_init(agp_sgi_init);
+diff -puN drivers/char/hvcs.c~remove-redundant-null-checks-before-free-in-drivers drivers/char/hvcs.c
+--- a/drivers/char/hvcs.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/char/hvcs.c
+@@ -1320,11 +1320,12 @@ static struct tty_operations hvcs_ops = 
+ static int hvcs_alloc_index_list(int n)
+ {
+ 	int i;
++
+ 	hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL);
+ 	if (!hvcs_index_list)
+ 		return -ENOMEM;
+ 	hvcs_index_count = n;
+-	for(i = 0; i < hvcs_index_count; i++)
++	for (i = 0; i < hvcs_index_count; i++)
+ 		hvcs_index_list[i] = -1;
+ 	return 0;
+ }
+@@ -1332,11 +1333,9 @@ static int hvcs_alloc_index_list(int n)
+ static void hvcs_free_index_list(void)
+ {
+ 	/* Paranoia check to be thorough. */
+-	if (hvcs_index_list) {
+-		kfree(hvcs_index_list);
+-		hvcs_index_list = NULL;
+-		hvcs_index_count = 0;
+-	}
++	kfree(hvcs_index_list);
++	hvcs_index_list = NULL;
++	hvcs_index_count = 0;
+ }
+ 
+ static int __init hvcs_module_init(void)
+diff -puN drivers/message/fusion/mptfc.c~remove-redundant-null-checks-before-free-in-drivers drivers/message/fusion/mptfc.c
+--- a/drivers/message/fusion/mptfc.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/message/fusion/mptfc.c
+@@ -305,10 +305,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, in
+ 	}
+ 
+  out:
+-	if (pp0_array)
+-		kfree(pp0_array);
+-	if (p0_array)
+-		kfree(p0_array);
++	kfree(pp0_array);
++	kfree(p0_array);
+ 	return rc;
+ }
+ 
+diff -puN drivers/message/fusion/mptsas.c~remove-redundant-null-checks-before-free-in-drivers drivers/message/fusion/mptsas.c
+--- a/drivers/message/fusion/mptsas.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/message/fusion/mptsas.c
+@@ -1378,8 +1378,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
+ 	return 0;
+ 
+  out_free_port_info:
+-	if (hba)
+-		kfree(hba);
++	kfree(hba);
+  out:
+ 	return error;
+ }
+diff -puN drivers/net/fs_enet/fs_enet-mii.c~remove-redundant-null-checks-before-free-in-drivers drivers/net/fs_enet/fs_enet-mii.c
+--- a/drivers/net/fs_enet/fs_enet-mii.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/net/fs_enet/fs_enet-mii.c
+@@ -431,8 +431,7 @@ static struct fs_enet_mii_bus *create_bu
+ 	return bus;
+ 
+ err:
+-	if (bus)
+-		kfree(bus);
++	kfree(bus);
+ 	return ERR_PTR(ret);
+ }
+ 
+diff -puN drivers/net/wireless/ipw2200.c~remove-redundant-null-checks-before-free-in-drivers drivers/net/wireless/ipw2200.c
+--- a/drivers/net/wireless/ipw2200.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/net/wireless/ipw2200.c
+@@ -1229,12 +1229,6 @@ static struct ipw_fw_error *ipw_alloc_er
+ 	return error;
+ }
+ 
+-static void ipw_free_error_log(struct ipw_fw_error *error)
+-{
+-	if (error)
+-		kfree(error);
+-}
+-
+ static ssize_t show_event_log(struct device *d,
+ 			      struct device_attribute *attr, char *buf)
+ {
+@@ -1296,10 +1290,9 @@ static ssize_t clear_error(struct device
+ 			   const char *buf, size_t count)
+ {
+ 	struct ipw_priv *priv = dev_get_drvdata(d);
+-	if (priv->error) {
+-		ipw_free_error_log(priv->error);
+-		priv->error = NULL;
+-	}
++
++	kfree(priv->error);
++	priv->error = NULL;
+ 	return count;
+ }
+ 
+@@ -1970,8 +1963,7 @@ static void ipw_irq_tasklet(struct ipw_p
+ 				struct ipw_fw_error *error =
+ 				    ipw_alloc_error_log(priv);
+ 				ipw_dump_error_log(priv, error);
+-				if (error)
+-					ipw_free_error_log(error);
++				kfree(error);
+ 			}
+ #endif
+ 		} else {
+@@ -11693,10 +11685,8 @@ static void ipw_pci_remove(struct pci_de
+ 		}
+ 	}
+ 
+-	if (priv->error) {
+-		ipw_free_error_log(priv->error);
+-		priv->error = NULL;
+-	}
++	kfree(priv->error);
++	priv->error = NULL;
+ 
+ #ifdef CONFIG_IPW2200_PROMISCUOUS
+ 	ipw_prom_free(priv);
+diff -puN drivers/scsi/libata-scsi.c~remove-redundant-null-checks-before-free-in-drivers drivers/scsi/libata-scsi.c
+--- a/drivers/scsi/libata-scsi.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/scsi/libata-scsi.c
+@@ -222,9 +222,7 @@ int ata_cmd_ioctl(struct scsi_device *sc
+ 	 && copy_to_user(arg + sizeof(args), argbuf, argsize))
+ 		rc = -EFAULT;
+ error:
+-	if (argbuf)
+-		kfree(argbuf);
+-
++	kfree(argbuf);
+ 	return rc;
+ }
+ 
+diff -puN drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers drivers/video/au1100fb.c
+--- a/drivers/video/au1100fb.c~remove-redundant-null-checks-before-free-in-drivers
++++ a/drivers/video/au1100fb.c
+@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void)
+ {
+ 	driver_unregister(&au1100fb_driver);
+ 
+-	if (drv_info.opt_mode)
+-		kfree(drv_info.opt_mode);
++	kfree(drv_info.opt_mode);
+ }
+ 
+ module_init(au1100fb_init);
+_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/extdiff	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+echo '[extensions]' >> $HGRC
+echo 'extdiff =' >> $HGRC
+
+hg init a
+cd a
+echo 'The first line.' > myfile
+hg ci -Ama
+echo 'The second line.' >> myfile
+
+#$ name: diff
+
+hg diff
+
+#$ name: extdiff
+
+hg extdiff
+
+#$ name: extdiff-ctx
+
+#$ ignore: ^\*\*\* a.*
+
+hg extdiff -o -NprcC5
+
+#$ name:
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/filenames	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+hg init a
+cd a
+mkdir -p examples src/watcher
+touch COPYING MANIFEST.in README setup.py
+touch examples/performant.py examples/simple.py
+touch src/main.py src/watcher/_watcher.c src/watcher/watcher.py src/xyzzy.txt
+
+#$ name: files
+
+hg add COPYING README examples/simple.py
+
+#$ name: dirs
+
+hg status src
+
+#$ name: wdir-subdir
+
+cd src
+hg add -n
+hg add -n .
+
+#$ name: wdir-relname
+
+hg status
+hg status `hg root`
+
+#$ name: glob.star
+
+hg add 'glob:*.py'
+
+#$ name: glob.starstar
+
+cd ..
+hg status 'glob:**.py'
+
+#$ name: glob.star-starstar
+
+hg status 'glob:*.py'
+hg status 'glob:**.py'
+
+#$ name: glob.question
+
+hg status 'glob:**.?'
+
+#$ name: glob.range
+
+hg status 'glob:**[nr-t]'
+
+#$ name: glob.group
+
+hg status 'glob:*.{in,py}'
+
+#$ name: filter.include
+
+hg status -I '*.in'
+
+#$ name: filter.exclude
+
+hg status -X '**.py' src
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/hook.msglen	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+hg init a
+cd a
+echo '[hooks]' > .hg/hgrc
+echo 'pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10' >> .hg/hgrc
+
+#$ name: go
+
+cat .hg/hgrc
+echo a > a
+hg add a
+hg commit -A -m 'too short'
+hg commit -A -m 'long enough'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/hook.simple	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+#$ name: init
+
+hg init hook-test
+cd hook-test
+echo '[hooks]' >> .hg/hgrc
+echo 'commit = echo committed $HG_NODE' >> .hg/hgrc
+cat .hg/hgrc
+echo a > a
+hg add a
+hg commit -m 'testing commit hook'
+
+#$ name: ext
+#$ ignore: ^date of commit.*
+
+echo 'commit.when = echo -n "date of commit: "; date' >> .hg/hgrc
+echo a >> a
+hg commit -m 'i have two hooks'
+
+#$ name:
+
+echo '#!/bin/sh' >> check_bug_id
+echo '# check that a commit comment mentions a numeric bug id' >> check_bug_id
+echo 'hg log -r $1 --template {desc} | grep -q "\<bug *[0-9]"' >> check_bug_id
+chmod +x check_bug_id
+
+#$ name: pretxncommit
+
+cat check_bug_id
+
+echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' >> .hg/hgrc
+
+echo a >> a
+hg commit -m 'i am not mentioning a bug id'
+
+hg commit -m 'i refer you to bug 666'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/hook.ws	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+hg init a
+cd a
+echo '[hooks]' > .hg/hgrc
+echo "pretxncommit.whitespace = hg export tip | (! egrep -q '^\\+.*[ \\t]$')" >> .hg/hgrc
+
+#$ name: simple
+
+cat .hg/hgrc
+echo 'a ' > a
+hg commit -A -m 'test with trailing whitespace'
+echo 'a' > a
+hg commit -A -m 'drop trailing whitespace and try again'
+
+#$ name:
+
+echo '[hooks]' > .hg/hgrc
+echo "pretxncommit.whitespace = .hg/check_whitespace.py" >> .hg/hgrc
+cp $EXAMPLE_DIR/data/check_whitespace.py .hg
+
+#$ name: better
+
+cat .hg/hgrc
+echo 'a ' >> a
+hg commit -A -m 'add new line with trailing whitespace'
+sed -i 's, *$,,' a
+hg commit -A -m 'trimmed trailing whitespace'
+
+#$ name:
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/issue29	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+#$ name: go
+
+hg init issue29
+cd issue29
+echo a > a
+hg ci -Ama
+echo b > b
+hg ci -Amb
+hg up 0
+mkdir b
+echo b > b/b
+hg ci -Amc
+
+#$ ignore: abort: Is a directory: .*
+hg merge
+
+#$ name:
+# This error is expected from the failed merge.
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.dodiff	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+#$ name: diff
+
+echo 'this is my original thought' > oldfile
+echo 'i have changed my mind' > newfile
+
+diff -u oldfile newfile > tiny.patch
+
+cat tiny.patch
+
+patch < tiny.patch
+
+cat oldfile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.guards	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+
+hg init a
+cd a
+
+#$ name: init
+
+hg qinit
+hg qnew hello.patch
+echo hello > hello
+hg add hello
+hg qrefresh
+hg qnew goodbye.patch
+echo goodbye > goodbye
+hg add goodbye
+hg qrefresh
+
+#$ name: qguard
+
+hg qguard
+
+#$ name: qguard.pos
+
+hg qguard +foo
+hg qguard
+
+#$ name: qguard.neg
+
+hg qguard hello.patch -quux
+hg qguard hello.patch
+
+#$ name: series
+
+cat .hg/patches/series
+
+#$ name: qselect.foo
+
+hg qpop -a
+hg qselect
+hg qselect foo
+hg qselect
+
+#$ name: qselect.cat
+
+cat .hg/patches/guards
+
+#$ name: qselect.qpush
+hg qpush -a
+
+#$ name: qselect.error
+
+hg qselect +foo
+
+#$ name: qselect.quux
+
+hg qselect quux
+hg qpop -a
+hg qpush -a
+
+#$ name: qselect.foobar
+
+hg qselect foo bar
+hg qpop -a
+hg qpush -a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.id	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+
+hg init a
+cd a
+hg qinit
+echo 'int x;' > test.c
+hg ci -Ama
+
+hg qnew first.patch
+echo 'float c;' >> test.c
+hg qrefresh
+
+hg qnew second.patch
+echo 'double u;' > other.c
+hg add other.c
+hg qrefresh
+
+#$ name: output
+
+hg qapplied
+hg log -r qbase:qtip
+hg export second.patch
+
+#$ name:
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.qinit-help	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+
+#$ name: help
+hg help qinit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.tarball	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+cp $EXAMPLE_DIR/data/netplug-*.tar.bz2 .
+ln -s /bin/true download
+export PATH=`pwd`:$PATH
+
+#$ name: download
+
+download netplug-1.2.5.tar.bz2
+tar jxf netplug-1.2.5.tar.bz2
+cd netplug-1.2.5
+hg init
+hg commit -q --addremove --message netplug-1.2.5
+cd ..
+hg clone netplug-1.2.5 netplug
+
+#$ name:
+
+cd netplug
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+cd ..
+
+#$ name: qinit
+
+cd netplug
+hg qinit
+hg qnew -m 'fix build problem with gcc 4' build-fix.patch
+perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c
+hg qrefresh
+hg tip -p
+
+#$ name: newsource
+
+hg qpop -a
+cd ..
+download netplug-1.2.8.tar.bz2
+hg clone netplug-1.2.5 netplug-1.2.8
+cd netplug-1.2.8
+hg locate -0 | xargs -0 rm
+cd ..
+tar jxf netplug-1.2.8.tar.bz2
+cd netplug-1.2.8
+hg commit --addremove --message netplug-1.2.8
+
+#$ name: repush
+
+cd ../netplug
+hg pull ../netplug-1.2.8
+hg qpush -a
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.tools	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+cp $EXAMPLE_DIR/data/remove-redundant-null-checks.patch .
+
+#$ name: tools
+diffstat -p1 remove-redundant-null-checks.patch
+
+filterdiff -i '*/video/*' remove-redundant-null-checks.patch
+
+#$ name: lsdiff
+lsdiff -nvv remove-redundant-null-checks.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/mq.tutorial	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+echo '[extensions]' >> $HGRC
+echo 'hgext.mq =' >> $HGRC
+
+#$ name: qinit
+
+hg init mq-sandbox
+cd mq-sandbox
+echo 'line 1' > file1
+echo 'another line 1' > file2
+hg add file1 file2
+hg commit -m'first change'
+
+hg qinit
+
+#$ name: qnew
+
+hg tip
+hg qnew first.patch
+hg tip
+ls .hg/patches
+
+#$ name: qrefresh
+#$ ignore: \s+200[78]-.*
+
+echo 'line 2' >> file1
+hg diff
+hg qrefresh
+hg diff
+hg tip --style=compact --patch
+
+#$ name: qrefresh2
+
+echo 'line 3' >> file1
+hg status
+hg qrefresh
+hg tip --style=compact --patch
+
+#$ name: qnew2
+
+hg qnew second.patch
+hg log --style=compact --limit=2
+echo 'line 4' >> file1
+hg qrefresh
+hg tip --style=compact --patch
+hg annotate file1
+
+#$ name: qseries
+
+hg qseries
+hg qapplied
+
+#$ name: qpop
+
+hg qapplied
+hg qpop
+hg qseries
+hg qapplied
+cat file1
+
+#$ name: qpush-a
+
+hg qpush -a
+cat file1
+
+#$ name: add
+
+echo 'file 3, line 1' >> file3
+hg qnew add-file3.patch
+hg qnew -f add-file3.patch
+
+#$ name:
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/rename.divergent	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+hg init orig
+cd orig
+echo foo > foo
+hg ci -A -m 'First commit'
+cd ..
+
+#$ name: clone
+
+hg clone orig anne
+hg clone orig bob
+
+#$ name: rename.anne
+
+cd anne
+hg mv foo bar
+hg ci -m 'Rename foo to bar'
+
+#$ name: rename.bob
+
+cd ../bob
+hg mv foo quux
+hg ci -m 'Rename foo to quux'
+
+#$ name: merge
+# See http://www.selenic.com/mercurial/bts/issue455
+
+cd ../orig
+hg pull -u ../anne
+hg pull ../bob
+hg merge
+ls
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/rollback	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+hg init a
+cd a
+echo a > a
+hg ci -A -m 'First commit'
+
+echo a >> a
+
+#$ name: tip
+
+#$ name: commit
+
+hg status
+echo b > b
+hg commit -m 'Add file b'
+
+#$ name: status
+
+hg status
+hg tip
+
+#$ name: rollback
+
+hg rollback
+hg tip
+hg status
+
+#$ name: add
+
+hg add b
+hg commit -m 'Add file b, this time for real'
+
+#$ name: twice
+
+hg rollback
+hg rollback
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/run-example	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,391 @@
+#!/usr/bin/env python
+#
+# This program takes something that resembles a shell script and runs
+# it, spitting input (commands from the script) and output into text
+# files, for use in examples.
+
+import cStringIO
+import errno
+import getopt
+import os
+import pty
+import re
+import select
+import shutil
+import signal
+import stat
+import sys
+import tempfile
+import time
+
+tex_subs = {
+    '\\': '\\textbackslash{}',
+    '{': '\\{',
+    '}': '\\}',
+    }
+
+def gensubs(s):
+    start = 0
+    for i, c in enumerate(s):
+        sub = tex_subs.get(c)
+        if sub:
+            yield s[start:i]
+            start = i + 1
+            yield sub
+    yield s[start:]
+
+def tex_escape(s):
+    return ''.join(gensubs(s))
+        
+def maybe_unlink(name):
+    try:
+        os.unlink(name)
+        return True
+    except OSError, err:
+        if err.errno != errno.ENOENT:
+            raise
+    return False
+
+def find_path_to(program):
+    for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
+        name = os.path.join(p, program)
+        if os.access(name, os.X_OK):
+            return p
+    return None
+        
+class example:
+    shell = '/usr/bin/env bash'
+    ps1 = '__run_example_ps1__ '
+    ps2 = '__run_example_ps2__ '
+    pi_re = re.compile(r'#\$\s*(name|ignore):\s*(.*)$')
+    
+    timeout = 10
+
+    def __init__(self, name, verbose):
+        self.name = name
+        self.verbose = verbose
+        self.poll = select.poll()
+
+    def parse(self):
+        '''yield each hunk of input from the file.'''
+        fp = open(self.name)
+        cfp = cStringIO.StringIO()
+        for line in fp:
+            cfp.write(line)
+            if not line.rstrip().endswith('\\'):
+                yield cfp.getvalue()
+                cfp.seek(0)
+                cfp.truncate()
+        
+    def status(self, s):
+        sys.stdout.write(s)
+        if not s.endswith('\n'):
+            sys.stdout.flush()
+
+    def send(self, s):
+        if self.verbose:
+            print >> sys.stderr, '>', self.debugrepr(s)
+        while s:
+            count = os.write(self.cfd, s)
+            s = s[count:]
+
+    def debugrepr(self, s):
+        rs = repr(s)
+        limit = 60
+        if len(rs) > limit:
+            return ('%s%s ... [%d bytes]' % (rs[:limit], rs[0], len(s)))
+        else:
+            return rs
+            
+    timeout = 5
+
+    def read(self, hint):
+        events = self.poll.poll(self.timeout * 1000)
+        if not events:
+            print >> sys.stderr, ('[%stimed out after %d seconds]' %
+                                  (hint, self.timeout))
+            os.kill(self.pid, signal.SIGHUP)
+            return ''
+        return os.read(self.cfd, 1024)
+        
+    def receive(self, hint):
+        out = cStringIO.StringIO()
+        while True:
+            try:
+                if self.verbose:
+                    sys.stderr.write('< ')
+                s = self.read(hint)
+            except OSError, err:
+                if err.errno == errno.EIO:
+                    return '', ''
+                raise
+            if self.verbose:
+                print >> sys.stderr, self.debugrepr(s)
+            out.write(s)
+            s = out.getvalue()
+            if s.endswith(self.ps1):
+                return self.ps1, s.replace('\r\n', '\n')[:-len(self.ps1)]
+            if s.endswith(self.ps2):
+                return self.ps2, s.replace('\r\n', '\n')[:-len(self.ps2)]
+        
+    def sendreceive(self, s, hint):
+        self.send(s)
+        ps, r = self.receive(hint)
+        if r.startswith(s):
+            r = r[len(s):]
+        return ps, r
+    
+    def run(self):
+        ofp = None
+        basename = os.path.basename(self.name)
+        self.status('running %s ' % basename)
+        tmpdir = tempfile.mkdtemp(prefix=basename)
+
+        # remove the marker file that we tell make to use to see if
+        # this run succeeded
+        maybe_unlink(self.name + '.run')
+
+        rcfile = os.path.join(tmpdir, '.hgrc')
+        rcfp = open(rcfile, 'w')
+        print >> rcfp, '[ui]'
+        print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>"
+        
+        rcfile = os.path.join(tmpdir, '.bashrc')
+        rcfp = open(rcfile, 'w')
+        print >> rcfp, 'PS1="%s"' % self.ps1
+        print >> rcfp, 'PS2="%s"' % self.ps2
+        print >> rcfp, 'unset HISTFILE'
+        path = ['/usr/bin', '/bin']
+        hg = find_path_to('hg')
+        if hg and hg not in path:
+            path.append(hg)
+        def re_export(envar):
+            v = os.getenv(envar)
+            if v is not None:
+                print >> rcfp, 'export ' + envar + '=' + v
+        print >> rcfp, 'export PATH=' + ':'.join(path)
+        re_export('PYTHONPATH')
+        print >> rcfp, 'export EXAMPLE_DIR="%s"' % os.getcwd()
+        print >> rcfp, 'export HGMERGE=merge'
+        print >> rcfp, 'export LANG=C'
+        print >> rcfp, 'export LC_ALL=C'
+        print >> rcfp, 'export TZ=GMT'
+        print >> rcfp, 'export HGRC="%s/.hgrc"' % tmpdir
+        print >> rcfp, 'export HGRCPATH=$HGRC'
+        print >> rcfp, 'cd %s' % tmpdir
+        rcfp.close()
+        sys.stdout.flush()
+        sys.stderr.flush()
+        self.pid, self.cfd = pty.fork()
+        if self.pid == 0:
+            cmdline = ['/usr/bin/env', '-i', 'bash', '--noediting',
+                       '--noprofile', '--norc']
+            try:
+                os.execv(cmdline[0], cmdline)
+            except OSError, err:
+                print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror)
+                sys.stderr.flush()
+                os._exit(0)
+        self.poll.register(self.cfd, select.POLLIN | select.POLLERR |
+                           select.POLLHUP)
+
+        prompts = {
+            '': '',
+            self.ps1: '$',
+            self.ps2: '>',
+            }
+
+        ignore = [
+            r'\d+:[0-9a-f]{12}', # changeset number:hash
+            r'[0-9a-f]{40}', # long changeset hash
+            r'[0-9a-f]{12}', # short changeset hash
+            r'^(?:---|\+\+\+) .*', # diff header with dates
+            r'^date:.*', # date
+            #r'^diff -r.*', # "diff -r" is followed by hash
+            r'^# Date \d+ \d+', # hg patch header
+            ]
+
+        err = False
+        read_hint = ''
+
+        try:
+            try:
+                # eat first prompt string from shell
+                self.read(read_hint)
+                # setup env and prompt
+                ps, output = self.sendreceive('source %s\n' % rcfile,
+                                              read_hint)
+                for hunk in self.parse():
+                    # is this line a processing instruction?
+                    m = self.pi_re.match(hunk)
+                    if m:
+                        pi, rest = m.groups()
+                        if pi == 'name':
+                            self.status('.')
+                            out = rest
+                            if out in ('err', 'lxo', 'out', 'run', 'tmp'):
+                                print >> sys.stderr, ('%s: illegal section '
+                                                      'name %r' %
+                                                      (self.name, out))
+                                return 1
+                            assert os.sep not in out
+                            if ofp is not None:
+                                ofp.close()
+                                err |= self.rename_output(ofp_basename, ignore)
+                            if out:
+                                ofp_basename = '%s.%s' % (self.name, out)
+                                read_hint = ofp_basename + ' '
+                                ofp = open(ofp_basename + '.tmp', 'w')
+                            else:
+                                ofp = None
+                        elif pi == 'ignore':
+                            ignore.append(rest)
+                    elif hunk.strip():
+                        # it's something we should execute
+                        newps, output = self.sendreceive(hunk, read_hint)
+                        if not ofp:
+                            continue
+                        # first, print the command we ran
+                        if not hunk.startswith('#'):
+                            nl = hunk.endswith('\n')
+                            hunk = ('%s \\textbf{%s}' %
+                                    (prompts[ps],
+                                     tex_escape(hunk.rstrip('\n'))))
+                            if nl: hunk += '\n'
+                        ofp.write(hunk)
+                        # then its output
+                        ofp.write(tex_escape(output))
+                    ps = newps
+                self.status('\n')
+            except:
+                print >> sys.stderr, '(killed)'
+                os.kill(self.pid, signal.SIGKILL)
+                pid, rc = os.wait()
+                raise
+            else:
+                try:
+                    ps, output = self.sendreceive('exit\n', read_hint)
+                    if ofp is not None:
+                        ofp.write(output)
+                        ofp.close()
+                        err |= self.rename_output(ofp_basename, ignore)
+                    os.close(self.cfd)
+                except IOError:
+                    pass
+                os.kill(self.pid, signal.SIGTERM)
+                pid, rc = os.wait()
+                err = err or rc
+                if err:
+                    if os.WIFEXITED(rc):
+                        print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc)
+                    elif os.WIFSIGNALED(rc):
+                        print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
+                else:
+                    open(self.name + '.run', 'w')
+                return err
+        finally:
+            shutil.rmtree(tmpdir)
+
+    def rename_output(self, base, ignore):
+        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
+        def mangle(s):
+            return mangle_re.sub('', s)
+        def matchfp(fp1, fp2):
+            while True:
+                s1 = mangle(fp1.readline())
+                s2 = mangle(fp2.readline())
+                if cmp(s1, s2):
+                    break
+                if not s1:
+                    return True
+            return False
+
+        oldname = base + '.out'
+        tmpname = base + '.tmp'
+        errname = base + '.err'
+        errfp = open(errname, 'w+')
+        for line in open(tmpname):
+            errfp.write(mangle_re.sub('', line))
+        os.rename(tmpname, base + '.lxo')
+        errfp.seek(0)
+        try:
+            oldfp = open(oldname)
+        except IOError, err:
+            if err.errno != errno.ENOENT:
+                raise
+            os.rename(errname, oldname)
+            return False
+        if matchfp(oldfp, errfp):
+            os.unlink(errname)
+            return False
+        else:
+            print >> sys.stderr, '\nOutput of %s has changed!' % base
+            os.system('diff -u %s %s 1>&2' % (oldname, errname))
+            return True
+
+def print_help(exit, msg=None):
+    if msg:
+        print >> sys.stderr, 'Error:', msg
+    print >> sys.stderr, 'Usage: run-example [options] [test...]'
+    print >> sys.stderr, 'Options:'
+    print >> sys.stderr, '  -a --all       run all tests in this directory'
+    print >> sys.stderr, '  -h --help      print this help message'
+    print >> sys.stderr, '  -v --verbose   display extra debug output'
+    sys.exit(exit)
+
+def main(path='.'):
+    opts, args = getopt.getopt(sys.argv[1:], '?ahv',
+                               ['all', 'help', 'verbose'])
+    verbose = False
+    run_all = False
+    for o, a in opts:
+        if o in ('-h', '-?', '--help'):
+            print_help(0)
+        if o in ('-a', '--all'):
+            run_all = True
+        if o in ('-v', '--verbose'):
+            verbose = True
+    errs = 0
+    if args:
+        for a in args:
+            try:
+                st = os.lstat(a)
+            except OSError, err:
+                print >> sys.stderr, '%s: %s' % (a, err.strerror)
+                errs += 1
+                continue
+            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
+                if example(a, verbose).run():
+                    errs += 1
+            else:
+                print >> sys.stderr, '%s: not a file, or not executable' % a
+                errs += 1
+    elif run_all:
+        names = os.listdir(path)
+        names.sort()
+        for name in names:
+            if name == 'run-example' or name.startswith('.'): continue
+            if name.endswith('.out') or name.endswith('~'): continue
+            if name.endswith('.run'): continue
+            pathname = os.path.join(path, name)
+            try:
+                st = os.lstat(pathname)
+            except OSError, err:
+                # could be an output file that was removed while we ran
+                if err.errno != errno.ENOENT:
+                    raise
+                continue
+            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
+                if example(pathname, verbose).run():
+                    errs += 1
+        print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
+    else:
+        print_help(1, msg='no test names given, and --all not provided')
+    return errs
+
+if __name__ == '__main__':
+    try:
+        sys.exit(main())
+    except KeyboardInterrupt:
+        print >> sys.stderr, 'interrupted!'
+        sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/svn-long.txt	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,11 @@
+------------------------------------------------------------------------
+r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines
+Changed paths:
+   M /gen2/trunk/src/linux-kernel/infiniband/core/cma.c
+
+On reporting a route error, also include the status for the error,
+rather than indicating a status of 0 when an error has occurred.
+
+Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/svn-short.txt	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,9 @@
+------------------------------------------------------------------------
+r9653 | sean.hefty | 2006-09-27 14:39:55 -0700 (Wed, 27 Sep 2006) | 5 lines
+
+On reporting a route error, also include the status for the error,
+rather than indicating a status of 0 when an error has occurred.
+
+Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/svn.style	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2 @@
+header = '------------------------------------------------------------------------\n\n'
+changeset = svn.template
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/svn.template	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,5 @@
+r{rev} | {author|user} | {date|isodate} ({date|rfc822date})
+
+{desc|strip|fill76}
+
+------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/tag	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+#$ name: init
+
+hg init mytag
+cd mytag
+
+echo hello > myfile
+hg commit -A -m 'Initial commit'
+
+#$ name: tag
+
+hg tag v1.0
+
+#$ name: tags
+
+hg tags
+
+#$ name: log
+
+hg log
+
+#$ name: log.v1.0
+
+echo goodbye > myfile2
+hg commit -A -m 'Second commit'
+hg log -r v1.0
+
+#$ name: remove
+
+hg tag --remove v1.0
+hg tags
+
+#$ name: replace
+
+hg tag -r 1 v1.1
+hg tags
+hg tag -r 2 v1.1
+hg tag -f -r 2 v1.1
+hg tags
+
+#$ name: tip
+
+hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/template.simple	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+# So many different bits of random output, it would be a nightmare to
+# ignore each individually.
+#$ ignore: .*
+
+hg init myrepo
+cd myrepo
+echo hello > hello
+hg commit -Am'added hello'
+
+echo hello >> hello
+echo goodbye > goodbye
+echo '   added line to end of <<hello>> file.' > ../msg
+echo '' >> ../msg
+echo 'in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.' >> ../msg
+
+hg commit -Al../msg
+
+hg tag mytag
+hg tag v0.1
+
+#$ name: normal
+
+hg log -r1
+
+#$ name: compact
+
+hg log --style compact
+
+#$ name: changelog
+
+hg log --style changelog
+
+#$ name: simplest
+
+hg log -r1 --template 'i saw a changeset\n'
+
+#$ name: simplesub
+
+hg log --template 'i saw a changeset: {desc}\n'
+
+#$ name: keywords
+
+hg log -r1 --template 'author: {author}\n'
+hg log -r1 --template 'desc:\n{desc}\n'
+hg log -r1 --template 'files: {files}\n'
+hg log -r1 --template 'file_adds: {file_adds}\n'
+hg log -r1 --template 'file_dels: {file_dels}\n'
+hg log -r1 --template 'node: {node}\n'
+hg log -r1 --template 'parents: {parents}\n'
+hg log -r1 --template 'rev: {rev}\n'
+hg log -r1 --template 'tags: {tags}\n'
+
+#$ name: datekeyword
+
+hg log -r1 --template 'date: {date}\n'
+hg log -r1 --template 'date: {date|isodate}\n'
+
+#$ name: manyfilters
+
+hg log -r1 --template '{author}\n'
+hg log -r1 --template '{author|domain}\n'
+hg log -r1 --template '{author|email}\n'
+hg log -r1 --template '{author|obfuscate}\n' | cut -c-76
+hg log -r1 --template '{author|person}\n'
+hg log -r1 --template '{author|user}\n'
+
+hg log -r1 --template 'looks almost right, but actually garbage: {date}\n'
+hg log -r1 --template '{date|age}\n'
+hg log -r1 --template '{date|date}\n'
+hg log -r1 --template '{date|hgdate}\n'
+hg log -r1 --template '{date|isodate}\n'
+hg log -r1 --template '{date|rfc822date}\n'
+hg log -r1 --template '{date|shortdate}\n'
+
+hg log -r1 --template '{desc}\n' | cut -c-76
+hg log -r1 --template '{desc|addbreaks}\n' | cut -c-76
+hg log -r1 --template '{desc|escape}\n' | cut -c-76
+hg log -r1 --template '{desc|fill68}\n'
+hg log -r1 --template '{desc|fill76}\n'
+hg log -r1 --template '{desc|firstline}\n'
+hg log -r1 --template '{desc|strip}\n' | cut -c-76
+hg log -r1 --template '{desc|tabindent}\n' | expand | cut -c-76
+
+hg log -r1 --template '{node}\n'
+hg log -r1 --template '{node|short}\n'
+
+#$ name: combine
+
+hg log -r1 --template 'description:\n\t{desc|strip|fill68|tabindent}\n'
+
+#$ name: rev
+
+echo 'changeset = "rev: {rev}\n"' > rev
+hg log -l1 --style ./rev
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/template.svnstyle	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+svn() {
+  cat $EXAMPLE_DIR/svn-short.txt
+}
+
+#$ name: short
+
+svn log -r9653
+
+#$ name:
+
+hg init myrepo
+cd myrepo
+
+echo hello > hello
+hg commit -Am'added hello'
+
+echo hello >> hello
+echo goodbye > goodbye
+echo '   added line to end of <<hello>> file.' > ../msg
+echo '' >> ../msg
+echo 'in addition, added a file with the helpful name (at least i hope that some might consider it so) of goodbye.' >> ../msg
+
+hg commit -Al../msg
+
+hg tag mytag
+hg tag v0.1
+
+echo 'changeset = "{node|short}\n"' > svn.style
+
+#$ name: id
+
+hg log -r0 --template '{node}'
+
+#$ name: simplest
+
+cat svn.style
+hg log -r1 --style svn.style
+
+#$ name:
+
+echo 'changeset =' > broken.style
+
+#$ name: syntax.input
+
+cat broken.style
+
+#$ name: syntax.error
+
+hg log -r1 --style broken.style
+
+#$ name:
+
+cp $EXAMPLE_DIR/svn.style .
+cp $EXAMPLE_DIR/svn.template .
+
+#$ name: template
+
+cat svn.template
+
+#$ name: style
+
+cat svn.style
+
+#$ name: result
+#$ ignore: \| 200[78].*
+
+hg log -r1 --style svn.style
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/tour	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,194 @@
+#!/bin/bash
+
+#$ name: version
+
+hg version
+
+#$ name: help
+
+hg help init
+
+#$ name: clone
+
+hg clone http://hg.serpentine.com/tutorial/hello
+
+#$ name: ls
+#$ ignore: ^drwx.*
+#$ ignore: ^total \d+
+
+ls -l
+ls hello
+
+#$ name: ls-a
+
+cd hello
+ls -a
+
+#$ name: log
+
+hg log
+
+#$ name: log-r
+
+hg log -r 3
+hg log -r 0272e0d5a517
+hg log -r 1 -r 4
+
+#$ name: log.range
+
+hg log -r 2:4
+
+#$ name: log-v
+
+hg log -v -r 3
+
+#$ name: log-vp
+
+hg log -v -p -r 2
+
+#$ name: reclone
+
+cd ..
+hg clone hello my-hello
+cd my-hello
+
+#$ name: sed
+
+sed -i '/printf/a\\tprintf("hello again!\\n");' hello.c
+
+#$ name: status
+
+ls
+hg status
+
+#$ name: diff
+
+hg diff
+
+#$ name:
+
+export HGEDITOR='echo Added an extra line of output >'
+
+#$ name: commit
+
+hg commit
+
+#$ name: merge.dummy1
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-hello
+
+#$ name: tip
+
+hg tip -vp
+
+#$ name: clone-pull
+
+cd ..
+hg clone hello hello-pull
+
+#$ name: incoming
+
+cd hello-pull
+hg incoming ../my-hello
+
+#$ name: pull
+
+hg tip
+hg pull ../my-hello
+hg tip
+
+#$ name: update
+
+grep printf hello.c
+hg update tip
+grep printf hello.c
+
+#$ name: parents
+
+hg parents
+
+#$ name: older
+
+hg update 2
+hg parents
+hg update
+
+#$ name: clone-push
+
+cd ..
+hg clone hello hello-push
+
+#$ name: outgoing
+
+cd my-hello
+hg outgoing ../hello-push
+
+#$ name: push
+
+hg push ../hello-push
+
+#$ name: push.nothing
+
+hg push ../hello-push
+
+#$ name: outgoing.net
+
+hg outgoing http://hg.serpentine.com/tutorial/hello
+
+#$ name: push.net
+
+hg push http://hg.serpentine.com/tutorial/hello
+
+#$ name: merge.clone
+
+cd ..
+hg clone hello my-new-hello
+cd my-new-hello
+sed -i '/printf/i\\tprintf("once more, hello.\\n");' hello.c
+hg commit -m 'A new hello for a new day.'
+
+#$ name: merge.dummy2
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-new-hello
+
+#$ name: merge.cat
+
+cat hello.c
+cat ../my-hello/hello.c
+
+#$ name: merge.pull
+
+hg pull ../my-hello
+
+#$ name: merge.dummy3
+
+hg log -r 6 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV6.my-new-hello
+
+#$ name: merge.heads
+
+hg heads
+
+#$ name: merge.update
+
+hg update
+
+#$ name: merge.merge
+
+hg merge
+
+#$ name: merge.parents
+
+hg parents
+cat hello.c
+
+#$ name: merge.commit
+
+hg commit -m 'Merged changes'
+
+#$ name: merge.dummy4
+
+hg log -r 7 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV7.my-new-hello
+
+#$ name: merge.tip
+
+hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/examples/tour-merge-conflict	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+hg init scam
+cd scam
+
+#$ name: wife
+
+cat > letter.txt <<EOF
+Greetings!
+
+I am Mariam Abacha, the wife of former
+Nigerian dictator Sani Abacha.
+EOF
+
+hg add letter.txt
+hg commit -m '419 scam, first draft'
+
+#$ name: cousin
+
+cd ..
+hg clone scam scam-cousin
+cd scam-cousin
+
+cat > letter.txt <<EOF
+Greetings!
+
+I am Shehu Musa Abacha, cousin to the former
+Nigerian dictator Sani Abacha.
+EOF
+
+hg commit -m '419 scam, with cousin'
+
+#$ name: son
+
+cd ..
+hg clone scam scam-son
+cd scam-son
+
+cat > letter.txt <<EOF
+Greetings!
+
+I am Alhaji Abba Abacha, son of the former
+Nigerian dictator Sani Abacha.
+EOF
+
+hg commit -m '419 scam, with son'
+
+#$ name: pull
+
+cd ..
+hg clone scam-cousin scam-merge
+cd scam-merge
+hg pull -u ../scam-son
+
+#$ name: merge
+#$ ignore: [<>]{7} /tmp/.*
+
+export HGMERGE=merge
+hg merge
+cat letter.txt
+
+#$ name: commit
+
+cat > letter.txt <<EOF
+Greetings!
+
+I am Bryan O'Sullivan, no relation of the former
+Nigerian dictator Sani Abacha.
+EOF
+
+hg resolve -m letter.txt
+hg commit -m 'Send me your money'
+hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/fblinks	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/fblinks
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/feature-branches.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+digraph feature_branches {
+	maestro -> cripto;
+	maestro -> sistemadearchivos;
+	maestro -> ipc;
+	maestro -> memoria;
+	maestro -> red;
+	maestro -> seguridad;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/filelog.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="filelog.svg"
+   sodipodi:docbase="/home/arun/hgbook/en"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective57" />
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3128"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient2887">
+      <stop
+         style="stop-color:#91cfcf;stop-opacity:1;"
+         offset="0"
+         id="stop2889" />
+      <stop
+         style="stop-color:aqua;stop-opacity:0;"
+         offset="1"
+         id="stop2891" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2795">
+      <stop
+         style="stop-color:#ccc;stop-opacity:1;"
+         offset="0"
+         id="stop2797" />
+      <stop
+         style="stop-color:#ccc;stop-opacity:0;"
+         offset="1"
+         id="stop2799" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3170"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(121.2183,94.95434)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3172"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3174"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3176"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3208"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.001035,0,0,0.653159,236.7075,153.0415)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3210"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3212"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(121.2183,94.95434)"
+       x1="81.322357"
+       y1="404.34424"
+       x2="201.52036"
+       y2="373.03967" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3214"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,12)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3256"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2343775,0,0,0.9981848,103.25588,95.681888)"
+       x1="74.301666"
+       y1="431.67441"
+       x2="260.05884"
+       y2="369.95322" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3258"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.228929,0,0,0.9972824,-62.037003,13.312997)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2795"
+       id="linearGradient3260"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2300738,0,0,0.6517275,219.97511,153.61527)"
+       x1="74.387527"
+       y1="431.80576"
+       x2="259.97339"
+       y2="369.82224" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2887"
+       id="linearGradient3262"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.2289272,0,0,0.9972824,-62.036756,13.312985)"
+       x1="62.634491"
+       y1="503.3392"
+       x2="248.49242"
+       y2="462.94327" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="455.8122"
+     inkscape:cy="520"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1280"
+     inkscape:window-height="800"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#abadf8;fill-opacity:1;stroke:#595959;stroke-width:0.93760371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3180"
+       width="273.81375"
+       height="199.06245"
+       x="369.1796"
+       y="351.79019" />
+    <rect
+       style="opacity:1;fill:#a2f69c;fill-opacity:1;stroke:#595959;stroke-width:0.93760341;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3178"
+       width="273.81339"
+       height="199.06233"
+       x="72.699799"
+       y="351.78983" />
+    <g
+       id="g3144"
+       transform="translate(80.467048,0.71578)">
+      <g
+         id="g2940">
+        <rect
+           style="fill:url(#linearGradient3260);fill-opacity:1;stroke:#000000;stroke-width:0.89536202;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect2914"
+           width="227.38896"
+           height="39.500999"
+           x="311.92496"
+           y="395.08627" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="323.72824"
+           y="416.7626"
+           id="text2918"><tspan
+             sodipodi:role="line"
+             id="tspan2920"
+             x="323.72824"
+             y="416.7626"
+             style="font-family:Courier">.hg/store/data/README.i</tspan></text>
+      </g>
+      <g
+         transform="translate(3.79093e-5,-80.1853)"
+         id="g2945">
+        <g
+           id="g2955">
+          <rect
+             y="475.4968"
+             x="15.550935"
+             height="39.500999"
+             width="227.17694"
+             id="rect2947"
+             style="fill:url(#linearGradient3262);fill-opacity:1;stroke:#000000;stroke-width:1.10706258;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text2949"
+             y="498.35123"
+             x="31.230644"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="498.35123"
+               x="31.230644"
+               id="tspan2951"
+               sodipodi:role="line">README</tspan></text>
+        </g>
+      </g>
+      <path
+         inkscape:connector-type="polyline"
+         id="path2960"
+         d="M 242.94685,414.91115 C 242.94685,414.91115 293.61127,415.26754 310.16269,415.38633"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.02046943px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         sodipodi:nodetypes="cz" />
+    </g>
+    <g
+       id="g3156"
+       transform="translate(80.467048,0.71578)">
+      <g
+         transform="translate(116,0)"
+         id="g2831">
+        <rect
+           style="fill:url(#linearGradient3256);fill-opacity:1;stroke:#000000;stroke-width:1.11001658;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect1906"
+           width="228.18446"
+           height="60.499123"
+           x="195.52719"
+           y="465.51859" />
+        <g
+           id="g2803"
+           transform="translate(-0.893671,1.833581)">
+          <text
+             id="text1884"
+             y="483.92801"
+             x="208.95944"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="483.92801"
+               x="208.95944"
+               id="tspan1886"
+               sodipodi:role="line">.hg/store/data/src/hello.c.d</tspan></text>
+          <text
+             id="text1888"
+             y="507.79309"
+             x="208.95944"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="507.79309"
+               x="208.95944"
+               id="tspan1890"
+               sodipodi:role="line">.hg/store/data/src/hello.c.i</tspan></text>
+        </g>
+      </g>
+      <g
+         id="g2907">
+        <rect
+           style="fill:url(#linearGradient3258);fill-opacity:1;stroke:#000000;stroke-width:1.10706329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect2843"
+           width="227.17728"
+           height="39.500999"
+           x="15.550805"
+           y="475.4968" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="31.230644"
+           y="498.35123"
+           id="text2847"><tspan
+             sodipodi:role="line"
+             id="tspan2849"
+             x="31.230644"
+             y="498.35123"
+             style="font-family:Courier">src/hello.c</tspan></text>
+      </g>
+      <path
+         inkscape:connection-end="#g2831"
+         inkscape:connection-start="#g2907"
+         inkscape:connector-type="polyline"
+         id="path2962"
+         d="M 242.4315,495.88043 C 242.4315,495.88043 292.8861,495.99942 310.04102,496.03909"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         sodipodi:nodetypes="cs" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="98.496666"
+       y="373.96353"
+       id="text3216"><tspan
+         sodipodi:role="line"
+         id="tspan3218"
+         x="98.496666"
+         y="373.96353">Directorio de trabajo</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="391.39197"
+       y="373.96353"
+       id="text3228"><tspan
+         sodipodi:role="line"
+         id="tspan3230"
+         x="391.39197"
+         y="373.96353">Repositorio</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/filenames.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,344 @@
+\chapter{Nombres de ficheros y asociación de patrones}
+\label{chap:names}
+
+Mercurial provee mecanismos que le permiten trabajar con nombres de
+ficheros en una manera consistente y expresiva.
+
+\section{Nombrado de ficheros simple}
+
+% TODO traducción literal de "under the hood". revisar
+Mercurial usa un mecanismo unificado ``bajo el capó'' para manejar
+nombres de ficheros. Cada comando se comporta de manera uniforme con
+respecto a los nombres de fichero. La manera en que los comandos
+operan con nombres de fichero es la siguiente.
+
+Si usted especifica explícitamente nombres reales de ficheros en la
+línea de comandos, Mercurial opera únicamente sobre dichos ficheros,
+como usted esperaría.
+\interaction{filenames.files}
+
+Cuando usted provee el nombre de un directorio, Mercurial interpreta
+eso como ``opere en cada fichero en este directorio y sus
+subdirectorios''. Mercurial va por todos los ficheros y subdirectorios
+de un directorio en orden alfabético. Cuando encuentra un
+subdirectorio, lo recorrerá antes de continuar con el directorio
+actual.
+\interaction{filenames.dirs}
+
+\section{Ejecución de comandos sin ningún nombre de fichero}
+
+Los comandos de Mercurial que trabajan con nombres de fichero tienen
+comportamientos por defecto adecuados cuando son utilizados sin pasar
+ningún patrón o nombre de fichero. El tipo de comportamiento depende
+de lo que haga el comando. Aquí presento unas cuantas reglas generales
+que usted puede usar para que es lo que probablemente hará un comando
+si usted no le pasa ningún nombre de fichero con el cual trabajar.
+\begin{itemize}
+\item Muchos comandos operarán sobre el directorio de trabajo
+    completo. Por ejemplo, esto es lo que hace el comando
+    \hgcmd{add},
+\item Si el comando tiene efectos difíciles o incluso imposibles de
+    revertir, se le obligará a usted a proveer explícitamente al menos
+    % TODO revisar ese "lo proteje a usted"
+    un nombre o patrón (ver más abajo). Esto lo proteje a usted de,
+    por ejemplo, borrar ficheros accidentalmente al ejecutar
+    \hgcmd{remove} sin ningún argumento.
+\end{itemize}
+
+
+Es fácil evitar este comportamiento por defecto, si no es el adecuado
+para usted. Si un comando opera normalmente en todo el directorio de
+trabajo, usted puede llamarlo para que trabaje sólo en el directorio
+actual y sus subdirectorio pasándole el nombre ``\dirname{.}''.
+\interaction{filenames.wdir-subdir}
+
+Siguiendo la misma línea, algunos comandos normalmente imprimen las
+rutas de ficheros con respecto a la raíz del repositorio, aún si usted
+los llama dentro de un subdirectorio. Dichos comandos imprimirán las
+rutas de los ficheros respecto al directorio en que usted se encuentra
+si se les pasan nombres explícitos. Vamos a ejecutar el comando
+\hgcmd{status} desde un subdirectorio, y a hacer que opere en el
+directorio de trabajo completo, a la vez que todas las rutas de
+ficheros se imprimen respecto a nuestro subdirectorio, pasándole la
+salida del comando \hgcmd{root}.
+\interaction{filenames.wdir-relname}
+
+\section{Reportar que está pasando}
+
+El ejemplo con el comando \hgcmd{add} en la sección anterior ilustra
+algo más que es útil acerca de los comandos de Mercurial. Si un
+comando opera en un fichero que usted no pasó explícitamente en la
+línea de comandos, usualmente se imprimirá el nombre del fichero, para
+que usted no sea sorprendido por lo que sucede.
+
+Esto es el principio de \emph{mínima sorpresa}. Si usted se ha
+referido explícitamente a un fichero en la línea de comandos, no tiene
+mucho sentido repetir esto de vuelta a usted. Si Mercurial está
+actuando en un fichero \emph{implícitamente}, porque usted no pasó
+nombres, ni directorios, ni patrones (ver más abajo), lo más seguro es
+decirle a usted qué se está haciendo.
+
+Usted puede silenciar a los comandos que se comportan de esta manera
+usando la opción \hggopt{-q}.  También puede hacer que impriman el
+nombre de cada fichero, aún aquellos que usted indicó explícitamente,
+usando la opción \hggopt{-v}.
+
+\section{Uso de patrones para identificar ficheros}
+
+Además de trabajar con nombres de ficheros y directorios, Mercurial le
+permite usar \emph{patrones} para identificar ficheros. El manejo de
+patrones de Mercurial es expresivo.
+
+En sistemas tipo Unix (Linux, MacOS, etc.), el trabajo de asociar
+patrones con nombres de ficheros recae sobre el intérprete de comandos.
+En estos sistemas, usted debe indicarle explícitamente a Mercurial que
+el nombre que se le pasa es un patrón. En Windows, el intérprete no
+expande los patrones, así que Mercurial identificará automáticamente
+los nombres que son patrones, y hará la expansión necesaria.
+
+Para pasar un patrón en vez de un nombre normal en la línea de
+comandos, el mecanismo es simple:
+\begin{codesample2}
+  syntax:patternbody
+\end{codesample2}
+Un patrón es identificado por una cadena de texto corta que indica qué
+tipo de patrón es, seguido por un dos puntos, seguido por el patrón en
+sí.
+
+Mercurial soporta dos tipos de sintaxis para patrones. La que se usa
+con más frecuencia  se denomina \texttt{glob}\ndt{Grupo, colección,
+aglomeración.}; es el mismo tipo de asociación de patrones usado por
+el intérprete de Unix, y también debería ser familiar para los
+usuarios de la línea de comandos de Windows.
+
+Cuando Mercurial hace asociación automática de patrones en Windows,
+usa la sintaxis \texttt{glob}.  Por esto, usted puede omitir el
+prefijo ``\texttt{glob:}'' en Windows, pero también es seguro usarlo.
+
+La sintaxis \texttt{re}\ndt{Expresiones regulares.} es más poderosa;
+le permite especificar patrones usando expresiones regulares, también
+conocidas como regexps.
+
+A propósito, en los ejemplos siguientes, por favor note que yo tengo
+el cuidado de rodear todos mis patrones con comillas sencillas, para
+que no sean expandidos por el intérprete antes de que Mercurial pueda
+verlos.
+
+\subsection{Patrones \texttt{glob} estilo intérprete}
+
+Este es un vistazo general de los tipos de patrones que usted puede
+usar cuando está usando asociación con patrone glob.
+
+La secuencia ``\texttt{*}'' se asocia con cualquier cadena, dentro de
+un único directorio.
+\interaction{filenames.glob.star}
+
+La secuencia ``\texttt{**}'' se asocia con cualquier cadena, y cruza los
+% TODO token
+límites de los directorios. No es una elemento estándar de los tokens
+de glob de Unix, pero es aceptado por varios intérpretes Unix
+populares, y es muy útil.
+\interaction{filenames.glob.starstar}
+
+La secuencia ``\texttt{?}'' se asocia con cualquier caracter sencillo.
+\interaction{filenames.glob.question}
+
+El caracter ``\texttt{[}'' marca el inicio de una \emph{clase de
+caracteres}.  Ella se asocia con cualquier caracter sencillo dentro de
+la clase. La clase se finaliza con un caracter ``\texttt{]}''. Una
+clase puede contener múltiples \emph{rango}s de la forma
+``\texttt{a-f}'', que en este caso es una abreviación para
+``\texttt{abcdef}''.
+\interaction{filenames.glob.range}
+Si el primer caracter en aparecer después de ``\texttt{[}'' en la
+clase de caracteres es un ``\texttt{!}'', se \emph{niega} la clase,
+haciendo que se asocie con cualquier caracter sencillo que no se
+encuentre en la clase.
+
+Un ``\texttt{\{}'' marca el inicio de un grupo de subpatrones, en
+donde todo el grupo es asociado si cualquier subpatrón en el grupo
+puede ser asociado. El caracter ``\texttt{,}'' separa los subpatrones,
+y el ``\texttt{\}}'' finaliza el grupo.
+\interaction{filenames.glob.group}
+
+\subsubsection{Cuidado!}
+
+No olvide que si usted desea asocia un patrón con cualquier
+directorio, no debería usar el elemento para asociar con cualquier
+cadena ``\texttt{*}'', ya que éste sólo generará asociaciones dentro
+de un solo directorio. En vez de eso, use el caracter para asociar con
+cualquier cadena ``\texttt{**}''. Este pequeño ejemplo ilustra la
+diferencia entre los dos.
+\interaction{filenames.glob.star-starstar}
+
+\subsection{Asociación con patrones de expresiones regulares \texttt{re}}
+
+Mercurial acepta la misma sintaxis para expresiones regulares del
+lenguaje de programación Python (internamente se usa el motor de
+expresiones regulares de Python). Esta sintaxis está basada en la
+misma del lenguaje Perl, que es el dialecto más popular en uso
+(por ejemplo, también se usa en Java).
+
+No discutiré el dialecto de expresiones regulares de Mercurial en
+detalle aquí, ya que las mismas no son usadas frecuentemente. Las
+expresiones regulares al estilo Perl se encuentran documentadas
+exhaustivamente en una multitud de sitios web, y en muchos libros.
+En vez de eso, me enfocaré en unas cuantas cosas que usted debería
+conocer si tiene la necesidad de usar expresiones regulares en
+Mercurial.
+
+Una expresión regular es comparada contra un nombre de fichero
+completo, relativo a la raíz del repositorio. En otras palabras, aún
+si usted se encuentra en un subdirectorio \dirname{foo}, si desea
+asociar ficheros en este directorio, su patrón debe empezar con
+``\texttt{foo/}''.
+
+Un detalle a tener en cuenta es que, si le son familiares las
+expresiones regulares al estilo Perl, las de Mercurial están
+\emph{enraízadas}. Esto es, que la asociación de una expresión se hace
+desde el inicio de la cadena; no se buscan coincidencias dentro de la
+cadena. Para buscar coincidencias en cualquier sitio dentro de una
+cadena, empiece su patrón con un ``\texttt{.*}''.
+
+\section{Filtrado de ficheros}
+
+Mercurial no sólo le provee una variedad de formas para especificar
+ficheros; le permite limitar aún más dichos ficheros mediante el uso
+de \emph{filtros}. Los comandos que operan con nombres de fichero
+aceptan dos opciones de filtrado.
+\begin{itemize}
+\item \hggopt{-I}, o \hggopt{--include}, le permite especificar un
+    patrón con el que deben coincidir los ficheros para ser
+    procesados.
+\item \hggopt{-X}, o \hggopt{--exclude}, le brinda una manera de 
+  \emph{evitar} procesar ficheros, si coinciden con este patrón.
+\end{itemize}
+Usted puede pasar múltiples veces las opciones \hggopt{-I} y
+\hggopt{-X} en la línea de comandos, e intercalarlos como desee.
+Por defecto, Mercurial interpreta los patrones que usted pase usando
+la sintaxis glob (pero usted puede usar expresiones regulares si lo
+necesita).
+
+El filtro \hggopt{-I} puede verse como un ``procese todos los ficheros
+que coincidan con este filtro''.
+\interaction{filenames.filter.include}
+El filtro \hggopt{-X} puede verse como ``procese únicamente los
+ficheros que no coincidan con este patrón''.
+\interaction{filenames.filter.exclude}
+
+\section{Ignorar ficheros y directorios no deseados}
+
+XXX.
+
+\section{Sensibilidad a mayúsculas}
+\label{sec:names:case}
+
+Si usted está trabajando en un ambiente de desarrollo mixto que
+contiene tanto sistemas Linux (u otro Unix) y sistemas Mac o Windows,
+debería tener en mente el hecho de que ellos tratan 
+%TODO FIXME seguir desde aqui, no tengo idea de como traducir case
+%sensitivity
+case (``N'' versus ``n'') of file names in incompatible ways.  This is
+not very likely to affect you, and it's easy to deal with if it does,
+but it could surprise you if you don't know about it.
+
+Operating systems and filesystems differ in the way they handle the
+\emph{case} of characters in file and directory names.  There are
+three common ways to handle case in names.
+\begin{itemize}
+\item Completely case insensitive.  Uppercase and lowercase versions
+  of a letter are treated as identical, both when creating a file and
+  during subsequent accesses.  This is common on older DOS-based
+  systems.
+\item Case preserving, but insensitive.  When a file or directory is
+  created, the case of its name is stored, and can be retrieved and
+  displayed by the operating system.  When an existing file is being
+  looked up, its case is ignored.  This is the standard arrangement on
+  Windows and MacOS.  The names \filename{foo} and \filename{FoO}
+  identify the same file.  This treatment of uppercase and lowercase
+  letters as interchangeable is also referred to as \emph{case
+    folding}.
+\item Case sensitive.  The case of a name is significant at all times.
+  The names \filename{foo} and {FoO} identify different files.  This
+  is the way Linux and Unix systems normally work.
+\end{itemize}
+
+On Unix-like systems, it is possible to have any or all of the above
+ways of handling case in action at once.  For example, if you use a
+USB thumb drive formatted with a FAT32 filesystem on a Linux system,
+Linux will handle names on that filesystem in a case preserving, but
+insensitive, way.
+
+\subsection{Almacenamiento portable y seguro de repositorios}
+
+El mecanismo de almacenamiento de los repositorios en Mercurial es
+\emph{robusto frente a sensibilidad/insensibilidad a mayúsculas}. Los nombres de
+fichero son traducidos para que puedan ser almacenados de manera
+segura tanto en sistemas sensibles como insensibles a mayúsculas. Esto
+significa que usted puede usar herramientas normales de copia de
+ficheros para transferir un repositorio Mercurial a, por ejemplo, una
+memoria USB, y trasladar de manera segura la memoria y el repositorio
+de ida y vuelta entre un Mac, un PC ejecutando Windows, y un sistema
+Linux
+
+\subsection{Detección de conflictos de mayúsculas/minúsculas}
+
+Al operar en el directorio de trabajo, Mercurial respeta la política
+de nombrado del sistema de ficheros en que se encuentre el directorio
+de trabajo. Si el sistema de ficheros conserva las diferencias entre
+mayúsculas, pero no es sensible a ellas, Mercurial tratará los nombres
+que sólo difieren en mayúsculas como uno solo y el mismo.
+
+Un aspecto importante de este enfoque es que es posible consignar un
+conjunto de cambios en un sistema de ficheros sensible a mayúsculas
+(típicamente Linux o Unix) que terminará causando problemas para
+usuarios en sistemas insensibles a mayúsculas (usualmente en Windows o
+MacOS). Si un usuario de Linux consigna cambios a dos ficheros, uno de
+ellos llamado \filename{myfile.c} y el otro llamado \filename{MyFile.C},
+ambos serán almacenados correctamente en el repositorio. Y serán
+representados correctamente como ficheros separados, en los
+directorios de trabajo de otros usuarios de Linux.
+
+Si un usuario de Windows o Mac jalan este cambio, no tendrán problemas
+inicialmente, porque el mecanismo de almacenamiento de Mercurial es
+seguro frente a sensibilidad/insensibilidad a mayúsculas. Sin embargo,
+una vez que ellos traten de actualizar (\hgcmd{update}) el directorio
+de trabajo con ese conjunto de cambios, o hagan fusión (\hgcmd{merge})
+con ese conjunto de cambios, Mercurial verá el conflicto entre los dos
+nombres de fichero que el sistema de ficheros trataría como el mismo,
+e impedirá que ocurra la actualización o fusión.
+
+\subsection{Arreglar un conflicto de mayúsculas/minúsculas}
+
+Si usted está usando Windows o Mac en un entorno mixto donde algunos
+de sus colaboradores están usando Linux o Unix, y Mercurial reporta un
+conflicto de mayúsculas/minúsculas cuando usted trata de actualizar
+(\hgcmd{update}) o fusionar (\hgcmd{merge}), el procedimiento para
+arreglar el problema es simple.
+
+Sólo busque un sistema Linux o Unix cercano, clone el repositorio
+problema allí, y use el comando \hgcmd{rename} de Mercurial para
+cambiar los nombres de cualquiera de los ficheros o directorios
+problemáticos para que no causen más conflictos. Consigne este cambio,
+y jálelo (\hgcmd{pull}) o empújelo (\hgcmd{push}) a su sistema Windows
+o MacOS, y actualícelo (\hgcmd{update}) a la revisión con los nombres
+que ya no generan conflictos.
+
+El conjunto de cambios con los nombres con conflictos de
+mayúsculas/minúsculas permanecerá en el historial de su proyecto, y
+usted no podrá actualizar (\hgcmd{update}) su directorio de trabajo a
+dicho conjunto de cambios en un sistema Windows o MacOS, pero puede
+continuar el desarrollo sin impedimentos.
+
+\begin{note}
+  Antes de la versión~0.9.3, Mercurial no usaba un mecanismos seguro
+  frente a sensibilidad/insensibilidad a mayúsculas o minúsculas, y no
+  detectaba los conflictos con nombres de ficheros. Si usted está
+  usando una versión más antigua de Mercurial en Windows o MacOS, le
+  recomiendo enérgicamente que se actualice.
+\end{note}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/fixhtml.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/fixhtml.py
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/fixsvg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/fixsvg
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/hgbook.css	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/hgbook.css
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/hgext.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,441 @@
+\chapter{Añadir funcionalidad con extensiones}
+\label{chap:hgext}
+
+A pesar de que el corazón de Mercurial es muy completo desde el punto
+de vista de funcionalidad, carece de características rimbombantes
+deliberadamente.  Esta aproximación de preservar la simplicidad
+mantiene el programa sencillo tanto para mantenedores como para
+usuarios.
+
+Si embargo Mercurial no le cierra las posibilidades a un conjunto
+inflexible de órdenes: usted puede añadir características como
+\emph{extensiones} (aveces llamadas \emph{añadidos}\ndt{plugins}).  Ya
+hemos discutido algunas de estas extensiones en capítulos anteriores:
+\begin{itemize}
+\item La sección~\ref{sec:tour-merge:fetch} cubre la extensión
+  \hgext{fetch}; que combina jalar cambios y fusionarlos con los
+  cambios locales en una sola orden: \hgxcmd{fetch}{fetch}.
+\item En el capítulo~\ref{chap:hook}, cubrimos muchas extensiones que
+  son útiles en funcionalidades relacionadas con ganchos: Los
+  \hgext{acl} añaden listas de control de acceso; \hgext{bugzilla}
+  añade integración con el sistema de seguimiento de fallos Bugzilla; y
+  \hgext{notify} envía notificaciones por correo de nuevos cambios.
+\item La extensión de administración de parches MQ es tan invaluable
+  que amerita dos capítulos y un apéndice por sí misma.
+  El capítulo~\ref{chap:mq} cubre lo básico; el
+  capítulo~\ref{chap:mq-collab} discute temas avanzados; y el
+  apéndice~\ref{chap:mqref} muestra en detalle cada orden.
+\end{itemize}
+
+En este capítulo cubriremos algunas extensiones adicionales
+disponibles para Mercurial, y daremos un vistazo a la maquinaria que
+necesita conocer en caso de que desee escribir una extensión.
+\begin{itemize}
+\item En la sección~\ref{sec:hgext:inotify}, discutiremos la
+  posibilidad de mejorar el desempeño \emph{en gran medida} con la extensión
+  \hgext{inotify}.
+\end{itemize}
+
+\section{Mejorar el desempeño con la extensión \hgext{inotify}}
+\label{sec:hgext:inotify}
+
+¿Desea lograr que las operaciones más comunmente usadas de Mercurial se
+ejecuten centenas de veces más rápido? ¡A leer!
+
+Mercurial tiene gran desempeño bajo circunstancias normales.  Por
+ejemplo, cuando ejecuta la orden \hgcmd{status}, Mercurial tiene que
+revisar casi todos los ficheros y directorios en su repositorio de
+forma que pueda desplegar el estado de los ficheros.  Muchas otras
+órdenes tienen que hacer tal trabajo tras bambalinas;  por ejemplo la
+orden \hgcmd{diff} usa la maquinaria de estado para evitar hacer
+operaciones de comparación costosas en ficheros que obviamente no han
+cambiado.
+
+Dado que obtener el estado de los ficheros es crucial para obtener
+buen desempeño, los autores de Mercurial han optimizado este código en
+la medida de lo posible.  Sin embargo, no puede obviarse el hecho de
+que cuando ejecuta \hgcmd{status}, Mercurial tendrá que hacer por lo
+menos una costosa llamada al sistema por cada fichero administrado
+para determinar si ha cambiado desde la última vez que se consignó.
+Para un repositorio suficientemente grande, puede tardar bastante
+tiempo.
+
+Para mostrar en números la magnitud de este efect, creé un repositorio
+que contenía 150.000 ficheros administrador.  Tardó diez segundos para
+ejecutar \hgcmd{status}, a pesar de que \emph{ninguno} de los ficheros
+había sido modificado.
+
+Muchos sistemas operativos modernos contienen una facilidad de
+notificación de ficheros.  Si un programa se registra con un servicio
+apropiado, el sistema operativo le notificará siempre que un fichero
+de interés haya sido creado, modificado o borrado.  En sistemas Linux,
+el componente del núcleo que lo hace se llama \texttt{inotify}.
+
+La extensión \hgext{inotify} habla con el componente \texttt{inotify}
+del núcleo para optimizar las órdenes de \hgcmd{status}.  La extensión
+tiene dos componentes.  Un daemonio está en el fondo recibiendo
+notificaciones del subsistema \texttt{inotify}.  También escucha
+conexiones de una orden regular de Mercurial.  La extensión modifica
+el comportamiento de Mercurial de tal forma que, en lugar de revisar
+el sistema de ficheros, le pregunta al daemonio.  Dado que el daemonio
+tiene información perfecta acerca del estado del repositorio, puede
+responder instantáneamente con el resultado, evitando la necesidad de
+revisar cada directorio y fichero del repositorio.
+
+Retomando los diez segundos que medí al ejecutar la orden
+\hgcmd{status} de Mercurial sobre un repositorio de 150.000
+ficheros. Con la extensión \hgext{inotify} habilitada, el tiempo se
+disipó a 0.1~seconds, un factor \emph{cien veces} más rápido.
+
+Antes de continuar, tenga en cuenta algunos detalles:
+\begin{itemize}
+\item La extensión \hgext{inotify} es específica de Linux.  Porque se
+  enlaza directamente con el subsistema \texttt{inotify} del núcleo
+  Linux, no funciona en otros sistemas operativos.
+\item Debería funcionar en cualquier distribución Linux a partir de
+  comienzos del 2005.  Las distribuciones más antiguas deben tener un
+  kernel sin \texttt{inotify}, o una versión de \texttt{glibc} que no
+  tiene necesariamente el soporte para la interfaz.
+\item No todos los sistemas de ficheros pueden usarse con la extensión
+  \hgext{inotify}.  Los sistemas de ficheros tales como NFS no lo
+  soportan, por ejemplo, si está corriendo Mercurial en vaios
+  sistemas, montados todos sobre el mismo sistema de ficheros en red.
+  El sistema \texttt{inotify} del kernel no tiene forma de saber
+  acerca de los cambios hechos en otro sistema.  La mayoría de
+  sistemas de ficheros locales (p.e.~ext3, XFS, ReiserFS) deberían
+  funcionar bien.
+\end{itemize}
+
+Hacia mayo de 2007 la extensión \hgext{inotify} no venía de forma
+predeterminada en Mercurial\ndt{Desde el 2008 para kernels 2.6 viene
+  en Mercurial, pero no está activada de forma predeterminada}, y es
+un poco más compleja de activar que otras extensiones.  Pero la mejora
+en el desempeño bien vale la pena!
+
+La extensión venía en dos partes: un conjunto de parches al código
+fuente de Mercurial, y una librería de interfaces de Python hacia el
+subsistema \texttt{inotify}.
+\begin{note}
+  Hay \emph{dos} librerías de enlace de Python hacia \texttt{inotify}.
+  Una de ellas se llama \texttt{pyinotify}, y en algunas
+  distribuciones de Linux se encuentra como \texttt{python-inotify}.
+  Esta es la que \emph{no} necesita, puesto que tiene muchos fallos,
+  y es ineficiente para ser práctica.
+\end{note}
+Para comenzar, es mejor tener una copia de Mercurial funcional
+instalada:
+\begin{note}
+  Si sigue las instrucciones a continuación, estará
+  \emph{reemplazando} y sobreescribiendo cualquier instalación previa
+  de Mercurial que pudiera tener, con el código de Mercurial ``más
+  reciente y peligrosa''.  No diga que no se le advirtio!
+\end{note}
+\begin{enumerate}
+\item Clone el repositorio de interfaz entre Python e
+  \texttt{inotify}. Ármelo e instálelo:
+  \begin{codesample4}
+    hg clone http://hg.kublai.com/python/inotify
+    cd inotify
+    python setup.py build --force
+    sudo python setup.py install --skip-build
+  \end{codesample4}
+\item Clone el repositorio \dirname{crew} de Mercurial.  Clone el
+  repositorio de parches de \hgext{inotify} de forma tal que las colas
+  de Mercurial puedan aplicar los parches sobre el repositorio \dirname{crew}.
+  \begin{codesample4}
+    hg clone http://hg.intevation.org/mercurial/crew
+    hg clone crew inotify
+    hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches
+  \end{codesample4}
+\item Asegúrese de instalar la extensión Colas de Mercurial
+  \hgext{mq} y que estén habilitadas.  Si nunca ha usado MQ, lea la
+  sección~\ref{sec:mq:start} para poder comenzar rápidamente.
+\item Vaya al repositorio de \dirname{inotify} y aplique todos los
+  parches de \hgext{inotify} con la opción \hgxopt{mq}{qpush}{-a} de
+  la orden \hgxcmd{mq}{qpush}.
+  \begin{codesample4}
+    cd inotify
+    hg qpush -a
+  \end{codesample4}
+  Si obtiene un mensaje de error de \hgxcmd{mq}{qpush}, no debería
+  continuar.  Mejor pida ayuda.
+\item Arme e instale la versión parchada de Mercurial.
+  \begin{codesample4}
+    python setup.py build --force
+    sudo python setup.py install --skip-build
+  \end{codesample4}
+\end{enumerate}
+Una vez que haya armado una versión funcional parchada de Mercurial,
+todo lo que necesita es habilitar la extensión \hgext{inotify}
+colocando una entrada en su \hgrc.
+\begin{codesample2}
+  [extensions]
+  inotify =
+\end{codesample2}
+Cuando la extensión \hgext{inotify} esté habilitada, Mercurial
+iniciará transparente y automáticamente el daemonio de estado la
+primera vez que ejecute un comando que requiera estado del
+repositorio.  Ejecuta un daemonio de estado por repositorio.
+
+El daemonio de estado se inicia silenciosamente y se ejecuta en el
+fondo. Si mira a la lista de procesos en ejecución después de
+habilitar la extensión \hgext{inotify} y ejecuta unos pocos comandos
+en diferentes repositorios, verá que hay algunos procesos de
+\texttt{hg} por ahí, esperando actualizaciones del kernel y
+solicitudes de Mercurial.
+
+La primera vez que ejecuta un comando de Mercurial en un repositorio
+cuando tiene la extensión \hgext{inotify} habilitada, correrá casi con
+el mismo desempeño que una orden usual de Mercurial.  Esto es debido a
+que el estado del daemonio necesita aplicar una búsqueda normal sobre
+el estado para poder tener una línea de partida frente a la cual
+aplicar posteriormente actualizaciones del núcleo.  De todas formas,
+\emph{todo} comando posterior que haga cualquier clase de revisión del
+estado debería ser notablemente más rápido en repositorios con incluso
+un tamaño modesto.  Aún mejor, a medida que su repositorio sea más
+grande, mejor desempeño verá.  El daemonio \hgext{inotify} hace
+operaciones de estado de forma casi instantánea en repositorios de
+todos los tamaños!
+
+Si lo desea, puede iniciar manualmente un daemonio de estado con la orden
+\hgxcmd{inotify}{inserve}.  Esto le da un control un poco más fino
+acerca de cómo debería ejecutarse el daemonio.  Esta orden solamente
+estará disponible cuando haya habilitado la extensión \hgext{inotify}.
+
+Cuando esté usando la extensión \hgext{inotify},
+\emph{no debería ver diferencia} en el comportamiento de Mercurial,
+con la única excepción de que los comandos relacionados con el estado
+deberían ejectuarse mucho más rápido que como solían hacerlo.  Debería
+esperar específicamente que las órdenes no deberían ofrecer salidas
+distintas; ni ofrecer resultados diferentes.  Si alguna de estas
+situaciones ocurre, por favor reporte el fallo.
+
+\section{Soporte flexible de diff con la extensión \hgext{extdiff}}
+\label{sec:hgext:extdiff}
+
+La orden predeterminada \hgcmd{diff} de Mercurial despliega diffs en
+texto plano unificadas.
+\interaction{extdiff.diff}
+Si dese emplear una herramienta externa para desplegar las
+modificaciones, querrá usar la extensión \hgext{extdiff}.  Esta le
+permitirá usar por ejemplo una herramienta gráfica de diff.
+
+La extensión \hgext{extdiff} viene con Mercurial, y es fácil
+configurar.  En la sección \rcsection{extensions} de su \hgrc,
+basta con añadir una entrada de una línea para habilitar la extensión.
+\begin{codesample2}
+  [extensions]
+  extdiff =
+\end{codesample2}
+Esto introduce una orden llamada \hgxcmd{extdiff}{extdiff}, que de
+forma predeterminada usa su orden del sistema \command{diff} para
+generar un diff unificado de la misma forma que lo hace el comando
+predeterminado \hgcmd{diff}.
+\interaction{extdiff.extdiff}
+El resultado no será exactamente el mismo que con la orden interna
+\hgcmd{diff}, puesto que la salida de \command{diff} varía de un
+sistema a otro, incluso pasando las mismas opciones.
+
+Como lo indican las líneas``\texttt{making snapshot}'', la orden
+\hgxcmd{extdiff}{extdiff} funciona creando dos instantáneas de su
+árbol de fuentes.  La primera instantánea es la revisión fuente; la
+segunda es la revisión objetivo del directorio de trabajo.  La orden
+\hgxcmd{extdiff}{extdiff} genera estas instantáneas en un directorio
+temporal, pasa el nombre de cada directorio a un visor de diffs
+temporal y borra los directorios temporales.  Por cuestiones de
+eficiencia solamente genera instantáneas de los directorios y ficheros
+que han cambiado entre dos revisiones.
+
+Los nombres de los directorios de instantáneas tienen los mismos
+nombres base de su repositorio.  Si su repositorio tiene por ruta
+\dirname{/quux/bar/foo}, \dirname{foo} será el nombre de cada
+instantánea de directorio.  Cada instantánea de directorio tiene sus
+identificadores de conjuntos de cambios al final del nombre en caso de
+que sea apropiado.  Si una instantánea viene de la revisión
+\texttt{a631aca1083f}, el directorio se llamará
+\dirname{foo.a631aca1083f}.  Una instantánea del directorio de trabajo
+no tendrá el identificador del conjunto de cambios, y por lo tanto
+será solamente \dirname{foo} en este ejemplo.  Para ver cómo luce en
+la práctica, veamos de nuevo el ejemplo \hgxcmd{extdiff}{extdiff}
+antes mencionado.  Tenga en cuenta que los diffs tienen los nombres de
+las instantáneas de directorio dentro de su encabezado.
+
+La orden \hgxcmd{extdiff}{extdiff} acepta dos opciones importantes.
+La opción \hgxopt{extdiff}{extdiff}{-p} le permite elegir un programa
+para ver las diferencias, en lugar de \command{diff}.  Con la opción
+\hgxopt{extdiff}{extdiff}{-o} puede cambiar las opciones que
+\hgxcmd{extdiff}{extdiff} pasa a tal programa (de forma predeterminada
+las opciones son``\texttt{-Npru}'', que tienen sentido únicamente si
+está usando \command{diff}).  En otros aspectos, la orden
+\hgxcmd{extdiff}{extdiff} actúa de forma similar a como lo hace la
+orden \hgcmd{diff} de Mercurial: usted usa los mismos nombres de
+opciones, sintaxis y argumentos para especificar las revisiones y los
+ficheros que quiere, y así sucesivamente.
+
+Por ejemplo, para ejecutar la orden usual del sistema \command{diff},
+para lograr que se generen diferencias de contexto (con la opción
+\cmdopt{diff}{-c}) en lugar de diferencias unificadas, y cinco líneas
+de contexto en lugar de las tres predeterminadas (pasando \texttt{5}
+como argumento a la opción \cmdopt{diff}{-C}).
+\interaction{extdiff.extdiff-ctx}
+
+Es sencillo lanzar unas herramienta usual de diferencias.  Para lanzar
+el visor \command{kdiff3}:
+\begin{codesample2}
+  hg extdiff -p kdiff3 -o ''
+\end{codesample2}
+
+Si su orden para visualizar diferencias no puede tratar con
+directorios, puede usar un poco de scripting para lograrlo.  Un
+ejemplo de un script con la extensión \hgext{mq} junto con la orden
+\command{interdiff} está en la sección~\ref{mq-collab:tips:interdiff}.
+
+\subsection{Definición de alias de comandos}
+
+Acordarse de todas las opciones de las órdenes
+\hgxcmd{extdiff}{extdiff} y el visor de diferencias de su preferencia
+puede ser dispendioso, y por lo tanto la extensión \hgext{extdiff} le
+permite definir \emph{nuevas} órdenes que invocarán su visor de
+diferencias con las opciones exactas.
+
+Basta con editar su fichero \hgrc, y añadir una sección llamada
+\rcsection{extdiff}.  Dentro de esta sección puede definir varias
+órdenes. Mostraremos como añadir la orden \texttt{kdiff3}.  Después de
+definido, puede teclear ``\texttt{hg kdiff3}'' y la extensión a
+\hgext{extdiff} ejecutará la orden \command{kdiff3}.
+\begin{codesample2}
+  [extdiff]
+  cmd.kdiff3 =
+\end{codesample2}
+Si deja vacía la porción derecha de la definición, como en el ejemplo,
+la extensión \hgext{extdiff} usa el nombre de la orden se definirá
+como el nombre del programa externo a ejecutar.  Pero tales nombres no
+tienen por qué ser iguales.  Definimos ahora la orden llamada
+ ``\texttt{hg wibble}'', que ejecuta \command{kdiff3}.
+\begin{codesample2}
+  [extdiff]
+  cmd.wibble = kdiff3
+\end{codesample2}
+
+También puede especificar las opciones predeterminadas con las cuales
+desea invocar el visor de diferencias.  Se usa el prefijo ``\texttt{opts.}'',
+seguido por el nombre de la orden a la cual se aplican las opciones.
+En este ejemplos se define la orden ``\texttt{hg vimdiff}'' que
+ejecuta la extensión \texttt{DirDiff} del editor \command{vim}.
+\begin{codesample2}
+  [extdiff]  
+  cmd.vimdiff = vim
+  opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'
+\end{codesample2}
+
+\section{Uso de la extensión \hgext{transplant} para seleccionar}
+\label{sec:hgext:transplant}
+
+Need to have a long chat with Brendan about this.
+
+\section{Enviar cambios vía correo electrónico con la extensión \hgext{patchbomb}}
+\label{sec:hgext:patchbomb}
+
+Varios proyectos tienen la cultura de ``revisión de cambios'', en la
+cual la gente envía sus modificaciones a una lista de correo para que
+otros las lean y comenten antes de consignar la versión final a un
+repositorio compartido.  Algunos proyectos tienen personas que actúan
+como cancerberos; ellos aplican los cambios de otras personas a un
+repositorio para aquellos que no tienen acceso.
+
+Mercurial facilita enviar cambios por correo para revisión o
+aplicación gracias a su extensión \hgext{patchbomb}.  La extensión es
+tan popular porque los cambios se formatean como parches y es usual
+que se envía un conjunto de cambios por cada correo.  Enviar una gran
+cantidad de cambios por correos se llama por tanto ``bombardear'' el
+buzón de entrada del destinatario, de ahí su nombre ``bombardeo de
+parches''.
+
+Como es usual, la configuración básica de la extensión
+\hgext{patchbomb} consta de una o dos líneas en su \hgrc.
+\begin{codesample2}
+  [extensions]
+  patchbomb =
+\end{codesample2}
+Cuando haya habilitado la extensión, dispondrá de una nueva orden,
+llamada \hgxcmd{patchbomb}{email}.
+
+La forma mejor y más segura para invocar la orden
+\hgxcmd{patchbomb}{email} es ejecutarla \emph{siempre} con la opción
+\hgxopt{patchbomb}{email}{-n}; que le mostrará lo que la orden
+\emph{enviaría}, sin enviar nada.  Una vez que haya dado un vistazo a
+los cambios y verificado que está enviando los correctos, puede volver
+a ejecutar la misma orden, sin la opción \hgxopt{patchbomb}{email}{-n}.
+
+La orden \hgxcmd{patchbomb}{email} acepta la misma clase de sintaxis
+de revisiones como cualquier otra orden de Mercurial.  Por ejemplo,
+enviará todas las revisiones entre la 7 y la \texttt{punta}, inclusive.
+\begin{codesample2}
+  hg email -n 7:tip
+\end{codesample2}
+También puede especificar un \emph{repositorio} para comparar.  Si
+indica un repositoro sin revisiones, la orden \hgxcmd{patchbomb}{email}
+enviará todas las revisiones en el repositorio local que no están
+presentes en el repositorio remoto.  Si especifica revisiones
+adicionalmente o el nombre de una rama (la última con la opción
+\hgxopt{patchbomb}{email}{-b}), respetará las revisiones enviadas.
+
+Ejecutar la orden \hgxcmd{patchbomb}{email} sin los nombres de
+aquellas personas a las cuales desea enviar el correo es completamente
+seguro: si lo hace, solicitará tales valores de forma interactiva.
+(Si está usando Linux o un sistema tipo Unix, tendrá capacidades
+estilo--\texttt{readline} aumentadas cuando ingrese tales encabezados,
+lo cual es sumamente útil.)
+
+Cuando envíe una sola revisión, la orden \hgxcmd{patchbomb}{email}
+de forma predeterminada usará la primera línea de descripción del
+conjunto de cambios como el tema del único mensaje que se enviará.
+
+Si envía varias revisiones, la orden \hgxcmd{patchbomb}{email} enviará
+normalmente un mensaje por conjunto de cambios. Colocará como
+prefacio un mensaje introductorio en el cual usted debería describir
+el propósito de la serie de cambios que está enviando.
+
+\subsection{Cambiar el comportamiento de las bombas de parches}
+
+Cada proyecto tiene sus propias convenciones para enviar cambios en un
+correo electrónico; la extensión \hgext{patchbomb} intenta acomodarse
+a diferentes variaciones gracias a las opciones de la línea de órdenes:
+\begin{itemize}
+\item Puede escribir un tema para el mensaje introductorio en la línea
+  de órdenes con la opciń \hgxopt{patchbomb}{email}{-s}.  Toma un
+  argumento: el tema del mensaje a usar.
+\item Para cambiar el correo electrónico del campo del cual se
+  origina, use la opción \hgxopt{patchbomb}{email}{-f}.  Toma un
+  argumento, el correo electrónico a usar.
+\item El comportamiento predeterminado es enviar diferencias
+  unificadas (consulte la sección~\ref{sec:mq:patch} si desea una
+  descripción del formato), una por mensaje.  Puede enviar un conjunto
+  binario\ndt{binary bundle} con la opción \hgxopt{patchbomb}{email}{-b}.
+\item Las diferencias unificadas están precedidas por un encabezado de
+  metadatos.  Puede omitirlo, y enviar diferencias sin adornos con la
+  opción \hgxopt{patchbomb}{email}{--plain}.
+\item Las diferencias usualmente se envían ``en línea'', como parte
+  del cuerpo del mensaje con la descripción del parche.  Que facilita a
+  a la mayor cantidad de lectores citar y responder partes de un diff,
+  dado que algunos clientes de correo solamente citarán la primera
+  parte MIME del cuerpo de un mensaje.  Si prefiere enviar la
+  descripción y el diff en partes separadas del cuerpo, use la opción
+  \hgxopt{patchbomb}{email}{-a}.
+\item En lugar de enviar mensajes de correo puede escribirlos a un
+  fichero con formato-\texttt{mbox}- con la opción
+  \hgxopt{patchbomb}{email}{-m}.  La opción recibe un argumento, el
+  nombre del fichero en el cual escribir.
+\item Si desea añadir un resumen con formato-\command{diffstat} en
+  cada parche, y uno como mensaje introductorio, use la opción
+  \hgxopt{patchbomb}{email}{-d}.  La orden \command{diffstat}
+  despliega una tabla que contiene el nombre de cada fichero parchado,
+  el número de líneas afectadas, y un historgrama mostrando cuánto ha
+  sido modificado cada fichero.  Lo cual ofrece a los lectores una
+  mirada cuantitativa de cuan complejo es el parche.
+\end{itemize}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/hook.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1568 @@
+\chapter{Manejo de eventos en repositorios mediante ganchos}
+\label{chap:hook}
+
+Mercurial ofrece un poderoso mecanismo para permitirle a usted
+automatizar la ejecución de acciones en respuesta a eventos que
+ocurran en un repositorio. En algunos casos, usted puede controlar
+incluso la respuesta de Mercurial a dichos eventos.
+
+Mercurial usa el término \emph{gancho} para identificar estas
+acciones. Los ganchos son conocidos como ``disparadores'' en algunos
+sistemas de control de revisiones, pero los dos nombres se refieren al
+mismo concepto.
+
+\section{Vistazo general de ganchos en Mercurial}
+
+A continuación se encuentra una breve lista de los ganchos que
+Mercurial soporta. Volveremos a cada uno de estos ganchos con más
+detalle después, en la sección~\ref{sec:hook:ref}.
+
+\begin{itemize}
+\item[\small\hook{changegroup}] Es ejecutado luego de que un grupo de
+    conjuntos de cambios ha sido traído al repositorio desde algún
+    otro sitio.
+\item[\small\hook{commit}] Es ejecutado después de la creación de
+    un conjunto de cambios en el repositorio local.
+\item[\small\hook{incoming}] Es ejecutado una vez por cada conjunto de
+    cambios traído al repositorio desde otra ubicación. Note la
+    diferencia respecto al gancho \hook{changegroup}, que es ejecutado
+    una vez por cada \emph{grupo} de conjuntos de cambios que se
+    traiga.
+\item[\small\hook{outgoing}] Es ejecutado luego de que un grupo de
+    conjuntos de cambios ha sido transmitido desde el repositorio.
+\item[\small\hook{prechangegroup}] Es ejecutado antes de iniciar la
+    recepción de un grupo de conjuntos de cambios en el repositorio.
+\item[\small\hook{precommit}] De control. Es ejecutado antes de
+    iniciar una consignación.
+\item[\small\hook{preoutgoing}] De control. Es ejecutado antes de
+    iniciar la transmisión de un grupo de conjuntos de cambios desde
+    el repositorio.
+\item[\small\hook{pretag}] De control. Es ejecutado antes de crear una
+    etiqueta.
+\item[\small\hook{pretxnchangegroup}] De control. Es ejecutado después
+    de haber recibido un grupo de conjuntos de cambios en el
+    repositorio local, pero antes de que la transacción se complete y
+    los cambios sean permanentes dentro del repositorio.
+\item[\small\hook{pretxncommit}] De control. Es ejecutado luego de la
+    creación de un conjunto de cambios en el repositorio local, pero
+    antes de que la transacción que hace permanente el cambio sea
+    completada.
+\item[\small\hook{preupdate}] De control. Es ejecutado antes de
+    iniciar una actualización o fusión en el directorio de trabajo.
+\item[\small\hook{tag}] Es ejecutado después de la creación de una
+    etiqueta.
+\item[\small\hook{update}] Es ejecutado después de que termina una
+    actualización o una fusión.
+\end{itemize}
+Cada uno de los ganchos cuya descripción empieza con la frase
+``de control'' tiene la facultad de determinar si una actividad puede
+continuar. Si el gancho se ejecuta con éxito, la actividad puede
+continuar; si falla, o bien la actividad no es permitida, o se
+deshacen los cambios que se puedan haber llevado a cabo, dependiendo
+del gancho involucrado.
+
+\section{Ganchos y seguridad}
+
+\subsection{Los ganchos se ejecutan con sus privilegios de usuario}
+
+Cuando usted ejecuta un comando de Mercurial en un repositorio, y el
+comando causa la ejecución de un gancho, dicho gancho se ejecuta en
+\emph{su} sistema, en \emph{su} cuenta de usuario, con \emph{sus}
+privilegios. Ya que los ganchos son elementos arbitrarios de código
+ejecutable, usted debería tratarlos con un nivel adecuado de
+desconfianza. No instale un gancho a menos en que confíe en quien lo
+creó y en lo que el gancho hace.
+
+En algunos casos, usted puede estar expuesto a ganchos que usted no
+%TODO acá introduzco algo de texto por mi cuenta, por claridad
+instaló. Si usted usa Mercurial en un sistema extraño, tenga en cuenta
+que Mercurial ejecutará los ganchos definidos en el fichero \hgrc.
+
+Si está trabajando con un repositorio propiedad de otro usuario,
+Mercurial podrá ejecutar los ganchos definidos en el repositorio de
+dicho usuario, pero los ejecutará como ``usted''. Por ejemplo, si
+usted jala (\hgcmd{pull}) desde ese repositorio, y el
+\sfilename{.hg/hgrc} define un gancho saliente (\hook{outgoing}),
+dicho gancho se ejecuta bajo su cuenta de usuario, aun cuando usted no
+es el propietario del repositorio.
+
+\begin{note}
+  Esto sólo aplica si usted está jalando desde un repositorio en un
+  sistema de ficheros local o de red. Si está jalando a través de http
+  o ssh, cualquier gancho saliente (\hook{outgoing}) se ejecutará bajo
+  la cuenta que está ejecutando el proceso servidor, en el servidor.
+\end{note}
+
+XXX Para ver qué ganchos han sido definidos en un repositorio, use el
+comando \hgcmdargs{config}{hooks}. Si usted está trabajando en un
+repositorio, pero comunicándose con otro que no le pertenece
+(por ejemplo, usando \hgcmd{pull} o \hgcmd{incoming}), recuerde que
+los ganchos que debe considerar son los del otro repositorio, no los
+del suyo.
+
+\subsection{Los ganchos no se propagan}
+
+En Mercurial, no se hace control de revisiones de los ganchos, y no se
+propagan cuando usted clona, o jala de, un repositorio. El motivo para
+esto es simple: un gancho es código ejecutable arbitrario. Se ejecuta
+bajo su identidad, con su nivel de privilegios, en su máquina.
+
+Sería extremadamente descuidado de parte de cualquier sistema
+distribuido de control de revisiones el implementar control de
+revisiones para ganchos, ya que esto ofrecería maneras fácilmente
+%TODO subvertir
+aprovechables de subvertir las cuentas de los usuarios del sistema de
+control de revisiones.
+
+Ya que Mercurial no propaga los ganchos, si usted está colaborando con
+otras personas en un proyecto común, no debería asumir que ellos están
+usando los mismos ganchos para Mercurial que usted usa, o que los de
+ellos están configurado correctamente. Usted debería documentar los
+ganchos que usted espera que la gente use.
+
+En una intranet corporativa, esto es algo más fácil de manejar, ya que
+usted puede, por ejemplo, proveer una instalación ``estándar'' de
+Mercurial en un sistema de ficheros NFS, y usar un fichero \hgrc\
+global para definir los ganchos que verán todos los usuarios. Sin
+embargo, este enfoque tiene sus límites; vea más abajo.
+
+\subsection{Es posible hacer caso omiso de los ganchos}
+
+Mercurial le permite hacer caso omiso de la deficinión de un gancho,
+a través de la redefinición del mismo. Usted puede deshabilitar el
+gancho fijando su valor como una cadena vacía, o cambiar su
+comportamiento como desee.
+
+Si usted instala un fichero \hgrc\ a nivel de sistema o sitio completo
+que define algunos ganchos, debe entender que sus usuarios pueden
+deshabilitar o hacer caso omiso de los mismos.
+
+\subsection{Asegurarse de que ganchos críticos sean ejecutados}
+
+Algunas veces usted puede querer hacer respetar una política, y no
+permitir que los demás sean capaces de evitarla. Por ejemplo, usted
+puede tener como requerimiento que cada conjunto de cambios debe pasar
+un riguroso conjunto de pruebas. Definir este requerimientos a través
+de un gancho en un fichero \hgrc\ global no servirá con usuarios
+remotos en computadoras portátiles, y por supuesto que los usuarios
+locales pueden evitar esto a voluntad haciendo caso omiso del gancho.
+
+En vez de eso, usted puede definir las políticas para usar Mercurial
+de tal forma que se espere que los usuarios propaguen los cambios a
+través de un servidor ``canónico'' bien conocido que usted ha
+asegurado y configurado apropiadamente.
+
+Una manera de hacer esto es a través de una combinación de ingeniería
+social y tecnología. Cree una cuenta de acceso restringido; los
+usuarios pueden empujar cambios a través de la red a los repositorios
+administrados por esta cuenta, pero no podrán ingresar a dicha cuenta
+para ejecutar órdenes en el intérprete de comandos. En este escenario,
+un usuario puede enviar un conjunto de cambios que contenga la
+porquería que él desee.
+
+Cuando alguien empuja un conjunto de cambios al servidor del que todos
+jalan, el servidor probará el conjunto de cambios antes de aceptarlo
+como permanente, y lo rechazará si no logra pasar el conjunto de
+pruebas. Si la gente sólo jala cambios desde este servidor de filtro,
+servirá para asegurarse de que todos los cambios que la gente jala han
+sido examinados automáticamente
+
+\section{Precauciones con ganchos \texttt{pretxn} en un repositorio de
+acceso compartido}
+
+Si usted desea usar ganchos para llevar a cabo automáticamente algún
+trabajo en un repositorio al que varias personas tienen acceso
+compartido, debe tener cuidado con la forma de hacerlo.
+
+Mercurial sólo bloquea un repositorio cuando está escribiendo al
+mismo, y sólo las partes de Mercurial que escriben al repositorio le
+prestan atención a los bloqueos. Los bloqueos de escritura son
+necesarios para evitar que múltiples escritores simultáneos
+interfieran entre sí, corrompiendo el repositorio.
+
+Ya que Mercurial tiene cuidado con el orden en que lee y escribe
+datos, no necesita adquirir un bloqueo cuando desea leer datos del
+repositorio. Las partes de Mercurial que leen del repositorio nunca le
+prestan atención a los bloqueos. Este esquema de lectura libre de
+bloqueos incremententa en gran medida el desempeño y la concurrencia.
+
+Sin embargo, para tener un gran desempeño es necesario hacer
+sacrificios, uno de los cuales tiene el potencial de causarle
+problemas a menos de que usted esté consciente de él. Describirlo
+requiere algo de detalle respecto a cómo Mercurial añade conjuntos de
+cambios al repositorio y cómo lee esos cambios de vuelta.
+
+Cuando Mercurial \emph{escribe} metadatos, los escribe directamente en
+el fichero de destino. Primero escribe los datos del fichero, luego
+los datos del manifiesto (que contienen punteros a los nuevos datos
+del fichero), luego datos de la bitácora de cambios (que contienen
+punteros a los nuevos datos del manifiesto). Antes de la primera
+escritura a cada fichero, se guarda un registro de dónde estaba el
+final de fichero en su registro de transacciones. Si la transacción
+debe ser deshecha, Mercurial simplemente trunca cada fichero de vuelta
+al tamaño que tenía antes de que empezara la transacción.
+
+Cuando Mercurial \emph{lee} metadatos, lee la bitácora de cambios
+primero, y luego todo lo demás. Como un lector sólo accederá a las
+partes del manifiesto o de los metadatos de fichero que él puede ver
+en la bitácora de cambios, nunca puede ver datos parcialmente
+escritos.
+
+Algunos ganchos de control (\hook{pretxncommit} y
+\hook{pretxnchangegroup}) se ejecutan cuando una transacción está casi
+completa. Todos los metadatos han sido escritos, pero Mercurial aún
+puede deshacer la transacción y hacer que los datos recién escritos
+desaparezcan.
+
+Si alguno de estos ganchos permanece en ejecución por mucho tiempo,
+abre una ventana de tiempo en la que un lector puede ver los metadatos
+de conjuntos de cambios que aún no son permanentes y que no debería
+considerarse que estén ``realmante ahí''. Entre más tiempo tome la
+ejecución del gancho, más tiempo estará abierta esta ventana.
+
+\subsection{Ilustración del problema}
+
+En principio, un buen uso del gancho \hook{pretxnchangegroup} sería
+ensamblar y probar automáticamente todos los cambios entrantes antes
+de que sean aceptados en un repositorio central. Esto le permitiría a
+usted garantizar que nadie pueda empujar cambios que ``rompan el
+ensamblaje''. Pero si un cliente puede jalar cambios mientras están
+siendo probados, la utilidad de esta prueba es nula; alguien confiado
+puede jalar cambios sin probar, lo que potencialmente podría romper su
+proceso de ensamblaje.
+
+La respuesta técnica más segura frente a este retos es montar dicho
+repositorio ``guardián'' como \emph{unidireccional}. Permita que
+reciba cambios desde el exterior, pero no permita que nadie jale
+cambios de él (use el gancho \hook{preoutgoing} para bloquear esto).
+Configure un gancho \hook{changegroup} para que si el ensamblaje o
+prueba tiene éxito, el gancho empuje los nuevos cambios a otro
+repositorio del que la gente \emph{pueda} jalar.
+
+En la práctica, montar un cuello de botella centralizado como éste a
+menudo no es una buena idea, y la visibilidad de las transacciones no
+tiene nada que ver con el problema. A medida que el tamaño de un
+proyecto---y el tiempo que toma ensamblarlo y probarlo---crece, usted
+se acerca rápidamente a un límite con este enfoque ``pruebe antes de
+comprar'', en el que tiene más conjuntos de cambios a probar que
+tiempo para ocuparse de ellos. El resultado inevitable es frustración
+para todos los que estén involucrados.
+
+Una aproximación que permite manejar mejor el crecimiento es hacer que
+la gente ensamble y pruebe antes de empujar, y ejecutar el ensamble y
+pruebas automáticas centralmente \emph{después} de empujar, para
+asegurarse de que todo esté bien. La ventaja de este enfoque es que no
+impone un límite a la rata en la que un repositorio puede aceptar
+cambios.
+
+\section{Tutorial corto de uso de ganchos}
+\label{sec:hook:simple}
+
+Escribir un gancho para Mercurial es fácil. Empecemos con un gancho
+que se ejecute cuando usted termine un \hgcmd{commit}, y simplemente
+muestre el hash del conjunto de cambios que usted acaba de crear. El
+gancho se llamará \hook{commit}.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.init}
+  \caption{Un gancho simple que se ejecuta al hacer la consignación de
+  un conjunto de cambios}
+  \label{ex:hook:init}
+\end{figure}
+
+Todos los ganchos siguen el patrón del ejemplo~\ref{ex:hook:init}.
+Usted puede añadir una entrada a la sección \rcsection{hooks} de su
+fichero \hgrc.  A la izquierda está el nombre del evento respecto al
+cual dispararse; a la derecha está la acción a llevar a cabo. Como
+puede ver, es posible ejecutar cualquier orden de la línea de comandos
+en un gancho. Mercurial le pasa información extra al gancho usando
+variables de entorno (busque \envar{HG\_NODE} en el ejemplo).
+
+\subsection{Llevar a cabo varias acciones por evento}
+
+A menudo, usted querrá definir más de un gancho para un tipo de evento
+particular, como se muestra en el ejemplo~\ref{ex:hook:ext}. 
+Mercurial le permite hacer esto añadiendo una \emph{extensión} al
+final del nombre de un gancho. Usted extiende el nombre del gancho
+%TODO Yuk, no me gusta ese "parada completa"
+poniendo el nombre del gancho, seguido por una parada completa (el
+caracter ``\texttt{.}''), seguido de algo más de texto de su elección.
+Por ejemplo, Mercurial ejecutará tanto \texttt{commit.foo} como
+\texttt{commit.bar} cuando ocurra el evento \texttt{commit}.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.ext}
+  \caption{Definición de un segundo gancho \hook{commit}}
+  \label{ex:hook:ext}
+\end{figure}
+
+Para dar un orden bien definido de ejecución cuando hay múltiples
+ganchos definidos para un evento, Mercurial ordena los ganchos de
+acuerdo a su extensión, y los ejecuta en dicho orden. En el ejemplo de
+arribam \texttt{commit.bar} se ejecutará antes que
+\texttt{commit.foo}, y \texttt{commit} se ejecutará antes de ambos.
+
+Es una buena idea usar una extensión descriptiva cuando usted define
+un gancho. Esto le ayudará a recordar para qué se usa el gancho. Si el
+gancho falla, usted recibirá un mensaje de error que contiene el
+nombre y la extensión del gancho, así que usar una extensión
+descriptiva le dará una pista inmediata de porqué el gancho falló (vea
+un ejemplo en la sección~\ref{sec:hook:perm}).
+
+\subsection{Controlar cuándo puede llevarse a cabo una actividad}
+\label{sec:hook:perm}
+
+En los ejemplos anteriores, usamos el gancho \hook{commit}, que es
+ejecutado después de que se ha completado una consignación. Este es
+uno de los varios ganchos que Mercurial ejecuta luego de que una
+actividad termina. Tales ganchos no tienen forma de influenciar la
+actividad como tal.
+
+Mercurial define un número de eventos que ocurren antes de que una
+actividad empiece; o luego de que empiece, pero antes de que termine.
+Los ganchos que se disparan con estos eventos tienen la capacidad
+adicional de elegir si la actividad puede continuar, o si su ejecución
+es abortada.
+
+El gancho \hook{pretxncommit} se ejecuta justo antes de que una
+consignación se ejecute. En otras palabras, los metadatos que
+representan el conjunto de cambios han sido escritos al disco, pero no
+se ha terminado la transacción. El gancho \hook{pretxncommit} tiene la
+capacidad de decidir si una transacción se completa, o debe
+deshacerse.
+
+Si el gancho \hook{pretxncommit} termina con un código de salida de
+cero, se permite que la transacción se complete; la consignación
+termina; y el gancho \hook{commit} es ejecutado. Si el gancho
+\hook{pretxncommit} termina con un código de salida diferente de cero,
+la transacción es revertida; los metadatos representando el conjunto
+de cambios son borrados; y el gancho \hook{commit} no es ejecutado.
+
+\begin{figure}[ht]
+  \interaction{hook.simple.pretxncommit}
+  \caption{Uso del gancho \hook{pretxncommit} para controlar consignaciones}
+  \label{ex:hook:pretxncommit}
+\end{figure}
+
+El gancho en el ejemplo~\ref{ex:hook:pretxncommit} revisa si el
+mensaje de consignación contiene el ID de algún fallo. Si lo contiene,
+la consignación puede continuar. Si no, la consignación es cancelada.
+
+\section{Escribir sus propios ganchos}
+
+Cuando usted escriba un gancho, puede encontrar útil el ejecutar
+Mercurial o bien pasándole la opción \hggopt{-v}, o con el valor de
+configuración \rcitem{ui}{verbose} fijado en ``true'' (verdadero).
+Cuando lo haga, Mercurial imprimirá un mensaje antes de llamar cada
+gancho.
+
+\subsection{Escoger cómo debe ejecutarse su gancho}
+\label{sec:hook:lang}
+
+Usted puede escribir un gancho que funcione como un programa normal
+---típicamente un guión de línea de comandos---o como una función de
+Python que se ejecuta dentro del proceso Mercurial.
+
+Escribir un gancho como un programa externo tiene la ventaja de que no
+requiere ningún conocimiento del funcionamiento interno de Mercurial.
+Usted puede ejecutar comandos Mercurial normales para obtener la
+informción extra que pueda necesitar. La contraparte de esto es que
+los ganchos externos son más lentos que los ganchos internos
+ejecutados dentro del proceso.
+
+Un gancho Python interno tiene acceso completo a la API de Mercurial,
+y no se ``externaliza'' a otro proceso, así que es inherentemente más
+rápido que un gancho externo. Adicionalmente es más fácil obtener la
+mayoría de la información que un gancho requiere a través de llamadas
+directas a la API de Mercurial que hacerlo ejecutando comandos
+Mercurial.
+
+Si se siente a gusto con Python, o requiere un alto desempeño,
+escribir sus ganchos en Python puede ser una buena elección. Sin
+embargo, cuando usted tiene un gancho bastante directo por escribir y
+no le importa el desempeño (el caso de la mayoría de los ganchos), es
+perfectamente admisible un guión de línea de comandos.
+
+\subsection{Parámetros para ganchos}
+\label{sec:hook:param}
+
+Mercurial llama cada gancho con un conjunto de paŕametros bien
+definidos. En Python, un parámetro se pasa como argumento de palabra
+clave a su función de gancho. Para un programa externo, los parámetros
+son pasados como variables de entornos.
+
+Sin importar si su gancho está escrito en Python o como guión de línea
+de comandos, los nombres y valores de los parámetros específicos de
+los ganchos serán los mismos. Un parámetro booleano será representado
+como un valor booleano en Python, pero como el número 1 (para
+``verdadero'') o 0 (para falso) en una variable de entorno para un
+gancho externo. Si un parámetro se llama \texttt{foo}, el argumento de
+palabra clave para un gancho en Python también se llamará
+\texttt{foo}, mientras que la variable de entorno para un gancho
+externo se llamará \texttt{HG\_FOO}.
+
+\subsection{Valores de retorno de ganchos y control de actividades}
+
+Un gancho que se ejecuta exitosamente debe terminar con un código de
+salida de cero, si es externo, o retornar el valor booleano
+``falso'', si es interno. Un fallo se indica con un código de salida
+diferente de cero desde un gancho externo, o un valor de retorno
+booleano ``verdadero''. Si un gancho interno genera una excepción, se
+considera que el gancho ha fallado.
+
+Para los ganchos que controlan si una actividad puede continuar o no,
+cero/falso quiere decir ``permitir'', mientras que
+% TODO me suena mejor "no permitir" que "denegar"
+no-cero/verdadero/excepción quiere decir ``no permitir''.
+
+\subsection{Escribir un gancho externo}
+
+Cuando usted define un gancho externo en su fichero \hgrc\ y el mismo
+es ejecutado, dicha definición pasa a su intérprete de comandos, que
+hace la interpretación correspondiente. Esto significa que usted puede
+usar elementos normales del intérprete en el cuerpo del gancho.
+
+Un gancho ejecutable siempre es ejecutado con su directorio actual
+fijado al directorio raíz del repositorio.
+
+Cada parámetro para el gancho es pasado como una variable de entorno;
+el nombre está en mayúsculas, y tiene como prefijo la cadena
+``\texttt{HG\_}''.
+
+Con la excepción de los parámetros para los ganchos, Mercurial no
+define o modifica ninguna variable de entorno al ejecutar un gancho.
+Es útil recordar esto al escribir un gancho global que podría ser
+ejecutado por varios usuarios con distintas variables de entorno
+fijadas. En situaciones con múltiples usuarios, usted no debería
+asumir la existencia de ninguna variable de entorno, ni que sus
+valores sean los mismos que tenían cuando usted probó el gancho en su
+ambiente de trabajo.
+
+\subsection{Indicar a Mercurial que use un gancho interno}
+
+La sintaxis para definir un gancho interno en el fichero \hgrc\ es
+ligeramente diferente de la usada para un gancho externo. El valor del
+gancho debe comenzar con el texto ``\texttt{python:}'', y continuar
+con el nombre completamente cualificado de un objeto invocable que se
+usará como el valor del gancho.
+
+El módulo en que vive un gancho es importado automáticamente cuando se
+ejecuta un gancho. Siempre que usted tenga el nombre del módulo y la
+variable de entorno \envar{PYTHONPATH} ajustada adecuadamente, todo
+debería funcionar sin problemas.
+
+El siguiente fragmento de ejemplo de un fichero \hgrc\ ilustra la
+sintaxis y significado de los conceptos que acabamos de describir.
+\begin{codesample2}
+  [hooks]
+  commit.example = python:mymodule.submodule.myhook
+\end{codesample2}
+Cuando Mercurial ejecuta el gancho \texttt{commit.example}, importa 
+\texttt{mymodule.submodule}, busca el objeto invocable llamado
+\texttt{myhook}, y lo invoca (llama).
+
+\subsection{Escribir un gancho interno}
+
+El gancho interno más sencillo no hace nada, pero ilustra la
+estructura básica de la API\ndt{\emph{Application Progamming
+Interface}, Interfaz para Programación de Aplicaciones} para ganchos:
+\begin{codesample2}
+  def myhook(ui, repo, **kwargs):
+      pass
+\end{codesample2}
+El primer argumento para un gancho Python siempre es un objeto
+\pymodclass{mercurial.ui}{ui}.  El segundo es un objeto repositorio;
+de momento, siempre es una instancia de 
+\pymodclass{mercurial.localrepo}{localrepository}.  Después de estos
+dos argumentos están los argumentos de palabra clave. Los argumentos
+que se pasen dependerán del tipo de gancho que se esté llamando, pero
+un gancho siempre puede ignorar los argumentos que no le interesen,
+relegándolos a un diccionario de argumentos por palabras clave, como se
+hizo arriba con \texttt{**kwargs}.
+
+\section{Ejemplos de ganchos}
+
+\subsection{Escribir mensajes de consignación significativos}
+
+Es difícil de imaginar un mensaje de consignación útil y al mismo
+tiempo muy corto. El simple gancho \hook{pretxncommit} de la
+figura~\ref{ex:hook:msglen.go} evitará que usted consigne un conjunto
+de cambios con un mensaje de menos de 10 bytes de longitud.
+
+\begin{figure}[ht]
+  \interaction{hook.msglen.go}
+  \caption{Un gancho que prohíbe mensajes de consignación demasiado
+  cortos}
+  \label{ex:hook:msglen.go}
+\end{figure}
+
+\subsection{Comprobar espacios en blanco finales}
+
+Un uso interesante para ganchos relacionados con consignaciones es
+ayudarle a escribir código más limpio. Un ejemplo simple de
+%TODO dictum => regla
+``código más limpio'' es la regla de que un cambio no debe añadir
+líneas de texto que contengan ``espacios en blanco finales''. El
+espacio en blanco final es una serie de caracteres de espacio y
+tabulación que se encuentran al final de una línea de texto. En la
+mayoría de los casos, el espacio en blanco final es innecesario, ruido
+invisible, pero ocasionalmente es problemático, y la gente en general
+prefiere deshacerse de él.
+
+Usted puede usar cualquiera de los ganchos \hook{precommit} o
+\hook{pretxncommit} para revisar si tiene el problema de los espacios
+en blanco finales. Si usa el gancho \hook{precommit}, el gancho no
+sabrá qué ficheros se están consignando, por lo que se tendrá que
+revisar cada fichero modificado en el repositorio para ver si tiene
+espacios en blanco finales. Si usted sólo quiere consignar un cambio
+al fichero \filename{foo}, y el fichero \filename{bar} contiene
+espacios en blanco finales, hacer la revisión en el gancho
+\hook{precommit} evitará que usted haga la consignación de
+\filename{foo} debido al problem en \filename{bar}.  Este no parece el
+enfoque adeucado.
+
+Si usted escogiera el gancho \hook{pretxncommit}, la revisión no
+ocurriría sino hasta justo antes de que la transacción para la
+consignación se complete. Esto le permitirá comprobar por posibles
+problemas sólo en los ficheros que serán consignados. Sin embargo, si
+usted ingresó el mensaje de consignación de manera interactiva y el
+%TODO roll-back
+gancho falla, la transacción será deshecha; usted tendrá que
+reingresar el mensaje de consignación luego de que corrija el problema
+con los espacios en blanco finales y ejecute \hgcmd{commit} de nuevo.
+
+\begin{figure}[ht]
+  \interaction{hook.ws.simple}
+  \caption{Un gancho simple que revisa si hay espacios en blanco
+  finales}
+  \label{ex:hook:ws.simple}
+\end{figure}
+
+La figura~\ref{ex:hook:ws.simple} presenta un gancho
+\hook{pretxncommit} simple que comprueba la existencia de espacios en
+blanco finales. Este gancho es corto, pero no brinda mucha ayuda.
+Termina con un código de salida de error si un cambio añade una línea
+con espacio en blanco final a cualquier fichero, pero no muestra
+ninguna información que pueda ser útil para identificar el fichero o
+la línea de texto origen del problema. También tiene la agradable
+propiedad de no prestar atención a las líneas que no sufrieron
+modificaciones; sólo las líneas que introducen nuevos espacios en
+blanco finales causan problemas.
+
+\begin{figure}[ht]
+  \interaction{hook.ws.better}
+  \caption{Un mejor gancho para espacios en blanco finales}
+  \label{ex:hook:ws.better}
+\end{figure}
+
+El ejemplo de la figura~\ref{ex:hook:ws.better} es mucho más complejo,
+pero también más útil. El gancho procesa un diff unificado para
+revisar si alguna línea añade espacios en blanco finales, e imprime el
+nombre del fichero y el número de línea de cada ocurrencia. Aún mejor,
+si el cambio añade espacios en blanco finales, este gancho guarda el
+mensaje de consignación e imprime el nombre del fichero en el que el
+mensaje fue guardado, antes de terminar e indicarle a Mercurial que
+deshaga la transacción, para que uste pueda usar
+\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{nombre\_fichero}} para
+reutilizar el mensaje de consignación guardado anteriormente, una vez
+usted haya corregido el problema.
+
+Como anotación final, note en la figura~\ref{ex:hook:ws.better} el
+%TODO on-site => in-situ ?
+uso de la característica de edición \emph{in-situ} de \command{perl}
+para eliminar los espacios en blanco finales en un fichero. Esto es
+lo suficientemente conciso y poderoso para que lo presente aquí.
+% TODO corregí el backslash, y comprobé por mi cuenta un archivo
+% aparte, y el comando hace lo que debe hacer. Favor copiar del pdf el
+% comando perl y comprobar con un archivo con espacios en blanco
+% finales, y si todo está bien (que debería), borrar esta nota
+\begin{codesample2}
+    perl -pi -e 's,\textbackslash{}s+\$,,' nombre\_fichero
+\end{codesample2}
+
+\section{Ganchos adicionales}
+
+Mercurial se instala con varios ganchos adicionales. Usted puede
+encontrarlos en el directorio \dirname{hgext} del árbol de ficheros
+fuente de Mercurial. Si usted está usando un paquete binario de
+Mercurial, los ganchos estarán ubicados en el directorio
+\dirname{hgext} en donde su instalador de paquetes haya puesto a
+Mercurial.
+
+\subsection{\hgext{acl}---control de acceso a partes de un repositorio}
+
+La extensión \hgext{acl} le permite controlar a qué usuarios remotos
+les está permitido empujar conjuntos de cambios a un servidor en red.
+Usted puede proteger cualquier porción de un repositorio (incluyendo
+el repositorio completo), de tal manera que un usuario remoto
+específico pueda empujar cambios que no afecten la porción protegida.
+
+Esta extensión implementa control de acceso basado en la identidad del
+usuario que empuja los conjuntos de cambios, \emph{no} en la identidad
+de quien hizo la consignación de los mismos. Usar este gancho tiene
+sentido sólo si se tiene un servidor adecuadamente asegurado que
+autentique a los usuarios remotos, y si usted desea segurarse de que
+sólo se le permita a ciertos usuarios empujar cambios a dicho
+servidor.
+
+\subsubsection{Configuración del gancho \hook{acl}}
+
+Para administrar los conjuntos de cambios entrantes, se debe usar el
+gancho \hgext{acl} como un gancho de tipo \hook{pretxnchangegroup}.
+Esto le permite ver qué ficheros son modificados por cada conjunto de
+%TODO rollback => "deshacer el efecto"
+cambios entrante, y deshacer el efecto de un grupo de conjuntos de
+cambios si alguno de ellos modifica algún fichero ``prohibido''.
+Ejemplo:
+\begin{codesample2}
+  [hooks]
+  pretxnchangegroup.acl = python:hgext.acl.hook
+\end{codesample2}
+
+La extensión \hgext{acl} es configurada mediante tres secciones.
+
+La sección \rcsection{acl} sólo tiene una entrada,
+\rcitem{acl}{sources}\ndt{Fuentes.}, que lista las fuentes de los
+conjuntos de cambios entrantes a las que el gancho debe prestar
+atención. Usualmente usted no necesita configurar esta sección.
+\begin{itemize}
+  \item[\rcitem{acl}{serve}] Controlar conjuntos de
+    cambios entrantes que están llegando desde un repositorio a
+    través de http o ssh. Este es el valor por defecto de
+  \rcitem{acl}{sources}, y usualmente es el único valor de
+  configuración que necesitará para este ítem.
+\item[\rcitem{acl}{pull}] Controlar conjuntos de cambios entrantes que
+  lleguen vía un pull (jalado) desde un repositorio local.
+\item[\rcitem{acl}{push}] Controlar conjuntos de cambios entrantes que
+  lleguen vía un push (empuje) desde un repositorio local.
+\item[\rcitem{acl}{bundle}] Controlar conjuntos de cambios entrantes
+    %TODO bundle
+  que lleguen desde otro repositorio a través de un paquete.
+\end{itemize}
+
+La sección \rcsection{acl.allow} controla los usuarios a los que les
+está permitido añadir conjuntos de cambios al repositorio. Si esta
+sección no está presente, se le permite acceso a todos los usuarios
+excepto  a los que se les haya negado explícitamente el acceso. Si
+esta sección no está presente, se niega el acceso a todos los usuarios
+excepto a todos a los que se les haya permitido de manera explícita
+(así que una sección vacía implica que se niega el acceso a todos los
+usuarios).
+
+La sección \rcsection{acl.deny} determina a qué usuarios no se les
+permite añadir conjuntos de cambios al repositorio. Si esta sección no
+está presente o está vacía, no se niega el acceso a ningún usuario.
+
+La sintaxis para los ficheros \rcsection{acl.allow} y
+\rcsection{acl.deny} es idéntica. A la izquierda de cada entrada se
+encuentra un patrón glob que asocia ficheros o directorios, respecto a
+la raíz del repositorio; a la derecha, un nombre usuario.
+
+En el siguiente ejemplo, el usuario \texttt{escritordoc} sólo puede
+empujar cambios al directorio \dirname{docs} del repositorio, mientras
+que \texttt{practicante} puede enviar cambios a cualquier fichero o
+directorio excepto \dirname{fuentes/sensitivo}.
+\begin{codesample2}
+  [acl.allow]
+  docs/** = escritordoc
+
+  [acl.deny]
+  fuentes/sensitivo/** = practicante
+\end{codesample2}
+
+\subsubsection{Pruebas y resolución de problemas}
+
+Si usted desea probar el gancho \hgext{acl}, ejecútelo habilitando la
+opción de salida de depuración habilitada. Ya que usted probablemente
+lo estará ejecutando en un servidor donde no es conveniente (o incluso
+posible) pasar la opción \hggopt{--debug}, no olvide que usted puede
+habilitar la salida de depuración en su \hgrc:
+\begin{codesample2}
+  [ui]
+  debug = true
+\end{codesample2}
+Con esto habilitado, el gancho \hgext{acl} imprimirá suficiente
+información para permitirle saber porqué está permitiendo o denegando
+la operación de empujar a usuarios específicos.
+
+\subsection{\hgext{bugzilla}---integración con Bugzilla}
+
+La extensión \hgext{bugzilla} añade un comentario a un fallo Bugzilla
+siempre que encuentre una referencia al ID de dicho fallo en un
+mensaje de consignación. Usted puede instalar este gancho en un
+servidor compartido, para que cada vez que un usuario remoto empuje
+cambios al servidor, el gancho sea ejecutado.
+
+Se añade un comentario al fallo que se ve así (usted puede configurar
+los contenidos del comentario---vea más abajo):
+%TODO traducir?
+\begin{codesample2}
+  Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
+  the frobnitz repository, refers to this bug.
+
+  For complete details, see
+  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a
+
+  Changeset description:
+        Fix bug 10483 by guarding against some NULL pointers
+\end{codesample2}
+El valor de este gancho se encuentra en que automatiza el proceso de
+actualizar un fallo cuando un conjunto de cambios se refiera a él. Si
+usted configura este gancho adecuadamente, hará fácil para la gente
+navegar directamente desde un fallo Bugzilla a un conjunto de cambios
+que se refiere a ese fallo.
+
+Usted puede usar el código de este gancho como un punto de partida
+para otras recetas de integración con Bugzilla aún más exóticas. Acá
+hay algunas posibilidades:
+\begin{itemize}
+\item Requerir que cada conjunto de cambios tenga un ID de fallo en su
+  mensaje de consignación. En este caso, usted querrá configurar el
+  gancho como uno de tipo \hook{pretxncommit}.  Esto le permitirá al
+  gancho rechazar cambios que no contiene IDs de fallos.
+\item Permitir a los conjuntos de cambios entrantes modificar
+  automáticamente el \emph{estado} de un fallo, así como simplemente
+  añadir un comentario. Por ejemplo, el gancho podría reconocer la
+  cadena ``corregido fallo 31337'' como la señal de que debería
+  actualizar el estado del fallo 31337 a ``requiere pruebas''.
+\end{itemize}
+
+\subsubsection{Configuración del gancho \hook{bugzilla}}
+\label{sec:hook:bugzilla:config}
+
+Usted debería configurar este gancho en el \hgrc\ de su servidor como
+un gancho \hook{incoming}\ndt{Entrante.}, por ejemplo como sigue:
+\begin{codesample2}
+  [hooks]
+  incoming.bugzilla = python:hgext.bugzilla.hook
+\end{codesample2}
+
+Debido a la naturaleza especializada de este gancho, y porque Bugzilla
+no fue escrito con este tipo de integración en mente, configurar este
+% TODO involved => complejo ? no intarwebs here :(
+gancho es un proceso algo complejo.
+
+Antes de empezar, usted debe instalar la interfaz de Python para MySQL
+en los sistemas en los que se vaya a ejecutar el gancho. Si no está
+disponible como paquete binario para su sistema, usted puede descargar
+el paquete desde~\cite{web:mysql-python}.
+
+La información para configurar este gancho se ubica en la sección 
+\rcsection{bugzilla} de su \hgrc.
+\begin{itemize}
+\item[\rcitem{bugzilla}{version}] La versión de Bugzilla instalada en
+  el servidor. El esquema de base de datos que Bugzilla usa cambia
+  ocasionalmente, así que este gancho debe saber exactamente qué
+  esquema usar. A la fecha, la única versión soportada es la
+  \texttt{2.16}.
+\item[\rcitem{bugzilla}{host}] El nombre de máquina (\emph{hostname})
+  del servidor MySQL que almacena sus datos Bugzilla. La base de datos
+  debe ser configurada para permitir conexiones desde las máquinas en
+  las que usted ejecute el gancho \hook{bugzilla}.
+\item[\rcitem{bugzilla}{user}] El nombre de usuario que se usará para
+  conectarse al servidor MySQL. La base de datos debe ser configurada
+  para permitir a dicho usuario conectarse desde cualquiera de las
+  máquinas en las que se ejecute el gancho \hook{bugzilla}.  Este
+  usuario debe tener acceso y poder modificar las tablas de Bugzilla.
+  El valor por defecto para este ítem es \texttt{bugs}, que es el
+  nombre estándar del usuario para Bugzilla en una base de datos
+  MySQL.
+\item[\rcitem{bugzilla}{password}] La contraseña MySQL para el usuario
+  configurado anteriormente. Ésta es almacenada como texto plano, así
+  que usted deberá asegurarse de que los usuarios no autorizados no
+  puedan leer el fichero \hgrc\ en donde usted guarda esta
+  información.
+\item[\rcitem{bugzilla}{db}] El nombre de la base de datos Bugzilla en
+  el servidor MySQL. El nombre por defecto para este ítem es
+  \texttt{bugs}, que es el nombre estándar de la base de datos MySQL
+  en donde Bugzilla almacena sus datos.
+\item[\rcitem{bugzilla}{notify}] Si usted desea que Bugzilla envíe un
+    %TODO suBscriptores?
+  correo de notificación a los suscriptores después de que el gancho
+  haya añadido un comentario a un fallo, necesitará que este gancho
+  ejecute un comando siempre que actualice la base de datos. El
+  comando que se ejecute depende de en dónde haya sido instalado
+  Bugzilla, pero típicamente se verá así, si usted ha instalado
+  Bugzilla en \dirname{/var/www/html/bugzilla}:
+  \begin{codesample4}
+    cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
+  \end{codesample4}
+  El programa \texttt{processmail} de Bugzilla espera recibir un ID de
+  fallo (el gancho reemplaza ``\texttt{\%s}'' por el ID del fallo) y
+  una dirección de correo. También espera poder escribir a ciertos
+  ficheros en el directorio en que se ejecuta. Si Bugzilla y éste
+  gancho no están instalados en la misma máquina, usted deberá
+  encontrar una manera de ejecutar \texttt{processmail} en el servidor
+  donde está instalado Bugzilla.
+\end{itemize}
+
+\subsubsection{Asociar nombres de consignadores a nombres de usuario
+Bugzilla}
+
+Por defecto, el gancho \hgext{bugzilla} trata de usar la dirección de
+correo electrónico de la persona que hizo la consignación del conjunto
+de cambios como el nombre de usuario Bugzilla con el cual debe
+actualizar el fallo. Si esto no se ajusta a sus necesidades, es
+posible asociar direcciones de correo a nombres de usuario Bugzilla
+usando una sección \rcsection{usermap}.
+
+Cada ítem en la sección \rcsection{usermap} contiene una dirección de
+correo electrónico a la izquierda, y un nombre de usuario Bugzilla a
+la derecha.
+\begin{codesample2}
+  [usermap]
+  jane.user@example.com = jane
+\end{codesample2}
+Usted puede mantener los datos de \rcsection{usermap} en un fichero
+\hgrc, o decirle al gancho \hgext{bugzilla} que lea la información
+desde un fichero \filename{usermap} externo.  En este caso, usted
+puede almacenar los datos de \filename{usermap} en (por ejemplo) un
+repositorio modificable por los usuarios. Esto hace posible para sus
+usuarios mantener sus propias entradas \rcitem{bugzilla}{usermap}.  El
+fichero \hgrc\ principal se vería así:
+\begin{codesample2}
+  # fichero hgrc normal se refiere a un fichero usermap externo
+  [bugzilla]
+  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
+\end{codesample2}
+Mientras que el fichero \filename{usermap} al que se hace referencia
+se vería así:
+\begin{codesample2}
+  # bugzilla-usermap.conf - dentro de un repositorio hg
+  [usermap]
+  stephanie@example.com = steph
+\end{codesample2}
+
+\subsubsection{Configurar el texto que se añade a un fallo}
+
+Usted puede configurar el texto que este gancho añade como comentario;
+usted los especifica como una plantilla Mercurial. Varias entradas
+\hgrc\ (aún en la sección \rcsection{bugzilla}) controlan este
+comportamiento.
+\begin{itemize}
+\item[\texttt{strip}] La cantidad de elementos iniciales de ruta a
+  remover de un nombre de ruta del repositorio para construir una ruta
+  parcial para una URL. Por ejemplo, si los repositorios en su
+  servidor se ubican en \dirname{/home/hg/repos}, y usted tiene un
+  repositorio cuya ruta es \dirname{/home/hg/repos/app/tests},
+  entonces fijar \texttt{strip} a \texttt{4} resultará en una ruta
+  parcial de \dirname{app/tests}.  El gancho hará disponible esta ruta
+  parcial cuando expanda una plantilla, como \texttt{webroot}.
+\item[\texttt{template}] El texto de la plantilla a usar. En adición a
+  las variables usuales relacionadas con conjuntos de cambios, esta
+  plantilla puede usar \texttt{hgweb} (el valor del ítem de
+  configuración \texttt{hgweb} de arriba) y \texttt{webroot} (la ruta
+  construida usando \texttt{strip} arriba).
+\end{itemize}
+
+Adicionalmente, usted puede añadir un ítem \rcitem{web}{baseurl} a la
+sección \rcsection{web} de su \hgrc.  El gancho \hgext{bugzilla}
+publicará esto cuando expanda una plantilla, como la cadena base a
+usar cuando se construya una URL que le permita a los usuarios navegar
+desde un comentario de Bugzilla a la vista de un conjunto de cambios.
+Ejemplo:
+\begin{codesample2}
+  [web]
+  baseurl = http://hg.domain.com/
+\end{codesample2}
+
+A continuación se presenta un ejemplo completo de configuración para
+el gancho \hgext{bugzilla}.
+%TODO traducir?
+\begin{codesample2}
+  [bugzilla]
+  host = bugzilla.example.com
+  password = mypassword
+  version = 2.16
+  # server-side repos live in /home/hg/repos, so strip 4 leading
+  # separators
+  strip = 4
+  hgweb = http://hg.example.com/
+  usermap = /home/hg/repos/notify/bugzilla.conf
+  template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
+    repo, refers to this bug.\\nFor complete details, see 
+    \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
+    description:\\n\\t\{desc|tabindent\}
+\end{codesample2}
+
+\subsubsection{Pruebas y resolución de problemas}
+
+Los problemas más comunes que aparecen en la configuración del gancho
+\hgext{bugzilla} suelen estar relacionados con la ejecución del guión
+de Bugzilla \filename{processmail} y la asociación de nombres de
+consignadores a nombres de usuario.
+
+Recuerde que en la sección~\ref{sec:hook:bugzilla:config} arriba el
+usuario que ejecuta el proceso Mercurial en el servidor es también 
+el usuario que ejecutará el guión \filename{processmail}. El guión
+\filename{processmail} algunas veces hace que Bugzilla escriba en
+ficheros en su directorio de configuración, y los ficheros de
+configuración de Bugzilla usualmente son propiedad del usuario bajo el
+cual se ejecuta el servidor web.
+
+Usted puede hacer que \filename{processmail} sea ejecutado con la
+identidad del usuario adecuado usando el comando \command{sudo}. A
+continuación se presenta una entrada de ejemplo para un fichero
+\filename{sudoers}.
+\begin{codesample2}
+  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
+\end{codesample2}
+Esto permite que el usuario \texttt{hg\_user} ejecute el programa
+\filename{processmail-wrapper} con la identidad del usuario
+\texttt{httpd\_user}.
+
+Esta indirección a través de un guión envoltorio es necesaria, porque
+\filename{processmail} espera que al ser ejecutado su directorio
+actual sea aquel en el cual se instaló Bugzilla; usted no puede
+especificar ese tipo de condición en un fichero \filename{sudoers}.
+Los contenidos del giuón envoltorio son simples:
+\begin{codesample2}
+  #!/bin/sh
+  cd `dirname $0` && ./processmail "$1" nobody@example.com
+\end{codesample2}
+No parece importar qué dirección de correo se le pase a
+\filename{processmail}.
+
+Si su \rcsection{usermap} no es configurada correctamente, los
+usuarios verán un mensaje de error del gancho \hgext{bugzilla} cuando
+empujen cambios al servidor. El mensaje de error se verá así:
+\begin{codesample2}
+  cannot find bugzilla user id for john.q.public@example.com
+\end{codesample2}
+Lo que esto quiere decir es que la dirección del consignador,
+\texttt{john.q.public@example.com}, no es un nombre de usuario
+Bugzilla válido, ni tiene una entrada en su \rcsection{usermap} que lo
+asocie con un nombre de usuario válido Bugzilla.
+
+\subsection{\hgext{notify}---enviar notificaciones de correo
+electrónico}
+
+%TODO feeds => notificaciones: lo más fácil es mirar en wikipedia
+Aunque el servidor web embebido de Mercurial provee notificaciones de
+cambios en cada repositorio, muchas personas prefieren recibir las
+notificaciones de cambios vía correo electrónico. El gancho
+\hgext{notify}\ndt{Notificación.} le permite a usted enviar
+notificaciones a un conjunto de direcciones de correo cuando lleguen
+conjuntos de cambios en los que los subscriptores estén interesados.
+
+De la misma forma que con el gancho \hgext{bugzilla}, el gancho
+\hgext{notify} está orientado a plantillas, así que usted puede
+personalizar los contenidos del mensaje de notificación que se envía.
+
+Por defecto, el gancho \hgext{notify} incluye un diff de cada conjunto
+%TODO que se envía? revisar, pienso que es ``que se recibe''
+de cambios que se envía; usted puede limitar el tamaño del diff, o
+desactivar completamente esta característica. Es útil para permitir a
+los subscriptores revisar los cambios inmediatamente, en vez de tener
+que hacer clic para visitar una URL.
+
+\subsubsection{Configuración del gancho \hgext{notify}}
+
+Usted puede configurar el gancho \hgext{notify} para enviar un mensaje
+de correo por conjunto de cambios entrante, o uno por grupo entrante
+de conjuntos de cambios (todos los que llegaron en un único empuje o
+jalado).
+\begin{codesample2}
+  [hooks]
+  # enviar un correo por grupo de cambios
+  changegroup.notify = python:hgext.notify.hook
+  # enviar un correo por cambio
+  incoming.notify = python:hgext.notify.hook
+\end{codesample2}
+
+La información para configurar este gancho se ubica en la sección
+\rcsection{notify} de un fichero \hgrc.
+\begin{itemize}
+\item[\rcitem{notify}{test}] Por defecto, este gancho no envía correos
+  en absoluto; en vez de eso, imprime el mensaje que se
+  \emph{enviaría}. Fije este ítem en \texttt{false} para permitir el
+  envío de correos. El motivo por el que el envío de correos está
+  desactivado es que hacen falta varios intentos para configurar esta
+  extensión exactamente como usted desea, y sería maleducado enviar a
+  los subscriptores una cantidad de notificaciones ``rotas'' mientras
+  usted depura su configuración.
+\item[\rcitem{notify}{config}] La ruta a un fichero de configuración
+  que contiene información de subscripción. Esto se mantiene separado
+  del \hgrc\ principal para que usted pueda mantenerlo en un
+  repositorio. La gente puede clonar ese repositorio, actualizar sus
+  subscripciones, y empujar los cambios de vuelta a su servidor.
+\item[\rcitem{notify}{strip}] La cantidad de caracteres iniciales de
+  separación de ruta a remover de la ruta del repositorio, al decidir
+  si un repositorio tiene subscriptores. Por ejemplo, si los
+  repositorios en su servidor están en \dirname{/home/hg/repos}, y
+  \hgext{notify} está trabajando con un repositorio llamado
+  \dirname{/home/hg/repos/shared/test}, fijar \rcitem{notify}{strip} a
+  \texttt{4} hará que \hgext{notify} elimine las partes iniciales de
+  la ruta hasta \dirname{shared/test}, y asociará los subscriptores
+  frente a dicha ruta.
+\item[\rcitem{notify}{template}] El texto de plantilla a usar cuando
+  se envíen mensajes. Especifica los contenidos de la cabecera del
+  mensaje y el cuerpo del mismo.
+\item[\rcitem{notify}{maxdiff}] El número máximo de líneas de datos de
+  diff a añadir al final de un mensaje. Si la longitud de un diff es
+  mayor a eso, se trunca. Por defecto, está fijado en 300. Fije esto a 
+  \texttt{0} para omitir los diffs en los correos de notificación.
+\item[\rcitem{notify}{sources}] Una lista de fuentes de conjuntos de
+  cambios a considerar. Esto le permite a usted indicar a
+  \hgext{notify} para que sólo envíe correos acerca de cambios que
+  usuarios remotos hayan empujado al repositorio vía un servidor, por
+  ejemplo.  Vea la sección~\ref{sec:hook:sources} para las fuentes que
+  usted puede especificar aquí.
+\end{itemize}
+
+Si usted fija el ítem \rcitem{web}{baseurl} en la sección
+\rcsection{web}, usted lo puede usar en una plantilla; estará
+disponible como \texttt{webroot}.
+
+A continuación se presenta un ejemplo completo de configuración para
+el gancho \hgext{notify}.
+\begin{codesample2}
+  [notify]
+  # enviar correo
+  test = false
+  # datos de subscriptores están en el repositorio notify
+  config = /home/hg/repos/notify/notify.conf
+  # repos están en /home/hg/repos on server, así que elimine 4
+  # caracteres"/"
+  strip = 4
+  template = X-Hg-Repo: \{webroot\}
+    Subject: \{webroot\}: \{desc|firstline|strip\}
+    From: \{author\}
+
+    changeset \{node|short\} in \{root\}
+    details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
+    description:
+      \{desc|tabindent|strip\}
+
+  [web]
+  baseurl = http://hg.example.com/
+\end{codesample2}
+
+Esto producirá un mensaje que se verá como el siguiente:
+\begin{codesample2}
+  X-Hg-Repo: tests/slave
+  Subject: tests/slave: Handle error case when slave has no buffers
+  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)
+
+  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
+  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
+  description:
+          Handle error case when slave has no buffers
+  diffs (54 lines):
+
+  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
+  --- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
+  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
+  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
+  [...snip...]
+\end{codesample2}
+
+\subsubsection{Pruebas y resolución de problemas}
+
+No olvide que por defecto, la extensión \hgext{notify} \emph{no
+enviará ningún correo electrónico} hasta que usted la configure
+explícitamente para hacerlo, fijando el valor de \rcitem{notify}{test}
+a \texttt{false}.  Hasta que usted haga eso, simplemente se imprimirá
+el mensaje que se \emph{enviaría}.
+
+\section{Información para escritores de ganchos}
+\label{sec:hook:ref}
+
+\subsection{Ejecución de ganchos internos}
+
+Un gancho interno es llamado con argumentos de la siguiente forma:
+\begin{codesample2}
+  def myhook(ui, repo, **kwargs):
+      pass
+\end{codesample2}
+El parámetro \texttt{ui} es un objeto \pymodclass{mercurial.ui}{ui}.
+El parámetro \texttt{repo} es un objeto
+\pymodclass{mercurial.localrepo}{localrepository}. Los nombres y
+valores de los parámetros en \texttt{**kwargs} dependen del gancho que
+se invoque, con las siguientes características en común:
+\begin{itemize}
+\item Si hay un parámetro llamado \texttt{node} o
+  \texttt{parent\emph{N}}, contendrá un ID hexadecimal de un conjunto
+  de cambios. La cadena vacía es usada para representar un
+  ``ID de conjunto de cambios nulo'' en vez de una cadena de ceros.
+\item Si hay un parámetro llamado \texttt{url}, contendrá la URL de un
+  repositorio remoto, si puede ser determinada.
+\item Los parámetros booleanos son representados como objetos
+    \texttt{bool} de Python.
+\end{itemize}
+
+Un gancho interno es ejecutado sin cambiar el directorio de trabajo
+del proceso (a diferencia de los ganchos externos, que son ejecutados
+desde la raíz del repositorio). El gancho no debe cambiar el
+directorio de trabajo del proceso, porque esto haría que falle
+cualquier llamada que se haga a la API de Mercurial.
+
+Si un gancho retorna el valor booleano ``false''\ndt{Falso.}, se
+considera que éste tuvo éxito. Si retorna
+``true''\ndt{Verdadero.} o genera una excepción, se considera que
+ha fallado. Una manera útil de pensar en esta convención de llamado es
+``dígame si usted falló''.
+
+Note que los IDs de conjuntos de cambios son pasados a los ganchos de
+Python como cadenas hexadecimales, no como los hashes binarios que la
+API de Mercurial usa normalmente. Para convertir un hash de
+hexadecimal a binario, use la función \pymodfunc{mercurial.node}{bin}.
+
+\subsection{Ejecución de ganchos externos}
+
+Un gancho externo es pasado al intérprete de comandos del usuario bajo
+el cual se ejecuta Mercurial. Las características del intérprete, como
+sustitución de variables y redirección de comandos, están disponibles.
+El gancho es ejecutado desde el directorio raíz del repositorio
+(a diferencia de los ganchos internos, que se ejecutan desde el mismo
+directorio en que Mercurial fue ejecutado).
+
+Los parámetros para el gancho se pasan como variables de entorno. El
+nombre de cada variable de entorno se pasa a mayúsculas y se le añade
+el prefijo ``\texttt{HG\_}''.  Por ejemplo, si el nombre de un
+parámetro es ``\texttt{node}'', el nombre de la variable de entorno
+que almacena el parámetro se llamará ``\texttt{HG\_NODE}''.
+
+Un parámetro booleano se representa con la cadena ``\texttt{1}'' para
+``true'', ``\texttt{0}'' para ``false''.  Si una variable se llama
+\envar{HG\_NODE}, \envar{HG\_PARENT1} o \envar{HG\_PARENT2},  
+contendrá un ID de conjunto de cambios representado como una cadena
+hexadecimal. La cadena vacía es usada para representar un ``ID de
+conjunto de cambios nulo'' en vez de una cadena de ceros. Si una
+variable de entorno se llama \envar{HG\_URL}, contendrá la URL de un
+repositorio remoto, si puede ser determinada.
+
+Si un gancho termina con un código de salida de cero, se considera que
+tuvo éxito. Si termina con un código de salida diferente de cero, se
+considera que falló.
+
+\subsection{Averiguar de dónde vienen los conjuntos de cambios}
+%TODO los trae la cigüeña. De París. Y quedan debajo de una col.
+
+Un gancho que involucra la transferencia de conjuntos de cambios entre
+un repositorio local y otro puede ser capaz de averiguar información
+acerca de ``el otro lado''. Mercurial sabe \emph{cómo} son
+transferidos los conjuntos de cambios, y en muchos casos también desde
+o hacia donde están siendo transferidos.
+
+\subsubsection{Fuentes de conjuntos de cambios}
+\label{sec:hook:sources}
+
+Mercurial le indicará a un gancho cuáles son, o fueron, los medios
+usados para transferir los conjuntos de cambios entre repositorios.
+Esta información es provista por Mercurial en un parámetro Python
+llamado \texttt{source}\ndt{Fuente.}, o una variable de entorno
+llamada \envar{HG\_SOURCE}.
+
+\begin{itemize}
+\item[\texttt{serve}] Los conjuntos de cambios son transferidos desde
+  o hacia un repositorio remoto a través de http o ssh.
+\item[\texttt{pull}] Los conjuntos de cambios son transferidos vía una
+  operación de jalado de un repositorio a otro.
+\item[\texttt{push}] Los conjuntos de cambios son transferidos vía un
+  empuje de un repositorio a otro.
+\item[\texttt{bundle}] Los conjuntos de cambios son transferidos desde
+    %TODO bundle
+  o hacia un paquete.
+\end{itemize}
+
+\subsubsection{A dónde van los cambios---URLs de repositorios remotos}
+\label{sec:hook:url}
+%TODO al cielo? no, ésos son los perros
+
+Cuando es posible, Mercurial le indicará a los ganchos la ubicación de
+``el otro lado'' de una actividad que transfiera datos de conjuntos de
+cambios entre repositorios. Esto es provisto por Mercurial en un
+parámetro Python llamado \texttt{url}, o en una variable de entorno
+llamada \envar{HG\_URL}.
+
+No siempre esta información está disponible. Si un gancho es invocado
+un repositorio que es servido a través de http o ssh, Mercurial no
+puede averiguar dónde está el repositorio remoto, pero puede saber
+desde dónde se conecta el cliente. En esos casos, la URL tendrá una de
+las siguientes formas:
+\begin{itemize}
+\item \texttt{remote:ssh:\emph{ip-address}}---cliente ssh remoto, en
+  la dirección IP dada.
+\item \texttt{remote:http:\emph{ip-address}}---cliente remoto http, en
+  la dirección IP dada. Si el cliente está usando SSL, tendrá la forma
+  \texttt{remote:https:\emph{ip-address}}.
+\item Vacío---no se pudo descubrir información acerca del cliente
+  remoto.
+\end{itemize}
+
+\section{Referencia de ganchos}
+
+\subsection{\hook{changegroup}---luego de añadir conjuntos de cambios
+remotos}
+\label{sec:hook:changegroup}
+
+Este gancho es ejecutado luego de que un grupo de conjuntos de cambios
+preexistentes ha sido añadido al repositorio, por ejemplo vía un
+\hgcmd{pull} o \hgcmd{unbundle}.  Este gancho es ejecutado una vez por
+cada operación que añade uno o más conjuntos de cambios. Este gancho
+se diferencia del gancho \hook{incoming}, que es ejecutado una vez por
+cada conjunto de cambios, sin importar si los cambios llegan en grupo.
+
+Algunos usos posibles para este gancho includen el probar o ensamblar
+los conjuntos de cambios añadidos, actualizar una base de datos de
+fallos, o notificar a subscriptores de que el repositorio contiene
+nuevos cambios.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto
+  de cambios que fue añadido en el grupo. Todos los conjuntos de
+  cambios entre éste y la punta
+  %TODO mirar qué hacer con el índice
+  \index{tags!\texttt{tip}}(\texttt{tip}), inclusive, fueron añadidos
+  %TODO unbundle
+  por un único jalado (\hgcmd{pull}), empuje (\hgcmd{push}) o \hgcmd{unbundle}.
+\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
+  sección~\ref{sec:hook:sources} para más detalles.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Veta también: \hook{incoming} (sección~\ref{sec:hook:incoming}),
+\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}),
+\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{commit}---luego de la creación de un nuevo conjunto
+de cambios}
+\label{sec:hook:commit}
+
+Este gancho es ejecutado luego de la creación de un nuevo conjunto de
+cambios.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID de conjunto
+  de cambios del conjunto de cambios que acabó de ser consignado.
+\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del primer padre del conjunto de cambios que
+  acaba de ser consignado.
+\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del segundo padre del conjunto de cambios que
+  acaba de ser consignado.
+\end{itemize}
+
+Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit}),
+\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit})
+
+\subsection{\hook{incoming}---luego de que un conjunto de cambios
+remoto es añadido}
+\label{sec:hook:incoming}
+
+Este gancho es ejecutado luego de que un conjunto de cambios
+preexistente ha sido añadido al repositorio, por ejemplo, vía un
+\hgcmd{push}.  Si un grupo de conjuntos de cambios fue añadido en una
+sola operación, este gancho es ejecutado una vez por cada conjunto de
+cambios añadido.
+
+Usted puede usar este gancho para los mismos fines que el gancho
+\hook{changegroup} (sección~\ref{sec:hook:changegroup}); simplemente
+algunas veces es más conveniente ejecutar un gancho una vez por cada
+grupo de conjuntos de cambios, mientras que otras es más útil correrlo
+por cada conjunto de cambios.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto
+  de cambios recién añadido.
+\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
+  sección~\ref{sec:hook:sources} para más detalles.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup})
+\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}),
+\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{outgoing}---luego de la propagación de los conjuntos
+de cambios}
+\label{sec:hook:outgoing}
+
+Este gancho es ejecutado luego de que un grupo de conjuntos de cambios
+ha sido propagado fuera de éste repositorio, por ejemplo por un
+comando \hgcmd{push} o \hgcmd{bundle}.
+
+Un uso posible para este gancho es notificar a los administradores que
+los cambios han sido jalados.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto
+  de cambios del grupo que fue enviado.
+\item[\texttt{source}] Una cadena. La fuente de la operación (vea la
+  sección~\ref{sec:hook:sources}).  Si un cliente remoto jaló cambios
+  de este repositorio, \texttt{source} será \texttt{serve}.  Si el
+  cliente que obtuvo los cambios desde este repositorio era local,
+  \texttt{source} será \texttt{bundle}, \texttt{pull}, o
+  \texttt{push}, dependiendo de la operación que llevó a cabo el
+  cliente.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Vea también: \hook{preoutgoing} (sección~\ref{sec:hook:preoutgoing})
+
+\subsection{\hook{prechangegroup}---antes de empezar la adición de
+conjuntos de cambios remotos}
+\label{sec:hook:prechangegroup}
+
+Este gancho de control es ejecutado antes de que Mercurial empiece a
+añadir un grupo de conjuntos de cambios de otro repositorio.
+
+Este gancho no tiene ninguna información acerca de los conjuntos de
+cambios que van a ser añadidos, porque es ejecutado antes de que se
+permita que empiece la transmisión de dichos conjuntos de cambios. Si
+este gancho falla, los conjuntos de cambios no serán transmitidos.
+
+Un uso para este gancho es prevenir que se añadan cambios externos a un
+repositorio. Por ejemplo, usted podría usarlo para ``congelar''
+temporal o permanentemente una rama ubicada en un servidor para que
+los usuarios no puedan empujar cambios a ella, y permitiendo al mismo
+tiempo modificaciones al repositorio por parte de un administrador
+local.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
+  sección~\ref{sec:hook:sources} para más detalles.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}),
+\hook{incoming} (sección~\ref{sec:hook:incoming}), ,
+\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})
+
+\subsection{\hook{precommit}---antes de iniciar la consignación de un
+conjunto de cambios}
+\label{sec:hook:precommit}
+
+Este gancho es ejecutado antes de que Mercurial inicie la consignación
+de un nuevo conjunto de cambios. Es ejecutado antes de que Mercurial
+tenga cualquier de los metadatos para la consignación, como los
+ficheros a ser consignados, el mensaje de consignación, o la fecha de
+consignación.
+
+Un uso para este gancho es deshabilitar la capacidad de consignar
+nuevos conjuntos de cambios, pero permitiendo conjuntos de cambios
+entrantes. Otro es ejecutar un proceso de ensamble/compilación o
+prueba, y permitir la consignación sólo si el ensamble/compilación o
+prueba tiene éxito.
+
+Parámetros para este gancho:
+\begin{itemize}
+  \item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del primer padre del directorio de trabajo.
+\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del segundo padre del directorio de trabajo.
+\end{itemize}
+Si la consignación continúa, los padres del directorio de trabajo se
+convertirán en los padres del nuevo conjunto de cambios.
+
+Vea también: \hook{commit} (sección~\ref{sec:hook:commit}),
+\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit})
+
+\subsection{\hook{preoutgoing}---antes de empezar la propagación de
+conjuntos de cambios}
+\label{sec:hook:preoutgoing}
+
+Este gancho es ejecutado antes de que Mercurial conozca las
+identidades de los conjuntos de cambios que deben ser transmitidos.
+
+Un uso para este gancho es evitar que los cambios sean transmitidos a
+otro repositorio.
+
+Parámetros para este gancho:
+\begin{itemize}
+  \item[\texttt{source}] Una cadena. La fuente la operación que está
+    tratando de obtener cambios de éste repositorio (vea
+    la sección~\ref{sec:hook:sources}).  Revise la documentación para
+    el parámetro \texttt{source} del gancho \hook{outgoing}, en la
+    sección~\ref{sec:hook:outgoing}, para ver los posibles valores de
+    este parámetro.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+    es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Vea también: \hook{outgoing} (sección~\ref{sec:hook:outgoing})
+
+\subsection{\hook{pretag}---antes de etiquetar un conjunto de cambios}
+\label{sec:hook:pretag}
+
+Este gancho de control es ejecutado antes de la creación de una
+etiqueta. Si el gancho termina exitosamente, la creación de la
+etiqueta continúa. Si el gancho falla, no se crea la etiqueta.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a
+  ésta instancia del repositorio (p.e.~almacenado en
+  \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado
+  en \sfilename{.hgtags}).
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto
+  de cambios a etiquetar.
+\item[\texttt{tag}] Una cadena. El nombre de la etiqueta por crear.
+\end{itemize}
+
+Si la etiqueta que se va a crear se encuentra bajo control de
+revisiones, los ganchos \hook{precommit} y \hook{pretxncommit}
+(secciones~\ref{sec:hook:commit} y~\ref{sec:hook:pretxncommit})
+también serán ejecutados.
+
+Vea también: \hook{tag} (sección~\ref{sec:hook:tag})
+
+\subsection{\hook{pretxnchangegroup}---antes de completar la adición
+de conjuntos de cambios remotos}
+\label{sec:hook:pretxnchangegroup}
+
+Este gancho de control es ejecutado antes de una transacción---la que
+maneja la adición de un grupo de conjuntos de cambios nuevos desde
+fuera del repositorio---se complete.  Si el gancho tiene éxito, la
+transacción se completa, y todos los conjuntos de cambios se vuelven
+permanentes dentro de este repositorio. Si el gancho falla, la
+transacción es deshecha, y los datos para los conjuntos de cambios son
+eliminados.
+
+Este gancho puede acceder a los metadatos asociados con los conjuntos
+de cambios casi añadidos, pero no debe hacer nada permanente con estos
+datos. Tampoco debe modificar el directorio de trabajo.
+
+Mientras este gancho está corriendo, si otro proceso Mercurial accesa
+el repositorio, podrá ver los conjuntos de cambios casi añadidos como
+si fueran permanentes. Esto puede llevar a condiciones de carrera si
+usted no toma precauciones para evitarlas.
+
+Este gancho puede ser usado para examinar automáticamente un grupo de
+conjuntos de cambios. Si el gancho falla, todos los conjuntos de
+cambios son ``rechazados'' cuando la transacción se deshace.
+
+Parámetros para este gancho:
+\begin{itemize}
+  \item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer
+  conjunto de cambios que fue añadido en el grupo. Todos los
+  conjuntos de cambios entre éste y el
+  \index{tags!\texttt{tip}}\texttt{tip}, inclusive, fueron añadidos
+  por un único \hgcmd{pull}, \hgcmd{push} o \hgcmd{unbundle}.
+\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
+  sección~\ref{sec:hook:sources} para más detalles.
+\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
+  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
+\end{itemize}
+
+Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}),
+\hook{incoming} (sección~\ref{sec:hook:incoming}),
+\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup})
+
+\subsection{\hook{pretxncommit}---antes de completar la consignación
+de un nuevo conjunto de cambios}
+\label{sec:hook:pretxncommit}
+
+Este gancho de control es ejecutado antes de que una transacción---que
+maneja una nueva consignación---se complete. Si el gancho tiene éxito,
+la transacción se completa y el conjunto de cambios se hace permanente
+dentro de éste repositorio. Si el gancho falla, la transacción es
+deshecha, y los datos de consignación son borrados.
+
+Este gancho tiene acceso a los metadatos asociados con el
+prácticamente nuevo conjunto de cambios, pero no debería hacer nada
+permanente con estos datos. Tampoco debe modificar el directorio de
+trabajo.
+
+Mientras este gancho está corriendo, si otro proceso Mercurial accesa
+éste repositorio, podrá ver el prácticamente nuevo conjunto de cambios
+como si fuera permanente. Esto puede llevar a condiciones de carrera si
+usted no toma precauciones para evitarlas.
+
+Parámetros para este gancho:
+\begin{itemize}
+  \item[\texttt{node}] Un ID de conjunto de cambios. El ID del
+    conjunto de cambios recién consignado.
+\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del primer padre del conjunto de cambios que
+  acaba de ser consignado.
+\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
+  conjunto de cambios del segundo padre del conjunto de cambios que
+  acaba de ser consignado.
+\end{itemize}
+
+Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit})
+
+\subsection{\hook{preupdate}---antes de actualizar o fusionar el
+directorio de trabajo}
+\label{sec:hook:preupdate}
+
+Este gancho de control es ejecutado antes de actualizar o fusionar el
+directorio de trabajo. Es ejecutado sólo si las revisiones usuales de
+Mercurial antes de las actualizaciones determinan que la actualización
+o fusión pueden proceder. Si el gancho termina exitosamente, la
+actualización o fusión pueden proceder.; si falla, la actualización o
+fusión no empiezan.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del
+  padre al que el directorio de trabajo será actualizado. Si se está
+  fusionando el directorio de trabajo, no cambiará este padre.
+\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está
+  definido si se está fusionando el directorio de trabajo. El ID de la
+  revisión con la cual está siendo fusionado el directorio de trabajo.
+\end{itemize}
+
+Vea también: \hook{update} (sección~\ref{sec:hook:update})
+
+\subsection{\hook{tag}---luego de etiquetar un conjunto de cambios}
+\label{sec:hook:tag}
+
+Este gancho es ejecutado luego de la creación de una etiqueta.
+
+Parámetros para este gancho:
+\begin{itemize}
+\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a
+  ésta instancia del repositorio (p.e.~almacenado en
+  \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado
+  en \sfilename{.hgtags}).
+\item[\texttt{node}] Un ID de conjunto de cambios. El ID del
+  conjunto de cambios que fue etiquetado.
+\item[\texttt{tag}] Una cadena. El nombre de la etiqueta que fue
+  creada.
+\end{itemize}
+
+Si la etiqueta creada está bajo control de revisiones, el gancho
+\hook{commit} (sección~\ref{sec:hook:commit}) es ejecutado antes de
+este gancho.
+
+Vea también: \hook{pretag} (sección~\ref{sec:hook:pretag})
+
+\subsection{\hook{update}---luego de actualizar o fusionar el
+directorio de trabajo}
+\label{sec:hook:update}
+
+Este gancho es ejecutado después de una actualización o fusión en el
+directorio de trabajo. Ya que una fusión puede fallar (si el comando
+externo \command{hgmerge} no puede resolver los conflictos en un
+fichero), este gancho indica si la actualización o fusión fueron
+completados adecuadamente.
+
+\begin{itemize}
+\item[\texttt{error}] Un booleano. Indica si la actualización o fusión
+  fue completada exitosamente.
+\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del padre
+  al cual fue actualizado el directorio de trabajo. Si se fusionó el
+  directorio de trabajo, no se habrá cambiado este padre.
+\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está
+  definido si se fusionó el directorio de trabajo. El ID de la
+  revisión con la que fue fusionado el directorio de trabajo.
+\end{itemize}
+
+Vea también: \hook{preupdate} (sección~\ref{sec:hook:preupdate})
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/htlatex.book	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+../en/htlatex.book
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/intro.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,621 @@
+\chapter{Introducción}
+\label{chap:intro}
+
+\section{Acerca del control de revisiones}
+
+El control de revisiones es el proceso de administrar diferentes
+versiones de una pieza de información. En su forma más simple es algo
+que la mayoría de gente hace a mano: cada vez que usted modifica un
+fichero, lo graba con un nuevo nombre que contiene un número, cada uno
+mayor que el anterior.
+
+Administrar manualmente muchas versiones de incluso sólo un fichero es una tarea
+propensa a errores, a pesar de que hace bastante tiempo hay
+herramientas que ayudan en este proceso.  Las primeras herramientas
+para automatizar el control de revisiones fueron pensadas para que un
+usuario administrara un solo fichero.  En las décadas pasadas, el
+alcance de las herramientas de control de revisiones ha ido aumentando
+considerablemente; ahora manejan muchos ficheros y facilitan el
+trabajo en conjunto de varias personas. Las mejores herramientas de
+control de revisiones de la actualidad no tienen problema con miles de
+personas trabajando en proyectos que consisten de cientos de miles de
+ficheros.
+
+\subsection{¿Por qué usar control de revisiones?}
+
+Hay muchas razones por las cuales usted o su equipo desearía usar una
+herramienta automática de control de revisiones para un proyecto.
+\begin{itemize}
+\item Llevar registro del historial y la evolución de su proyecto, para
+  evitar hacer la tarea manualmente. Por cada cambio, tendrá una
+  bitácora de \emph{quién} lo hizo; \emph{por qué} se hizo;
+  \emph{cuándo} se hizo; y de \emph{qué} se trataba el cambio.
+\item Cuando trabaja con más personas, los programas de control de
+  revisiones facilitan la colaboración.  Por ejemplo, cuando varias
+  personas hacen cambios potencialmente incompatibles de forma casi
+  simultánea, el programa le ayudará a identificar y resolver tales
+  conflictos.
+\item Puede ayudarle a recuperarse de equivocaciones. Si aplica un
+  cambio que posteriormente se evidencia como un error, puede
+  revertirlo a una versión previa a uno o muchos ficheros. De hecho,
+  una herramienta \emph{realmente} buena, incluso puede ayudarle
+  efectivamente a darse cuenta exactamente cuándo se introdujo el
+  error (para más detalles ver la sección~\ref{sec:undo:bisect}).
+\item Le ayudará a trabajar simultáneamente, y a manejar las diferencias
+  entre múltiples versiones de su proyecto.
+\end{itemize}
+La mayoría de estas razones son igualmente válidas ---por lo menos en
+teoría--- así esté trabajando en un proyecto solo usted, o con mucha gente.
+
+Algo fundamental acerca de lo práctico de un sistema de control de
+revisiones en estas dos escalas (``un hacker solitario'' y ``un equipo
+gigantesco'') es cómo se comparan los \emph{beneficios} con los
+\emph{costos}.  Una herramienta de control de revisiones que sea
+difícil de entender o usar impondrá un costo alto.
+
+Un proyecto de quinientas personas es muy propenso a colapsar
+solamente con su peso inmediatamente sin una herramienta y un proceso
+de control de versiones. En este caso, el costo de usar control de
+revisiones ni siquiera se tiene en cuenta, puesto que \emph{sin} él,
+el fracaso está casi garantizado.
+
+Por otra parte, un ``arreglo rápido'' de una sola persona, excluiría
+la necesidad de usar una herramienta de control de revisiones, porque
+casi seguramente, el costo de usar una estaría cerca del costo del
+proyecto. ¿No es así?
+
+Mercurial soporta \emph{ambas} escalas de de desarrollo de manera
+única. Puede aprender lo básico en pocos minutos, y dado su bajo
+sobrecosto, puede aplicar el control de revisiones al proyecto más
+pequeño con facilidad. Su simplicidad significa que no tendrá que
+preocuparse por conceptos obtusos o secuencias de órdenes compitiendo
+por espacio mental con lo que sea que \emph{realmente} esté tratando
+de hacer.  Al mismo tiempo, Mercurial tiene alto desempeño y su
+%TODO distribuida? en vez de p2p
+naturaleza peer-to-peer le permite escalar indoloramente para manejar
+grandes proyectos.
+
+Ninguna herramienta de control de revisiones puede salvar un
+proyecto mal administrado, pero la elección de herramientas puede
+hacer una gran diferencia en la fluidez con la cual usted puede
+trabajar en un proyecto.
+
+\subsection{La cantidad de nombres del control de revisiones}
+
+El control de revisiones es un campo amplio, tan amplio que no hay un
+acrónimo o nombre único. A continuación presentamos un listado de
+nombres comunes y acrónimos que se podrían encontrar:
+\begin{itemize}
+\item Control de revisiones (RCS)
+\item Manejo de Configuraciones de Programas (SCM), o administracón de
+  configuraciones
+\item Administración de código fuente
+\item Control de Código Fuente, o Control de Fuentes
+\item Control de Versiones (VCS)
+\end{itemize}
+Algunas personas aducen que estos términos tienen significados
+diversos, pero en la práctica se sobreponen tanto que no hay una
+forma acordada o incluso adecuada de separarlos.
+
+\section{Historia resumida del control de revisiones}
+
+La herramienta de control de revisiones más antigua conocida es SCCS 
+(Sistema de Control de Código), escrito por Marc Rochkind en Bell
+Labs, a comienzos de los setentas (1970s).  SCCS operaba sobre ficheros
+individuales, y requería que cada persona que trabajara en el proyecto
+tuviera acceso a un espacio compartido en un solo sistema.  Solamente
+una persona podía modificar un fichero en un momento dado; el
+arbitramiento del acceso a los ficheros se hacía con candados. Era
+común que la gente pusiera los candados a los ficheros, y que
+posteriormente olvidara quitarlos, impidiendo que otro pudiera
+modificar los ficheros en cuestión sin la intervención del
+administrador.
+
+Walter Tichy desarrolló una alternativa gratuita a SCCS a comienzos
+de los ochentas (1980s); llamó a su programa RCS (Sistema de Control de
+Revisiones).  Al igual que SCCS, RCS requería que los desarrolladores
+trabajaran en un único espacio compartido y colocaran candados a los
+ficheros para evitar que varias personas los modificaran
+simultáneamente.
+
+Después en los ochenta, Dick Grune usó RCS como un bloque de
+construcción para un conjunto de guiones de línea de comando, que
+inicialmente llamó cmt, pero que renombró a CVS (Sistema Concurrente de
+Versiones).  La gran innovación de CVS era que permitía a los
+desarrolladores trabajar simultáneamente de una forma más o menos
+independiente en sus propios espacios de trabajo. Los espacios de
+trabajo personales impedían que los desarrolladores se pisaran las
+mangueras todo el tiempo, situación común con SCCS y RCS.  Cada
+desarrollador tenía una copia de todos los ficheros del proyecto y podía
+modificar sus copias independientemente, Tenían que fusionar sus
+ediciones antes de consignar los cambios al repositorio central.
+
+Brian Berliner tomó los scripts originales de Grune y los reescribió
+en~C, publicando en 1989 el código sobre el cual se ha
+desarrollado la versión moderna de CVS.  CVS adquirió posteriormente 
+la habilidad de operar sobre una conexión de red, dotándolo de una
+arquitectura, cliente/servidor. La arquitectura de CVS es
+centralizada; el historial del proyecto está únicamente en el
+repositorio central.  Los espacios de trabajo de los clientes
+contienen únicamente copias recientes de las versiones de los
+ficheros, y pocos metadatos para indicar dónde está el servidor. CVS
+ha tenido un éxito enorme; Es probablemente el sistema de control de
+revisiones más extendido del planeta.
+
+A comienzos de los noventa~(1990s), Sun MicroSystems desarrollo un
+temprano sistema distribuido de control de revisiones llamado
+TeamWare.
+Un espacio de trabajo TeamWare contiene una copia completa del
+historial del proyecto. TeamWare no tiene la noción de repositorio
+central. (CVS se basaba en RCS para el almacenamiento de su historial;
+TeamWare usaba SCCS.)
+
+A medida que avanzaba la decada de los noventa, se empezó a
+evidenciar los problemas de CVS.  Almacena cambios simultáneos a muchos
+ficheros de forma individual, en lugar de agruparlos como una
+operación única y atómica lógicamente.  No maneja bien su jerarquía de
+ficheros; es fácil desordenar un repositorio al renombrar ficheros
+y directorios. Peor aún, su código fuente es difícil de leer y
+mantener, lo que hizo que su ``umbral de dolor'' para arreglar sus
+problemas arquitecturales fuera algo prohibitivo.
+
+En 2001, Jim Blandy y Karl Fogel, dos desarrolladores que habían
+trabajado en CVS, comenzaron un proyecto para reemplazarlo con una
+herramienta con mejor arquitectura y código más limpio.  El resultado,
+Subversion, no se separó del modelo centralizado cliente/servidor de
+CVS, pero añadió consignaciones atómicas de varios ficheros, mejor
+manejo de espacios de nombres , y otras características que lo hacen
+mejor que CVS. Desde su versión inicial, ha ido creciendo en
+popularidad rápidamente.
+
+Más o menos en forma simultánea Graydon Hoare comenzó a trabajar en un
+ambicioso sistema distribuido de control de versiones que llamó
+Monotone. Mientras que Monotone se enfocaba a evitar algunas fallas de
+diseño de CVS con una arquitectura peer-to-peer, fue mucho más
+allá de las herramientas anteriores (y posteriores) de
+control de revisiones en varios aspectos innovadores. Usa hashes
+criptográficos como identificadores, y tiene una noción integral de 
+``confianza'' para código de diversas fuentes.
+
+Mercurial nació en el 2005.  Algunos de sus aspectos de de diseño
+fueron influenciados por Monotone, pero Mercurial se enfoca en la
+facilidad de uso, gran rendimiento y escalabilidad para proyectos muy
+grandes.
+
+\section{Tendencias en el control de revisiones}
+
+Ha habido una tendencia inconfundible en el desarrollo y uso de las herramientas
+de control de revisiones en las cuatro décadas pasadas, mientras la
+gente se ha hecho familiar con las capacidades de sus herramientas y
+se ha visto restringida por sus limitaciones.
+
+La primera generación comenzó administrando ficheros individuales en
+computadores por persona. A pesar de que tales herramientas
+representaron un avance importante frente al control de revisiones
+manual, su modelo de candados y la dependencia a un sólo computador
+los limitó a equipos de trabajo pequeños y acoplados.
+
+La segunda generación dejó atrás esas limitaciones moviéndose a
+arquitecturas centradas en  redes, y administrando proyectos completos
+a la vez. A medida que los proyectos crecían, nacieron nuevos
+problemas. Con la necesidad de comunicación frecuente con los
+servidores, escalar estas máquinas se convirtió en un problema en
+proyectos realmente grandes. Las redes con poca estabilidad podrían
+impedir que usuarios remotos se conectaran al servidor. A medida que
+los
+proyectos de código abierto comenzaron a ofrecer acceso de sólo lectura
+de forma anónima a cualquiera, la gente sin permiso para consignar
+vio que no podían usar tales herramientas para interactuar en un
+proyecto de forma natural, puesto que no podían guardar sus cambios.
+
+La generación actual de herramientas de control de revisiones es
+peer-to-peer por naturaleza.  Todos estos sistemas han eliminado la
+dependencia de un único servidor central, y han permitido que la
+gente distribuya sus datos de control de revisiones donde realmente se
+necesita. La colaboración a través de Internet ha cambiado las
+limitantes tecnológicas por la cuestión de elección y consenso. Las
+herramientas modernas pueden operar sin conexión indefinidamente y
+autónomamente, necesitando una conexión de red solamente para
+sincronizar los cambios con otro repositorio.
+
+\section{Algunas ventajas del control distribuido de revisiones}
+
+A pesar de que las herramientas para el control distribuido de
+revisiones lleva varios años siendo tan robustas y usables como la
+generación previa de sus contrapartes, algunas personas que usan las
+herramientas más antiguas no se han percatado de sus ventajas.  Hay
+gran cantidad
+de situaciones en las cuales las herramientas distribuidas brillan
+frente a las centralizadas.
+
+Para un desarrollador individual, las herramientas distribuidas casi
+siempre son más rápidas que las centralizadas. Por una razón sencilla:
+Una herramienta centralizada necesita comunicarse por red para las
+operaciones más usuales, debido a que los metadatos se almacenan en
+una sola copia en el servidor central. Una herramienta distribuida
+almacena todos sus metadatos localmente.  Con todo lo demás de la
+misma forma, comunicarse por red tiene un sobrecosto en una
+herramienta centralizada. No subestime el valor de una herramienta de
+respuesta rápida: Usted empleará mucho tiempo interactuando con su
+programa de control de revisiones.
+
+Las herramientas distribuidas son indiferentes a los caprichos de su
+infraestructura de servidores, de nuevo, debido a la replicación de
+metadatos en tantos lugares. Si usa un sistema centralizado y su
+servidor explota, ojalá los medios físicos de su copia de seguridad
+sean confiables, y que su última copia sea reciente y además
+funcione. Con una herramienta distribuida tiene tantas copias de
+seguridad disponibles como computadores de contribuidores.
+
+La confiabilidad de su red afectará las herramientas distribuidas de
+una forma mucho menor que a las herramientas centralizadas. Usted no puede
+siquiera usar una herramienta centralizada sin conexión de red,
+excepto por algunas órdenes muy limitadas. Con herramientas
+distribuidas, si sus conexión cae mientras usted está trabajando,
+podría nisiquiera darse cuenta. Lo único que que no podrá hacer es
+comunicarse  con repositorios en otros computadores, algo que es
+relativamente raro comparado con las operaciones locales. Si tiene
+colaboradores remotos en su equipo, puede ser importante.
+
+\subsection{Ventajas para proyectos de código abierto}
+
+Si descubre un proyecto de código abierto y decide que desea comenzar
+a trabajar en él, y ese proyecto usa una herramienta de control
+distribuido de revisiones, usted es de inmediato un par con la gente que se
+considera el ``alma'' del proyecto.  Si ellos publican sus
+repositorios, usted puede copiar inmediatamente el historial del proyecto,
+hacer cambios y guardar su trabajo, usando las mismas herramientas de
+la misma forma que ellos. En contraste, con una herramienta
+centralizada, usted debe usar el programa en un modo ``sólo lectura'' a
+menos que alguien le otorgue permisos para consignar cambios en el
+repositorio central. Hasta entonces, no podrá almacenar sus cambios y
+sus modificaciones locales correrán el riesgo de dañarse cuando trate
+de actualizar su vista del repositorio.
+
+\subsubsection{Las bifurcaciones (forks) no son un problema}
+
+Se ha mencionado que las herramientas de control distribuido de
+versiones albergan un riesgo a los proyectos de código abierto, puesto
+que se vuelve muy sencillo hacer una ``bifurcación''\ndt{fork.} del
+desarrollo del proyecto.  Una bifurcación sucede cuando hay diferencias
+de opinión o actitud entre grupos de desarrolladores que desemboca en
+la decisión de la imposibilidad de continuar trabajando juntos. Cada
+parte toma una copia más o menos completa del código fuente del
+proyecto y toma su propio rumbo.
+
+En algunas ocasiones los líderes de las bifurcaciones reconcilian sus
+diferencias. Con un sistema centralizado de control de revisiones, el
+proceso \emph{técnico} de reconciliarse es doloroso, y se hace de
+forma muy manual.  Usted tiene que decidir qué historial de revisiones va a
+``ganar'', e injertar los cambios del otro equipo en el árbol de alguna
+manera. Con esto usualmente se pierde algo o todo del historial de la
+revisión de alguna de las partes.
+
+Lo que las herramientas distribuidas hacen con respecto a las
+bifurcaciones, es que las bifurcaciones son la \emph{única} forma de
+desarrollar un proyecto. Cada cambio que usted hace es potencialmente
+un punto de bifurcación. La gran fortaleza de esta aproximación es que
+las herramientas distribuidas de control de revisiones tiene que ser
+bueno al \emph{fusionar} las bifurcaciones, porque las bifurcaciones
+son absolutamente fundamentales: pasan todo el tiempo.
+
+Si todas las porciones de trabajo que todos hacen, todo el tiempo, se
+enmarcan en términos de bifurcaciones y fusiones, entonces a aquello a
+lo que se refiere en el mundo del código abierto a una ``bifurcación''
+se convierte \emph{puramente} en una cuestión social. Lo que hacen las
+herramientas distribuidas es \emph{disminuir} la posibilidad de una
+bifurcación porque:
+\begin{itemize}
+\item Eliminan la distinción social que imponen las herramientas
+  centralizadas: aquélla entre miembros (personas con permiso de
+  consignar) y forasteros (los que no tienen el permiso).
+\item Facilitan la reconciliación después de una bifurcación social,
+  porque todo lo que concierne al programa de control de revisiones es
+  una fusión.
+\end{itemize}
+
+Algunas personas se resisten a las herramientas distribuidas porque
+desean mantener control completo sobre sus proyectos, y creen que las
+herramientas centralizadas les dan tal control. En todo caso, si este
+es su parecer, y usted publica sus repositorios de CVS o Subversion, hay
+muchas herramientas disponibles que pueden obtener el historial
+completo (aunque sea lentamente) y recrearlo en otro sitio que usted no
+controla. Siendo así un control ilusorio, puesto que está impidiendo
+la fluidez de colaboración en lugar de prevenir que alguien se sienta
+impulsado a obtener una copia y hacer una bifurcación con su historial.
+
+\subsection{Ventajas para proyectos comerciales}
+
+Muchos proyectos comerciales tienen grupos de trabajo distribuidos
+alrededor del globo.  Quienes contribuyen y están lejos de un
+repositorio central verán una ejecución más lenta de los comandos y tal
+vez menos confiabilidad. Los sistemas de control de revisión
+comerciales intentan amortiguar estos problemas con adiciones de
+replicación remota que usualmente son muy costosos y complicados de
+administrar. Un sistema distribuido no padece estos problemas. Mejor
+aún, puede colocar varios servidores autorizados, por ejemplo, uno por
+sitio, de tal forma que no haya comunicación redundante entre
+repositorios sobre enlaces de conexión costosos.
+
+Los sistemas de control de revisiones distribuidos tienden a ser poco
+escalables. No es inusual que costosos sistemas centralizados caigan
+ante la carga combinada de unas cuantas docenas de usuarios
+concurrentes. De nuevo, las respuestas típicas de replicación tienden
+a ser costosas y complejas de instalar y administrar. Dado que la
+carga en un servidor central---si es que tiene uno---es muchas veces
+menor con una herramienta distribuida (debido a que los datos están
+replicados en todas partes), un solo servidor económico puede tratar
+las necesidades de equipos mucho más grandes, y la replicación para
+balancear la carga se vuelve cosa de guiones.
+
+Si tiene un empleado en el campo, se beneficiará grandemente de un
+sistema distribuido de control de versiones al resolver problemas en
+el sitio del cliente. La herramienta le permitirá generar
+construcciones a la medida, probar diferentes arreglos de forma
+independiente y buscar de forma eficiente las fuentes de fallos en el
+historial y regresiones en los ambientes de los clientes, todo sin
+necesidad de conectarse al servidor de su compañía.
+
+\section{¿Por qué elegir Mercurial?}
+
+Mercurial cuenta con un conjunto único de propiedades que lo hacen
+una elección particularmente buena como sistema de control de
+revisiones, puesto que:
+\begin{itemize}
+\item Es fácil de aprender y usar.
+\item Es liviano.
+\item Escala de forma excelente.
+\item Es fácil de acondicionar.
+\end{itemize}
+
+Si los sistemas de control de revisiones le son familiares, debería
+estar listo para usar Mercurial en menos de cinco minutos. Si no, sólo va a
+tomar unos pocos minutos más. Las órdenes de Mercurial y su conjunto
+de características son uniformes y consistentes generalmente, y basta
+con que siga unas pocas reglas generales en lugar de un montón de
+excepciones.
+
+En un proyecto pequeño, usted puede comenzar a trabajar con Mercurial en
+pocos momentos. Crear nuevos cambios y ramas, transferir cambios (localmente
+o por la red); y las operaciones relacionadas con el estado y el
+historial son rápidas. Mercurial buscar ser ligero y no incomodar en su
+camino combinando poca sobrecarga cognitiva con operaciones
+asombrosamente rápidas.
+
+La utilidad de Mercurial no se limita a proyectos pequeños: está
+siendo usado por proyectos con centenas de miles de contribuyentes,
+cada uno conteniendo decenas de miles de ficheros y centenas de
+megabytes de código fuente
+
+Si la funcionalidad básica de Mercurial no es suficiente para usted,
+es muy fácil extenderlo. Mercurial se comporta muy bien con tareas de
+scripting y su limpieza interna junto con su implementación en Python
+permiten añadir características fácilmente en forma de extensiones.
+Hay un buen número de extensiones útiles y populares en este momento,
+desde ayudar a identificar fallos hasta mejorar su desempeño.
+
+\section{Comparación de Mercurial con otras herramientas}
+
+Antes de leer, por favor tenga en cuenta que esta sección
+necesariamente refleja mis propias experiencias, intereses y (tengo que
+decirlo) mis preferencias. He usado cada una de las herramientas de
+control de versiones listadas a continuación, y en muchos casos por
+varios años.
+
+
+\subsection{Subversion}
+
+Subversion es una herramienta de control de revisiones muy popular,
+desarrollada para reemplazar a CVS.  Tiene una arquitectura
+centralizada tipo cliente/servidor.
+
+Subversion y Mercurial tienen comandos con nombres similares para hacer
+las mismas operaciones, por lo que si le son familiares en una, será
+sencillo aprender a usar la otra. Ambas herramientas son portables en
+todos los sistemas operativos populares.
+
+Antes de la versión 1.5, Subversion no tenía soporte para fusiones. En
+el momento de la escritura, sus capcidades para llevar cuenta de las
+funciones son nuevas,
+\href{http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword}{complicadas
+  y poco estables\ndt{buggy}}.
+
+Mercurial tiene una ventaja considerable en desempeño sobre
+Subversion en cualquier operación de control de revisiones que yo haya
+medido. He medido sus ventajas con factores desde dos hasta seis veces
+comparando con almacenamiento de ficheros \emph{ra\_local}
+Subversion~1.4.3, el cual es el método de acceso más rápido.  En los
+escenarios más realistas incluyendo almacenamiento con la red de por
+medio, Subversion se encuentra en desventaja aún mayor. Dado que casi
+todas las órdenes de Subversion deben tratar con el servidor y
+Subversion no tiene utilidades de replicación adecuadas, la capacidad
+del servidor y el ancho de banda se convierten en cuellos de botella
+para proyectos modestamente grandes.
+
+Adicionalmente, Subversion tiene un sobrecosto considerable en
+almacenamiento para evitar transacciones por red en algunas
+operaciones,
+tales como encontrar ficheros modificados (\texttt{status}) y desplegar
+información frente a la revisión actual (\texttt{diff}).  Como
+resultado, la copia de trabajo de Subversion termina siendo del mismo
+tamaño o más grande que un repositorio de Mercurial y el directorio de
+trabajo, a pesar de que el repositorio de Mercurial contiene el
+historial completo  del proyecto.
+
+Subversion tiene soporte amplio de otras herramientas. Mercurial por
+ahora está bastante atrás en este aspecto.  Esta diferencia está
+disminuyendo, y algunas de las herramientas GUI\ndt{Interfaz de
+  Usuario Gráfica}, eclipsan sus equivalentes de Subversion. Al igual
+que Mercurial, Subversion tiene un excelente manual de usuario.
+
+Dado que Subversion no almacena el historial de revisiones en el
+cliente, es muy bueno para administrar proyectos que tienen muchos
+ficheros binarios grandes y opacos. Si consigna cincuenta revisiones
+de un fichero de 10MB que no es comprimible, el esapacio en el cliente
+de Subversion se mantendrá constante mientras que el espacio usado por
+cualquier Sistema Distribuido de Control de Revisiones crecerá
+rápidamente en proporción con el número de revisiones, debido a que
+las diferencias entre cada revisión es grande.
+
+Adicionalmente, generalmente es difícil o más bien, imposible mezclar
+diferentes versiones de un fichero binario. La habilidad de Subversion
+para permitirle al usuario poner una cerradura  a un fichero, de modo
+que tenga un permiso exclusivo para consignar cambios, puede ser una
+ventaja significativa en un proyecto donde los ficheros binarios sean
+usados ampliamente.
+
+Mercurial puede importar el historial de revisiones de un repositorio
+de Subversion. También puede exportar el historial de revisiones a un
+repositorio de Subversion.  De esta forma es sencillo ``dar un
+vistazo'' y usar Mercurial y Subversion en paralelo antes de decidirse
+a dar el paso. La conversión del historial es incremental, de modo
+que puede aplicar una conversión inicial, y después conversiones
+pequeñas y adicionales posteriormente para traer nuevos cambios.
+
+\subsection{Git}
+
+Git es una herramienta distribuida de control de revisiones
+desarrollada para administrar el arbol del kernel de Linux.  Al igual
+que Mercurial los principios de su diseño fueron influenciados por 
+Monotone.
+
+Git tiene un conjunto de órdenes muy grande; en la versión~1.5.0
+ofrece~139 órdenes individuales.  Tiene cierta reputación de ser
+difícil de aprender. Comparado con Git, Mercurial tiene un fuerte
+enfoque hacia la facilidad.
+
+En términos de rendimiento, Git es extremadamente rápido. En muchos
+casos, es más rápido que Mercurial, por lo menos en Linux, mientras
+que Mercurial se comporta mejor en otras operaciones.  De todas
+maneras en Windows, el desempeño y el nivel general de soporte que
+ofrece Git, al momento de la escritura, está bastante atrás de
+Mercurial.
+
+Mientras que el repositorio de Mercurial no requiere mantenimiento, el
+repositorio de Git requiere frecuentes ``reempaquetados'' de sus metadatos.
+Sin estos, el desempeño se degrada y el uso de espacio crece rápidamente. Un
+servidor que contenga repositorios de Git que no sean reempacados
+rigurosa y frecuentemente requerirá trabajo intenso de disco durante
+las copias de seguridad, y ha habido situaciones en copias de
+seguridad diaria que toman más de~24 horas como resultado. Un
+repositorio recién reempacado de Git es un poco más pequeño que un
+repositorio de Mercurial, pero un repositorio sin reempacar es varios
+órdenes de magnitud más grande.
+
+El corazón de Git está escrito en C.  Muchas órdenes de Git están
+implementadas como guiones de línea de comandos o de Perl y la calidad de esos
+guiones varía ampliamente. He encontrado muchas situaciones en las
+cuales los guiones no tuvieron en cuenta la presencia de errores que
+podrían haber sido fatales.
+
+Mercurial puede importar el historial de revisiones de un repositorio
+de Git.
+
+\subsection{CVS}
+
+CVS es probablemente la herramienta de control de revisiones más
+ampliamente usada en el planeta.  Debido a su edad y su poca pulcritud
+interna, ha sido ligeramente mantenida en muchos años.
+
+Tiene una arquitectura centralizada cliente/servidor. No agrupa
+cambios relacionados en consignaciones atómicas, pemitiendo que con
+facilidad la gente ``rompa la construcción'': una persona puede
+consignar exitósamente parte del cambio y estar bloqueada por la
+necesidad de una mezcla, forzando a otras personas a ver solamente una
+porción del trabajo que estaban buscando hacer.  Esto afecta también
+la forma como usted trabaja con el historial del proyecto. Si quiere
+ver todas las modificaciones que alguien hizo como parte de una tarea,
+necesitará inspeccionar manualmente las descripciones y las marcas de
+tiempo de cambio de cada fichero involucrado (esto, si usted saber
+cuáles eran tales ficheros).
+
+CVS tiene una noción confusa de etiquetas y ramas que yo no trataría
+incluso de describir.  No soporta renombramiento de ficheros o
+directorios adecuadamente, facilitando el corromper un
+repositorio. Casi no tiene chequeo de consistencia interna, por lo
+tanto es casi imposible identificar por que o cómo se corrompió un
+repositorio. Yo no recomendaría un repositorio de CVS para proyecto
+alguno, ni existente ni nuevo.
+
+Mercurial puede importar el historial de revisiones de CVS.  De todas
+maneras hay ciertas precauciones que aplican; las cuales también son
+necesarias para cualquier herramienta importadora de historial de
+CVS. Debido a la falta de atomicidad de cambios y el no versionamiento
+de la jerarquía del sistema de ficheros, es imposible reconstruir
+completamente el historial de CVS con precisión; hay cierto trabajo de
+conjetura involucrado y los renombramientos tampoco se
+mostrarán. Debido a que gran parte de la administración avanzada de
+CVS tiene que hacerse manualmente y por lo tanto es proclive al error,
+es común que los importadores de CVS encuentren muchos problemas con
+repositorios corruptos (marcas de tiempo totalmente desubicadas y
+ficheros que han permanecido con candados por más de una década son
+dos de los problemas menos interesantes de los que puedo retomar de mi
+experiencia personal).
+
+Mercurial puede importar el historial de revisiones de un repositorio
+CVS.
+
+\subsection{Herramientas comerciales}
+
+Perforce tiene una arquitectura centralizada cliente/servidor sin
+almacenamiento de dato alguno de caché en el lado del cliente. A diferencia de
+las herramientas modernas de control de revisiones, Perforce requiere
+que un usuario ejecute un comando para informar al servidor acerca de
+todo fichero que se vaya a editar.
+
+El rendimiento de Perforce es muy bueno para equipos pequeños, pero se
+degrada rápidamente cuando el número de usuarios va más allá de pocas
+docenas. Instalaciones modestamente grandes de Perforce requiere la
+organización de proxies para soportar la carga que sus usuarios generan.
+
+\subsection{Elegir una herramienta de control de revisiones}
+
+Con la excepción de CVS, toda las herramientas que se han listado
+anteriormente tienen fortalezas únicas que las hacen valiosas de acuerdo al
+tipo de trabajo. No hay una única herramienta de control de revisiones
+que sea la mejor en todas las situaciones.
+
+Por ejemplo, Subversion es una buena elección para trabajar con
+edición frecuente de ficheros binarios, debido a su naturaleza
+centralizada y soporte para poner candados a ficheros.
+
+Personalmente encuentro las propiedades de simplicidad, desempeño, y
+buen soporte de fusiones de Mercurial una combinación llamativa que ha
+dado buenos frutos por varios años.
+
+
+\section{Migrar de otra herramienta hacia Mercurial}
+
+Mercurial viene con una extensión llamada \hgext{convert}, que puede
+importar historiales de revisiones de forma incremental desde varias
+herramientas de control de revisiones. Por ``incremental'', quiero
+decir que puede migrar toda el historial de un proyecto en una primera
+instancia y después volver a ejecutar la migración posteriormente para
+obtener los nuevos cambios que han sucedido después de la migración
+inicial.
+
+A continuación presentamos las herramientas de revisiones que soporta
+el comando \hgext{convert}:
+\begin{itemize}
+\item Subversion
+\item CVS
+\item Git
+\item Darcs
+\end{itemize}
+
+Adicionalmente, \hgext{convert} puede exportar cambios de Mercurial
+hacia Subversion.  Lo que hace posible probar Subversion y Mercurial
+en paralelo antes de lanzarse a un migración total, sin arriesgarse a
+perder trabajo alguno.
+
+El comando \hgxcmd{conver}{convert} es sencillo de usar. Basta con
+apuntarlo hacia la ruta o el URL del repositorio fuente, opcionalmente
+darle el nombre del nombre del repositorio destino y comenzará a hacer
+su trabajo. Después de la conversión inicial, basta con invocar de
+nuevo el comando para importar cambios nuevos.
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
Binary file es/kdiff3.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/license.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,142 @@
+\chapter{Licencia de Publicación Abierta}
+\label{cha:opl}
+
+Versión 1.0, 8 Junio de 1999
+
+\section{Requerimientos en versiones modificadas y no modificadas}
+
+Los trabajos bajo Publicación Abierta pueden reproducirse y
+distribuirse enteros o en porciones, en cualquier medio físico o
+electrónico, siempre y cuando se respeten los términos de esta 
+licencia, y se incorpore esta licencia o su referencia (con cualquiera
+de las opciones elegidas por el autor y el editor) en la reproducción.
+
+A continuación mostramos la forma correcta de incorporar por referencia:
+
+\begin{quote}
+  Copyright (c) \emph{año} por \emph{nombre del autor o designado}.
+  Este material puede distribuirse solamente bajo los términos y
+  condiciones especificados por la Licencia de Publicación Abierta,
+  v\emph{x.y} o  posterior (la última versión disponible está en
+  \url{http://www.opencontent.org/openpub/}).
+\end{quote}
+
+La referencia debe estar seguida inmediatamente por cualquier opción
+elegida por el(os) autor(es) y/o editor(es) del documento (consulte la
+sección~\ref{sec:opl:options}).
+
+Se permite la redistribución comercial de los materiales sujetos a la
+Publicación Abierta.
+
+Cualquier publicación en forma estándar de libro (papel) requerirá
+citar al editor y autor original.  Los nombres del editor y el autor
+aparecerán en todas las superficies externas del libro.  En todas las
+superficies externas el nombre del editor deberá aparecer en tamaño de
+la misma medida que el título del trabajo y será citado como poseedor
+con respecto al título.
+
+\section{Derechos de reproducción}
+
+El derecho de reproducción de cada Publicación Abierta pertenece
+al(os) autor(es) o designados.
+
+\section{Alcance de la licencia}
+
+Los términos de licencia dsecritos aplican a todos los trabajos bajo
+licencia de publicación abierta a menos que se indique de otra forma
+en este documento.
+
+La simple agregación de trabajos de Publicación Abierta o una porción
+de trabajos de Publicación Abierta con otros trabajos o programas en
+el mismo medio no causarán que esta licencia se aplique a los otros
+trabajos.  Los agregados deberán contener una nota que especifique la
+inclusión de matrial de Publicación Abierta y una nota de derechos de
+reproducción acorde.
+
+\textbf{Separabilidad}. Si cualquier porción de esta licencia no es
+aplicable en alguna jurisdicción, las porciones restantes se
+mantienen.
+
+\textbf{Sin garantía}.  Los trabajos de Publicación Abierta se
+licencian y ofrecen ``como están'' sin garantía de ninguna clase,
+expresa o implícita, incluyendo, pero no limitados a las garantías de
+mercabilidad y adaptabilidad para un propósito particular o garantía
+de no infracción.
+
+\section{Requerimientos sobre trabajos modificados}
+
+Todas las versiones modificadas de documentos cubiertos por esta
+licencia, incluyendo traducciones, antologías, compilaciones y
+documentos parciales, deben seguir estos requerimientos:
+
+\begin{enumerate}
+\item La versión modificada debe estar etiquetada como tal.
+\item La persona que hace la modificación debe estar identificada y la
+  modificación con fecha.
+\item El dar crédito al autor original y al editor si se requiere de
+  acuerdo a las prácticas académicas de citas.
+\item Debe identificarse el lugar del documento original sin
+  modificación.
+\item No puede usarse el(os) nombre(s) del autor (de los autores) para
+  implicar relación alguna con el documento resultante sin el permiso
+  explícito del autor (o de los autores).
+\end{enumerate}
+
+\section{Recomendaciones de buenas prácticas}
+
+Adicional a los requerimientos de esta licencia, se solicita a los
+redistribuidores y se recomienda en gran medida que:
+
+\begin{enumerate}
+\item Si está distribuyendo trabajaos de Publicación Abierta en copia
+  dura o CD-ROM, envíe una notificación por correo a los autores
+  acerca de su intención de redistribuir por lo menos con treinta días
+  antes de que su manuscrito o el medio se congelen, para permitir a
+  los autores tiempo para proveer documentos actualizados.  Esta
+  notificación debería describir las modificaciones, en caso de que
+  haya, al documento.
+\item Todas las modificaciones sustanciales (incluyendo eliminaciones)
+  deben estar marcadas claramente en el documento o si no descritas en
+  un adjunto del documento.
+\item Finalmente, aunque no es obligatorio bajo esta licencia, se
+  considera de buenos modales enviar una copia gratis de cualquier
+  expresión en copia dura o CD-ROM de un trabajo licenciado con
+  Publicación Abierta a el(os) autor(es).
+\end{enumerate}
+
+\section{Opciones de licencia}
+\label{sec:opl:options}
+
+El(os) autor(es) y/o editor de un documento licenciado con Publicación
+Abierta pueden elegir ciertas opciones añadiendo información a la
+referencia o a la copia de la licencia.  Estas opciones se consideran
+parte de la instancia de la licencia y deben incluirse con la
+licencia (o su incorporación con referencia) en trabajos derivados.
+
+\begin{enumerate}[A]
+\item Prohibir la distribución de versiones substancialmente
+  modificadas sin el permiso explícito del(os) autor(es).  Se definen
+  ``modificaciones substanciales'' como cambios en el contenido
+  semántico del documento, y se excluyen simples cambios en el formato
+  o correcciones tipográficas.
+
+  Para lograr esto, añada la frase ``Se prohibe la distribución de
+  versiones substancialmente modificadas de este documento sin el
+  permiso explícito del dueño de los derechos de reproducción.'' a la
+  referencia de la licencia o a la copia.
+
+\item Está prohibido prohibir cualquier publicación de este trabajo o
+  derivados como un todo o una parte en libros estándar (de papel) con
+  propósitos comerciales a menos que se obtenga un permiso previo del
+  dueño de los derechos de reproducción.
+
+  Para lograrlo, añada la frase ``La distribución del trabajo o
+  derivados en cualquier libro estándar (papel) se prohibe a menos que
+  se obtenga un permiso previo del dueño de los derechos de
+  reproducción.'' a la referencia de la licencia o la copia.
+\end{enumerate}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/metadata.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="metadata.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2479" />
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path2944"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="232.14286"
+     inkscape:cy="519.03485"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="181"
+     inkscape:window-y="58"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 326.94646,467.18359 L 326.94646,510.98123"
+       id="path1910"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2962"
+       inkscape:connection-start="#rect2764" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 326.94646,531.98123 L 326.94646,591.77887"
+       id="path1912"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2962"
+       inkscape:connection-end="#rect3000" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 316.1622,531.98123 L 192.30212,652.57648"
+       id="path1916"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect3038"
+       inkscape:connection-start="#rect2962" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 254.23217,467.18359 L 254.23216,510.98123"
+       id="path3088"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect1872"
+       inkscape:connection-end="#rect2960" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 254.23215,531.98123 L 254.23215,591.77887"
+       id="path3090"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2960"
+       inkscape:connection-end="#rect2998" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#484848;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4.5, 1.5;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 248.84002,531.98123 L 186.90999,652.57648"
+       id="path3092"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2960"
+       inkscape:connection-end="#rect3038" />
+    <rect
+       style="fill:#7b7df5;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1872"
+       width="51.42857"
+       height="20"
+       x="228.51788"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2764"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2766"
+       width="51.42857"
+       height="20"
+       x="155.80359"
+       y="446.68359" />
+    <rect
+       style="fill:#cacbfb;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2768"
+       width="51.42857"
+       height="20"
+       x="83.089294"
+       y="446.68359" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,456.68359 L 155.30359,456.68359"
+       id="path2770"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2768"
+       inkscape:connection-end="#rect2766" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,456.68359 L 228.01788,456.68359"
+       id="path2772"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2766"
+       inkscape:connection-end="#rect1872" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,456.68359 L 300.73218,456.68359"
+       id="path2774"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect1872"
+       inkscape:connection-end="#rect2764" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.303571,456.68359 L 82.589294,456.68359"
+       id="path2778"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2768" />
+    <rect
+       style="fill:#84f57b;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2960"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2962"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2964"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="511.48123" />
+    <rect
+       style="fill:#cefbca;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2966"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="511.48123" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,521.48121 L 155.30359,521.48121"
+       id="path2968"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,521.48121 L 228.01788,521.48121"
+       id="path2970"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,521.48121 L 300.73218,521.48121"
+       id="path2972"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,521.48121 L 82.5893,521.48121"
+       id="path2974"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2998"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3000"
+       width="51.42857"
+       height="20"
+       x="301.23218"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3002"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="592.27887" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3004"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="592.27887" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,602.27884 L 155.30359,602.27884"
+       id="path3006"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,602.27884 L 228.01788,602.27884"
+       id="path3008"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 280.44645,602.27884 L 300.73218,602.27884"
+       id="path3010"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,602.27884 L 82.5893,602.27884"
+       id="path3012"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#ffced6;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3034"
+       width="51.42857"
+       height="20"
+       x="228.51787"
+       y="653.07648" />
+    <rect
+       style="fill:#f57b8f;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3038"
+       width="51.42857"
+       height="20"
+       x="155.80357"
+       y="653.07648" />
+    <rect
+       style="fill:#fbcad2;fill-opacity:1;stroke:#595959;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3040"
+       width="51.42857"
+       height="20"
+       x="83.089287"
+       y="653.07648" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 135.01786,663.07646 L 155.30359,663.07646"
+       id="path3042"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 207.73216,663.07646 L 228.01788,663.07646"
+       id="path3044"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#747474;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 62.30358,663.07646 L 82.5893,663.07646"
+       id="path3048"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.072548"
+       y="432.64789"
+       id="text3094"><tspan
+         sodipodi:role="line"
+         id="tspan3096"
+         x="82.072548"
+         y="432.64789">Bitácora de cambios</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.306923"
+       y="498.97327"
+       id="text3098"><tspan
+         sodipodi:role="line"
+         id="tspan3100"
+         x="82.306923"
+         y="498.97327">Manifiesto</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="82.14286"
+       y="580.08569"
+       id="text3102"><tspan
+         sodipodi:role="line"
+         id="tspan3104"
+         x="82.14286"
+         y="580.08569">Bitácora de archivos</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/mq-collab.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,428 @@
+\chapter{Usos avanzados de las Colas de Mercurial}
+\label{chap:mq-collab}
+
+Auunque es fácil aprender los usos más directos de las Colas de
+Mercurial, tener algo de disciplina junto con algunas de las
+capacidadees menos usadas de MQ hace posible trabajar en entornos de
+desarrollo complejos.
+
+En este capítulo, usaré como ejemplo una técnica que he usado para
+administrar el desarrollo de un controlador de dispositivo Infiniband
+para el kernel de Linux. El controlador en cuestión es grande
+(al menos en lo que se refiere a controladores), con 25,000 líneas de
+código esparcidas en 35 ficheros fuente. Es mantenido por un equipo
+pequeño de desarrolladores. 
+
+Aunque mucho del material en este capítulo es específico de Linux, los
+mismos principios aplican a cualquier base de código de la que usted
+no sea el propietario principal, y sobre la que usted necesita hacer
+un montón de desarrollo.
+
+\section{El problema de múltiples objetivos}
+
+El kernel de Linux cambia con rapidez, y nunca ha sido estable
+internamente; los desarrolladores hacen cambios drásticos entre
+%TODO no encontré una traducción adecuada para "release". Por eso el
+%cambio
+versiones frecuentemente. Esto significa que una versión del
+controlador que funciona bien con una versión particular del kernel ni
+siquiera \emph{compilará} correctamente contra, típicamente, cualquier
+otra versión.
+
+Para mantener un controlador, debemos tener en cuenta una buena
+cantidad de versiones de Linux en mente.
+\begin{itemize}
+\item Un objetivo es el árbol de desarrollo principal del kernel de
+  Linux. En este caso el mantenimiento del código es compartido
+  parcialmente por otros desarrolladores en la comunidad del kernel, 
+  %TODO drive-by. 
+  quienes hacen modificaciones ``de-afán'' al controlador a medida que 
+  desarrollan y refinan subsistemas en el kernel.
+  %TODO backport
+\item También mantenemos algunos ``backports'' para versiones antiguas
+  del kernel de Linux, para dar soporte a las necesidades de los
+  clientes que están corriendo versiones antiguas de Linux que no
+  incorporan nuestros controladores. (Hacer el \emph{backport} de un
+  pedazo de código es modificarlo para que trabaje en una versión
+  de su entorno objetivo anterior a aquella para la cual fue escrito.)
+\item Finalmente, nosotros liberamos nuestro software de acuerdo a un
+  cronograma que no necesariamente está alineado con el que usan los
+  distribuidores de Linux y los desarrolladores del kernel, así que
+  podemos entregar nuevas características a los clientes sin forzarlos
+  a actualizar kernels completos o distribuciones.
+\end{itemize}
+
+\subsection{Aproximaciones tentadoras que no funcionan adecuadamente}
+
+Hay dos maneras estándar de mantener una porción de software que debe
+funcionar en muchos entornos diferentes.
+
+La primera es mantener varias ramas, cada una pensada para un único
+entorno. El problema de esta aproximación es que usted debe tener una
+disciplina férrea con el flujo de cambios entre repositorios. Una
+nueva característica o un arreglo de fallo deben empezar su vida en un
+repositorio ``prístino'', y luego propagarse a cada repositorio de
+backport. Los cambios para backports están más limitados respecto a
+las ramas a las que deberían propagarse; un cambio para backport que
+es aplicado a una rama en la que no corresponde probablemente hará que
+el controlador no compile.
+
+La segunda es mantener un único árbol de código fuente lleno de
+declaraciones que activen o desactiven secciones de código dependiendo
+del entorno objetivo. Ya que estos ``ifdefs'' no están permitidos en
+el árbol del kernel de Linux, debe seguirse algún proceso manual o
+automático para eliminarlos y producir un árbol limpio. Una base de
+código mantenida de esta manera se convierte rápidamente en un nido de
+ratas de bloques condicionales que son difíciles de entender y
+mantener.
+
+%TODO canónica?
+Ninguno de estos enfoques es adecuado para situaciones en las que
+usted no es ``dueño'' de la copia canónica de un árbol de fuentes. En
+el caso de un controlador de Linux que es distribuido con el kernel
+estándar, el árbol de Linux contiene la copia del código que será
+considerada por el mundo como la canónica. La versión oficial de
+``mi'' controlador puede ser modificada por gente que no conozco, sin
+que yo siquiera me entere de ello hasta después de que los cambios
+aparecen en el árbol de Linus.
+
+Estos enfoques tienen la debilidad adicional de dificultar la
+%TODO upstream. no no es río arriba
+generación de parches bien formados para enviarlos a la versión
+oficial.
+
+En principio, las Colas de Mercurial parecen ser un buen candidato
+para administrar un escenario de desarrollo como el de arriba. Aunque
+este es de hecho el caso, MQ tiene unas cuantas características
+adicionales que hacen el trabajo más agradable.
+
+\section{Aplicar parches condicionalmente mediante guardias}
+
+Tal vez la mejor manera de conservar la cordura con tantos entornos
+objetivo es poder escoger parches específicos para aplicar para cada
+situación. MQ provee una característica llamada ``guardias''
+(que se origina del comando \texttt{guards} de Quilt) que hace
+precisamente ésto. Para empezar, creemos un repositorio sencillo para
+experimentar.
+\interaction{mq.guards.init}
+Esto nos brinda un pequeño repositorio que contiene dos parches que no
+tienen ninguna dependencia respecto al otro, porque tocan ficheros
+diferentes.
+
+La idea detrás de la aplicación condicional es que usted puede
+``etiquetar'' un parche con un \emph{guardia}, que simplemente es una
+cadena de texto de su elección, y luego decirle a MQ que seleccione
+guardias específicos para usar cuando aplique parches. MQ entonces
+aplicará, u omitirá, un parche vigilado, dependiendo de los guardias
+que usted haya seleccionado.
+
+Un parche puede tener una cantidad arbitraria de guardias; cada uno es
+\emph{positivo} (``aplique el parche si este guardia es
+seleccionado'') o \emph{negativo} (``omita este parche si este guardia
+es seleccionado''). Un parche sin guardias siempre es aplicado.
+
+\section{Controlar los guardias de un parche}
+
+%TODO tal vez no decir determinar, sino definir?
+El comando \hgxcmd{mq}{qguard} le permite determinar qué guardias
+deben aplicarse a un parche, o mostrar los guardias que están en
+efecto. Sin ningún argumento, el comando muestra los guardias del
+parche actual de la parte más alta de la pila.
+\interaction{mq.guards.qguard}
+Para poner un guardia positivo en un parche, prefije el nombre del
+guardia con un ``\texttt{+}''.
+\interaction{mq.guards.qguard.pos}
+Para poner un guardia negativo en un parche, prefije el nombre del
+guardia con un ``\texttt{-}''.
+\interaction{mq.guards.qguard.neg}
+
+\begin{note}
+  El comando \hgxcmd{mq}{qguard} \emph{pone} los guardias en un
+  parche; no los \emph{modifica}. Esto significa que si usted ejecuta
+  \hgcmdargs{qguard}{+a +b} sobre un parche, y luego
+  \hgcmdargs{qguard}{+c} en el mismo parche, el único guardia sobre el
+  parche después del comando será \texttt{+c}.
+\end{note}
+
+Mercurial almacena los guardias en el fichero \sfilename{series}; la
+forma en que son almacenados es fácil tanto de entender como de editar
+a mano. (En otras palabras, usted no tiene que usar el comando
+\hgxcmd{mq}{qguard} si no lo desea; está bien simplemente editar el
+fichero \sfilename{series})
+\interaction{mq.guards.series}
+
+\section{Selecccionar los guardias a usar}
+
+%TODO tal vez no decir determinar, sino definir?
+El comando \hgxcmd{mq}{qselect} determina qué guardias están activos
+en cualquier momento. El efecto de esto es determinar qué parches
+aplicará MQ la próxima vez que usted ejecute \hgxcmd{mq}{qpush}.  No
+tiene ningún otro efecto; en particular, no hace nada a los parches
+que ya han sido aplicados.
+
+Sin argumentos, el comando \hgxcmd{mq}{qselect} lista los guardias en
+efecto actualmente, uno por cada línea de salida. Cada argumento es
+tratado como el nombre de un guardia a aplicar.
+\interaction{mq.guards.qselect.foo}
+Si está interesado, los guardias seleccionados actualmente están
+almacenados en el fichero \sfilename{guards}.
+\interaction{mq.guards.qselect.cat}
+Podemos ver el efecto que tienen los guardias seleccionados cuando
+ejecutamos \hgxcmd{mq}{qpush}.
+\interaction{mq.guards.qselect.qpush}
+
+Un guardia no puede empezar con un  caracter ``\texttt{+}'' o
+``\texttt{-}''. El nombre del guardia no debe contener espacios en
+blanco, pero muchos otros caracteres son aceptables. Si usted trata de
+usar un guardia con un nombre inválido, MQ se quejará:
+\interaction{mq.guards.qselect.error} 
+Cambiar los guardias seleccionados cambia los parches que son
+aplicados.
+\interaction{mq.guards.qselect.quux} 
+Usted puede ver en el ejemplo de abajo que los guardias negativos
+tienen precedencia sobre los guardias positivos.
+\interaction{mq.guards.qselect.foobar}
+
+\section{Reglas de MQ para aplicar parches}
+
+Las reglas que MQ usa para decidir si debe aplicar un parche son las
+siguientes.
+\begin{itemize}
+\item Un parche sin guardias es aplicado siempre.
+\item Si el parche tiene algún guardia negativo que corresponda con
+  cualquiera de los guardias seleccionados, se salta el parche.
+\item Si el parche tiene algún guardia positivo que corresponda con
+  cualquiera de los guardias seleccionados, se aplica el parche.
+\item Si el parche tiene guardias positivos o negativos, pero ninguno
+  corresponde con cualquiera de los guardias seleccionados, se salta
+  el parche.
+\end{itemize}
+
+\section{Podar el entorno de trabajo}
+
+En el trabajo del controlador de dispositivo que mencioné
+anteriormente, yo no aplico los parches a un árbol normal del kernel
+de Linux. En cambio, uso un repositorio que sólo contiene una
+instantánea de los ficheros fuente y de cabecera que son relevantes
+para el desarrollo de Infiniband. Este repositorio tiene un~1\% del
+tamaño del repositorio del kernel, por lo que es más fácil trabajar
+con él.
+
+Luego escojo una versión ``base'' sobre la cual son aplicados los
+parches. Es una instantánea del árbol del kernel de Linux en una
+revisión de mi elección. Cuando tomo la instantánea, almaceno el ID de
+conjunto de cambios en el mensaje de consignación. Ya que la
+instantánea preserva la ``forma'' y el contenido de las partes
+relevantes del árbol del kernel, puedo aplicar mis parches sobre mi
+pequeño repositorio o sobre un árbol normal del kernel.
+
+Normalmente, el árbol base sobre el que se aplican los parches debería
+ser una instantánea de un árbol de desarrollo muy reciente. Esto
+facilita mucho el desarrollo de parches que puedan ser enviados al
+árbol oficial con pocas o ninguna modificación.
+
+\section{Dividir el fichero \sfilename{series}}
+
+Yo categorizo los parches en el fichero \sfilename{series} en una
+serie de grupos lógicos. Cada sección de parches similares empieza con
+un bloque de comentarios que describen el propósito de los parches que
+le siguen.
+
+La secuencia de grupos de parches que mantengo se muestra a
+continuación. El orden de los grupos es importante; explicaré porqué
+luego de que presente los grupos.
+\begin{itemize}
+\item El grupo ``aceptado''. Son parches que el equipo de desarrollo
+  ha enviado al mantenedor del subsistema Infiniband, y que él ha
+  aceptado, pero que no están presentes en la instantánea en la cual
+  está basada el repositorio pequeño. Estos son parches de
+  ``sólo lectura'', presentes únicamente para transformar el árbol en
+  un estado similar al del repositorio del mantenedor oficial.
+\item El grupo ``revisar''. Parches que yo he enviado, pero sobre los
+  que que el mantenedor oficial ha solicitado modificaciones antes de
+  aceptarlos.
+\item El grupo ``pendiente''. Parches que no he enviado al mantenedor
+  oficial, pero que ya están terminados. Estos parches serán de
+  ``sólo lectura'' por un buen tiempo. Si el mantenedor oficial los
+  acepta cuando los envíe, los moveré al final del grupo ``aceptado''.
+  Si él solicita que modificaciones en alguno de ellos, los moveré al
+  principio del grupo ``revisar''.
+\item El grupo ``en proceso''. Parches que están siendo activamente
+  desarrollados, y no deberían ser enviados a ninguna parte aún.
+\item El grupo ``backport''. Parches que adaptan el árbol de fuentes a
+    versiones antiguas del árbol del kernel.
+\item El grupo ``no enviar''. Parches que por alguna razón nunca deben
+  ser enviados al mantenedor oficial del kernel. Por ejemplo, alguno
+  de esos parches podría cambiar las cadenas de identificación
+  embebidas del controlador para hacer más fácil la distinción, en
+  pruebas de campo, entre una versión del controlador de
+  salida-del-árbol  y una versión entregada por un vendedor de alguna
+  distribución.
+\end{itemize}
+
+Ahora volvemos a las razones para ordenar los grupos de parches en
+esta manera. Quisiéramos que los parches del fondo de la pila sean tan
+estables como sea posible, para no tener que revisar parches más
+arriba debido a cambios de contexto. Poner los parches que nunca
+cambiarán en el primer lugar del fichero \sfilename{series} sirve a
+este propósito.
+
+También desearíamos que los parches que sabemos que debemos modificar
+sean aplicados sobre un árbol de fuentes que se parezca al oficial
+tanto como sea posible. Es por esto que mantenemos los parches
+aceptados disponibles por una buena cantidad de tiempo.
+
+Los parches ``backport'' y ``no enviar'' flotan al final del fichero
+\sfilename{series}. Los parches de backport deben ser aplicados encima
+de todos los otros parches, y los parches ``no enviar'' pueden
+perfectamente quedarse fuera del camino.
+
+\section{Mantener la serie de parches}
+
+En mi trabajo, uso varios guardias para controlar qué parches deben
+ser aplicados.
+
+\begin{itemize}
+\item Los parches ``aceptados'' son vigilados con
+  \texttt{accepted}. Yo habilito este guardia la mayoría de las veces.
+  Cuando aplico los parches sobre un árbol donde los parches ya están
+  %TODO no será ``desactivar este guardia''? si sí, corregir versión
+  %en inglés también
+  presentes, puedo desactivar este parche, y los parches que lo siguen
+  se aplicarán sin problemas.
+\item Los parches que están ``terminados'', pero no han sido enviados,
+  no tienen guardias. Si estoy aplicando la pila de parches a una
+  copia del árbol oficial, no necesito habilitar ningún guardia para
+  obtener un árbol de fuentes razonablemente seguro.
+\item Los parches que necesitan revisión antes de ser reenviados
+  tienen el guardia \texttt{rework}.
+\item Para aquellos parches que aún están bajo desarrollo, uso
+  \texttt{devel}.
+\item Un parche de backport puede tener varios guardias, uno para cada
+  versión del kernel a la que aplica. Por ejemplo, un parche que hace
+  backport de un segmento de código a~2.6.9 tendrá un guardia~\texttt{2.6.9}.
+\end{itemize}
+La variedad de guardias me brinda una flexibilidad considerable para
+determinar qué tipo de árbol de fuentes acabaré por obtener. En la
+mayoría de las situaciones, la selección de guardias apropiados es
+automatizada durante el proceso de compilación, pero puedo ajustar
+manualmente los guardias a usar para circunstancias poco comunes.
+
+\subsection{El arte de escribir parches de backport}
+
+Al usar MQ, escribir un parche de backport es un proceso simple. Todo
+lo que dicho parche debe hacer es modificar una sección de código que
+usa una característica del kernel que no está presente en la versión
+anterior del kernel, para que el controlador siga funcionando
+correctamente en esa versión anterior.
+
+Una meta útil al escribir un buen parche de backport es hacer parecer
+que el código hubiera sido escrito para la versión vieja del kernel
+que usted tiene como objetivo. Entre menos intrusivo el parche, más
+fácil será entenderlo y mantenerlo. Si usted está escribiendo una
+colección de parches de backport para evitar el efecto de ``nido de
+ratas'' de tener muchos \texttt{\#ifdef}s (secciones de código fuente
+que sólo son usados condicionalmente) en su código, no introduzca
+\texttt{\#ifdef}s dependientes de versiones específicas en los
+parches. En vez de eso, escriba varios parches, cada uno de ellos
+haciendo cambios incondicionales, y controle su aplicación usando
+guardias.
+
+Hay dos razones para ubicar los parches de backport en un grupo
+diferente, aparte de los parches ``regulares'' cuyos efectos son
+modificados por ellos. La primera es que mezclar los dos hace más
+difícil usar herramientas como la extensión \hgext{patchbomb} para
+automatizar el proceso de enviar los parches a un mantenedor oficial.
+La segunda es que un parche de backport puede perturbar el contexto en
+el que se aplica un parche regular subsecuente, haciendo imposible
+aplicar el parche normal limpiamente \emph{sin} que el parche de
+backport sea aplicado antes.
+
+\section{Consejos útiles para hacer desarrollo con MQ}
+
+\subsection{Organizar parches en directorios}
+
+Si está trabajando en un proyecto grande con MQ, no es difícil
+acumular un gran número de parches. Por ejemplo, tengo un repositorio
+de parches que contiene más de 250 parches.
+
+Si usted puede agrupar estos parches en categorías lógicas separadas,
+usted puede almacenarlos en diferentes directorios si lo desea; MQ no
+tiene problemas manejando nombres de parches que contienen separadores
+de ruta.
+
+\subsection{Ver el historial de un parche}
+\label{mq-collab:tips:interdiff}
+
+Si usted está desarrollando un conjunto de parches en un período de
+tiempo grande, es una buena idea mantenerlos en un repositorio, como
+se discutió en la sección~\ref{sec:mq:repo}.  Si lo hace, notará
+rápidamente que usar el comando \hgcmd{diff} para mirar el historial
+del repositorio no es viable. Esto es debido en parte a que usted está
+mirando la segunda derivada del código real (el diff de un diff), pero
+también porque MQ añade ruido al proceso al modificar las marcas de
+tiempo y los nombres de directorio cuando actualiza un parche.
+
+Sin embargo, usted puede usar la extensión \hgext{extdiff}, que es
+provisto junto con Mercurial, para convertir un diff de dos versiones
+de un parche en algo legible. Para hacer esto, usted necesitará un
+paquete de un tercero llamado
+\package{patchutils}~\cite{web:patchutils}.  Éste paquete provee un
+comando llamado \command{interdiff}, que muestra las diferencias entre
+dos diffs como un diff. Al usarlo en dos versiones del mismo diff,
+genera un diff que representa el diff de la primera a la segunda
+versión.
+
+Usted puede habilitar la extensión \hgext{extdiff} de la manera usual,
+añadiendo una línea a la sección \rcsection{extensions} de su \hgrc.
+\begin{codesample2}
+  [extensions]
+  extdiff =
+\end{codesample2}
+El comando  \command{interdiff} espera recibir los nombres de dos
+ficheros, pero la extensión \hgext{extdiff} le pasa un par de
+directorios al programa que ejecuta, cada uno de los cuales puede
+contener una cantidad arbitraria de ficheros. Por esto necesitamos un
+programa pequeño que ejecute \command{interdiff} en cada par de
+ficheros de estos dos directorios. Este programa está disponible como
+\sfilename{hg-interdiff} en el directorio \dirname{examples} del
+repositorio de código fuente que acompaña a este libro.
+\excode{hg-interdiff}
+
+Con el programa \sfilename{hg-interdiff} en la ruta de búsqueda de su
+intérprete de comandos, puede ejecutarlo como sigue, desde dentro de
+un directorio de parches MQ:
+\begin{codesample2}
+  hg extdiff -p hg-interdiff -r A:B my-change.patch
+\end{codesample2}
+Ya que usted seguramente querrá usar este comando tan largo a menudo,
+puede hacer que \hgext{hgext} lo haga disponible como un comando
+normal de Mercurial, editando de nuevo su \hgrc.
+\begin{codesample2}
+  [extdiff]
+  cmd.interdiff = hg-interdiff
+\end{codesample2}
+Esto le indica a \hgext{hgext} que ponga a disposición un comando
+\texttt{interdiff}, con lo que usted puede abreviar la invocación
+anterior de \hgxcmd{extdiff}{extdiff} a algo un poco más manejable.
+\begin{codesample2}
+  hg interdiff -r A:B my-change.patch
+\end{codesample2}
+
+\begin{note}
+    %TODO revisar redacción
+  El comando \command{interdiff} trabaja bien sólo si los ficheros
+  contra los cuales son generadas las versiones de un parche se
+  mantienen iguales. Si usted crea un parche, modifica los ficheros
+  subyacentes, y luego regenera el parche, \command{interdiff} podría
+  no producir ningún resultado útil.
+\end{note}
+
+La extensión \hgext{extdiff} es útil para más que solamente mejorar la
+presentación de los parches~MQ. Para leer más acerca de esto, vaya a
+la sección~\ref{sec:hgext:extdiff}.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/mq-ref.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,378 @@
+\chapter{Referencia de las Colas de Mercurial}
+\label{chap:mqref}
+
+\section{Referencia de órdenes MQ}
+\label{sec:mqref:cmdref}
+
+Si desea dar un vistazo a las órdenes que ofrece MQ, use la orden
+\hgcmdargs{help}{mq}.
+
+\subsection{\hgxcmd{mq}{qapplied}---imprimir los parches aplicados}
+
+La orden \hgxcmd{mq}{qapplied} imprime la pila actual de parches
+aplicados.  Los parches se imprimen en orden de antigüedad, primero
+los más antiguos y después los más recientes, por lo tanto el último
+parche de la lista es el que está en el ``tope''.
+
+\subsection{\hgxcmd{mq}{qcommit}---consignar cambios en la cola del repositorio}
+
+La orden \hgxcmd{mq}{qcommit} consigna cualquier cambio sobresaliente
+en el repositorio \sdirname{.hg/patches}.  Esta orden solamente
+funciona si el directorio \sdirname{.hg/patches} es un repositorio,
+p.e.~usted creó el directorio con
+\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} o ejecutó
+\hgcmd{init} en el directorio después de correr \hgxcmd{mq}{qinit}.
+
+Esta orden es un atajo para \hgcmdargs{commit}{--cwd .hg/patches}.
+
+\subsection{\hgxcmd{mq}{qdelete}---eliminar un parche del fichero
+  \sfilename{series}}
+
+La orden \hgxcmd{mq}{qdelete} elimina la entrada del fichero
+\sfilename{series} para el parche en el directorio
+\sdirname{.hg/patches}.  No sca el parche si ha sido aplicado.  De
+forma predeterminada no borra el fichero del parche; use la opción
+\hgxopt{mq}{qdel}{-f} para hacerlo.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qdel}{-f}] Elimina el fichero del parche.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qdiff}---imprimir la diferencia del último
+  parche aplicado}
+
+La orden \hgxcmd{mq}{qdiff} imprime un diff del parche más
+recientemente aplicado.  Es equivalente a \hgcmdargs{diff}{-r-2:-1}.
+
+\subsection{\hgxcmd{mq}{qfold}---fusionar (``integrar'') varios parches en
+  uno solo}
+
+La orden \hgxcmd{mq}{qfold} fusiona muchos parches en el último parche
+aplicado, de tal forma que el último parche aplicado es la unión de
+todos los cambios de los parches en cuestión.
+
+Los parches a fusionar no deben haber sido aplicados;
+\hgxcmd{mq}{qfold} saldrá indicando un error si alguno ha sido
+aplicado.  El orden en el cual los parches se pliegan es
+significativo; \hgcmdargs{qfold}{a b} significa ``aplique el parche
+más reciente, seguido de \texttt{a}, y seguido de \texttt{b}''.
+
+Los comentarios de los parches integrados se colocan al final de los
+comentarios del parche destino, con cada bloque de comentarios
+separado con tres asteriscos (``\texttt{*}'').  Se usa la opción
+\hgxopt{mq}{qfold}{-e} para editar el mensaje de consignación para el
+conjunto de cambios/parches después de completarse el pliegue.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qfold}{-e}] Edita el mensaje de consignación y la
+  descripción del parche del parche que se ha integrado.
+\item[\hgxopt{mq}{qfold}{-l}] Usa los contenidos del fichero dado como
+  el nuevo mensaje de consignación y descripción del parche para el
+  parche a integrar.
+\item[\hgxopt{mq}{qfold}{-m}] Usa el texto dado como el mensaje de
+  consignación y descripción del parche para el parche integrado.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qheader}---desplegar el encabezado/descripción
+  de un parche}
+
+La orden \hgxcmd{mq}{qheader} imprime el encabezado o descripción de
+un parche.  De forma predeterminada, imprime el encabezado del último
+parche aplicado. Si se da un argumento, imprime el encabezado del
+parche referenciado.
+
+\subsection{\hgxcmd{mq}{qimport}---importar el parche de un tercero en
+  la cola}
+
+La orden \hgxcmd{mq}{qimport} añade una entrada de un parche externo
+al fichero \sfilename{series} y copia el parche en el directorio
+\sdirname{.hg/patches}.  Añade la entrada inmediatamente después del
+último parche aplicado, pero no introduce el parche.
+
+Si el directorio \sdirname{.hg/patches} es un repositorio, 
+\hgxcmd{mq}{qimport} automáticamente hace un \hgcmd{add} del parche
+importado.
+
+\subsection{\hgxcmd{mq}{qinit}---preparar un repositorio para trabajar
+  con MQ}
+
+La orden \hgxcmd{mq}{qinit} prepara un repositorio para trabajar con
+MQ.  Crea un directorio llamado \sdirname{.hg/patches}.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qinit}{-c}] Crea \sdirname{.hg/patches} como un
+  repositorio por sí mismo.  También crea un fichero
+  \sfilename{.hgignore} que ignorará el fichero \sfilename{status}.
+\end{itemize}
+
+Cuando el directorio \sdirname{.hg/patches} es un repositorio, las órdenes
+\hgxcmd{mq}{qimport} y \hgxcmd{mq}{qnew} hacen \hgcmd{add}
+automáticamente a los parches nuevos.
+
+\subsection{\hgxcmd{mq}{qnew}---crear un parche nuevo}
+
+La orden \hgxcmd{mq}{qnew} crea un parche nuevo.  Exige un argumento,
+el nombre que se usará para tal parche.  El parche recién creado está
+vacío inicialmente.   Se añade al fichero \sfilename{series} después
+del último parche aplicado, y se introduce en el tope de ese parche.
+
+Si \hgxcmd{mq}{qnew} encuentra ficheros modificados en el directorio
+de trabajo, rehusará crear un parche nuevo a meos que se emplee
+\hgxopt{mq}{qnew}{-f} la opción (ver más adelante).  Este
+comportamiento le permite hacer \hgxcmd{mq}{qrefresh} al último parche
+aplicado antes de aplicar un parche nuevo encima de este.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qnew}{-f}] Crea un parche nuevo si los contenidos
+  del directorio actual han sido modificados.  Cualquier modificación
+  significativa se añade al parche recientemente creado,  de tal forma
+  que al finalizar la orden, el directorio de trabajo no lucirá
+  modificado.
+\item[\hgxopt{mq}{qnew}{-m}] Usa el texto dado como el mensaje de
+  consignación.  Este texto se almacenará al principio del fichero del
+  parche, antes de los datos del parche.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qnext}---imprimir el nombre del próximo parche}
+
+La orden \hgxcmd{mq}{qnext} imprime el nombre del siguiente parche en
+el fichero \sfilename{series} a continuación del último parche
+aplicado.  Este parche sería el próximo parche a aplicar si se
+ejecutara la orden \hgxcmd{mq}{qpush}.
+
+\subsection{\hgxcmd{mq}{qpop}---sustraer parches de la pila}
+
+La orden \hgxcmd{mq}{qpop} elimina los parches aplicados del tope de
+la pila de parches aplicados.  De forma predeterminada solamente
+remueve un parche.
+
+Esta orden elimina los conjuntos de cambios que representan los
+parches sustraídos del repositorio, y actualiza el directorio de
+trabajo para deshacer los efectos de los parches.
+
+Esta orden toma un argumento opcional, que usa como el nombre o el
+índice del parche que desea sustraer.  Si se da el nombre, sustraerá
+los parches hasta que el parche nombrado sea el último parche
+aplicado.  Si se da un número, \hgxcmd{mq}{qpop} lo trata como un
+índice dentro del fichero \sfilename{series},  contando desde
+cero (no cuenta las líneas vacías o aquellas que sean únicamente
+comentarios).  Sustrae los parches hasta que el parche identificado
+por el índice sea el último parche aplicado.
+
+La orden \hgxcmd{mq}{qpop} no lee o escribe parches en el fichero
+\sfilename{series}.  \hgxcmd{mq}{qpop} se constituye por tanto en una
+forma segura de sustraer un parche del fichero \sfilename{series} o un
+parche que ha eliminado o renombrado completamente.  En los dos
+últimos casos, use el nombre del parche tal como lo hizo cuando lo
+aplicó.
+
+De forma predeterminada, la orden \hgxcmd{mq}{qpop} no sustraerá
+parche alguno si el directorio de trabajo ha sido modificado.  Puede
+modificar este comportamiento con la opción \hgxopt{mq}{qpop}{-f}, que
+revierte todas las modificaciones del directorio de trabajo.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qpop}{-a}] Sustrae todos los parches aplicados.
+  Restaura el repositorio al estado antes de haber aplicado parche alguno.
+\item[\hgxopt{mq}{qpop}{-f}] Revertir forzadamente cualquier
+  modificación del directorio de trabajo cuando se hace sustracciones.
+\item[\hgxopt{mq}{qpop}{-n}] Sustraer un parche de la cola dado un nombre.
+\end{itemize}
+
+La orden \hgxcmd{mq}{qpop} elimina una línea del final del fichero
+\sfilename{status} por cada parche que se sustrae.
+
+\subsection{\hgxcmd{mq}{qprev}---imprimir el nombre del parche anterior}
+
+La orden \hgxcmd{mq}{qprev} imprime el nombre del parche en el fichero
+\sfilename{series} que está antes del último parche aplicado.   Este
+se volverá el último parche aplicado si ejecuta \hgxcmd{mq}{qpop}.
+
+\subsection{\hgxcmd{mq}{qpush}---introducir parches a la pila}
+\label{sec:mqref:cmd:qpush}
+
+La orden \hgxcmd{mq}{qpush} añade parches a la pila.  De forma
+predeterminada añade solamente un parche.
+
+Esta orden crea un conjunto de cambios que representa cada parche
+aplicado y actualiza el directorio de trabajo aplicando los efectos de
+los parches.
+
+Los datos predeterminados cuando se crea un conjunto de cambios
+corresponde a:
+\begin{itemize}
+\item La fecha de consignación y zona horaria corresponden a la hora
+  actual de la zona.  Dado que tales datos se usan para computar la
+  identidad de un conjunto de cambios, significa que si hace
+  \hgxcmd{mq}{qpop} a un parche y \hgxcmd{mq}{qpush} de nuevo, el
+  conjunto de cambios que introduzca tendrá una identidad distinta a
+  la del conjunto de cambios que sustrajo.
+\item El autor es el mismo que el predeterminado usado por la orden
+  \hgcmd{commit}.
+\item El mensaje de consignación es cualquier texto del fichero del
+  parche que viene antes del primer encabezado del diff.  Si no hay
+  tal texto, un mensaje predeterminado se sua para identificar el
+  nombre del parche.
+\end{itemize}
+Su un parche contiene un encabezado de parche de Mercurial (XXX add
+link), la información en el encabezado del parche tiene precedencia
+sobre el predeterminado.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qpush}{-a}] Introduce todos los parches que no han
+  sido aplicados del fichero \sfilename{series} hasta que no haya nada
+  más para introducir.
+\item[\hgxopt{mq}{qpush}{-l}] Añade el nombre del parche al final del
+  mensaje de consignación
+\item[\hgxopt{mq}{qpush}{-m}] Si un parche no se aplica limpiamente,
+  usa la entrada para un parche en otra cola almacenada para computar
+  los parámetros en una fusión de tres, y aplica una fusión de tres
+  fuentes usando la maquinaria usual de Mercurial.  Usa la resolución
+  de la fusión como el contenido del parche nuevo.
+\item[\hgxopt{mq}{qpush}{-n}] Usa la cola mencionada si se está
+  fusionando en la introducción.
+\end{itemize}
+
+La orden \hgxcmd{mq}{qpush} lee, pero no modifica el fichero
+\sfilename{series}.  Añade al final del fichero \hgcmd{status} una
+línea por cada parche que se introduce.
+
+\subsection{\hgxcmd{mq}{qrefresh}---actualiza el último parche aplicado}
+
+La orden \hgxcmd{mq}{qrefresh} actualiza el último parche aplicado.
+Modifica el parche, elimina el último conjunto de cambios que
+representó el parche, y crea un nuevo conjunto de cambios para
+representar el parche modificado.
+
+La orden \hgxcmd{mq}{qrefresh} busca las siguientes modificaciones:
+\begin{itemize}
+\item Los cambios al mensaje de consignación, p.e.~el texto antes del
+  primer encabezado de diff en el fichero del parche, se replejan en
+  el nuevo conjunto de cambios que representa el parche.
+\item Las modificaciones a los ficheros a los que se les da
+  seguimiento en el directorio de trabajo se añade al parche.
+\item Los cambios a los ficheros a los que se les da seguimiento con
+  \hgcmd{add}, \hgcmd{copy}, \hgcmd{remove}, o \hgcmd{rename}.  Se
+  añaden al parche los ficheros añadidos, copiados y renombrados,
+  mientras que los ficheros eliminados y las fuentes renombradas se
+  eliminan.
+\end{itemize}
+
+Incluso si \hgxcmd{mq}{qrefresh} no detecta cambios, de todas maneras
+recrea el conjunto de cambios que representa el cambio.  Esto causa
+que la identidad del conjunto de cambios difiera del conjunto de
+cambios previo que identificó al parche.
+
+Opciones:
+\begin{itemize}
+\item[\hgxopt{mq}{qrefresh}{-e}] Modificar la descripción de la
+  consignación y el parche con el editor de texto preferido.
+\item[\hgxopt{mq}{qrefresh}{-m}] Modificar el mensaje de consignación
+  y la descripción del parche con el texto dado.
+\item[\hgxopt{mq}{qrefresh}{-l}] Modificar el mensaje de consignación
+  y la descripción del parche con el texto del fichero dado.
+\end{itemize}
+
+\subsection{\hgxcmd{mq}{qrename}---renombrar un parche}
+
+La orden \hgxcmd{mq}{qrename} renombra un parche y cambia la entrada
+del parche en el fichero \sfilename{series}.
+
+Con un argumento sencillo, \hgxcmd{mq}{qrename} renombra el último
+parche aplicado.  Con dos argumentos, renombra el primer argumento con
+el segundo.
+
+\subsection{\hgxcmd{mq}{qrestore}---restaurar el estado almacenado de
+  la cola}
+
+XXX No idea what this does.
+
+\subsection{\hgxcmd{mq}{qsave}---almacena el estado actual de la cola}
+
+XXX Likewise.
+
+\subsection{\hgxcmd{mq}{qseries}---imprime la serie completa de parches}
+
+La orden \hgxcmd{mq}{qseries} imprime la serie completa de parches del
+fichero \sfilename{series}.  Imprime solamente los nombres de los
+parches sin las líneas en blanco o comentarios.  Imprime primero el
+primero y de último, el último aplicado.
+
+\subsection{\hgxcmd{mq}{qtop}---imprime el nombre del parche actual}
+
+\hgxcmd{mq}{qtop} imprime el nombre del último parche aplicado.
+
+\subsection{\hgxcmd{mq}{qunapplied}---imprimir los parches que aún no
+  se han aplicado}
+
+La orden \hgxcmd{mq}{qunapplied} imprime los nombres de los parches
+del fichero \sfilename{series} que todavía no han sido aplicados.  Los
+imprime de acuerdo al orden en el cual serían introducidos.
+
+\subsection{\hgcmd{strip}---remover una revisión y sus descendientes}
+
+La orden \hgcmd{strip} remueve una revisión, y todos sus descendientes
+del repositorio.  Deshace los efectos de las revisiones removidas del
+repositorio, y actualiza el directorio de trabajo hasta el primer
+padre de la revisión removida.
+
+La orden \hgcmd{strip} almacena una copia de segurida de los conjuntos
+de cambios en un agrupamiento, de forma tal que puedan ser reaplicados
+en caso de que se hayan removido por equivocación.
+
+Opciones:
+\begin{itemize}
+\item[\hgopt{strip}{-b}] Almacenar conjuntos de cambios no
+  relacionados que se han mezclado con los conjuntos de cambios que
+  están en franjas con el agrupamiento de copia de seguridad.
+\item[\hgopt{strip}{-f}] Si una rama tiene varias ramas principales
+  remueve todos los frentes. XXX This should be renamed, y usa
+  \texttt{-f} para desagrupar revisiones cuando hay cambios pendientes.
+\item[\hgopt{strip}{-n}] No almacene la copia de seguridad agrupada.
+\end{itemize}
+
+\section{Referencia de ficheros de MQ}
+
+\subsection{El fichero \sfilename{series}}
+
+El fichero \sfilename{series} contiene una lista de los nombres de
+todos los parches que MQ puede aplicar.  Se representa como una lista
+de nombres, uno por línea.  Se ignora el espacio en blanco al
+principio y al final.
+
+Las líneas pueden contener comentario.  Un comentario comienza con el
+caracter ``\texttt{\#}'', y va hasta el final de la línea.  Se ignoran
+las líneas vacías y las que solamente contengan comentarios.
+
+En algún momento podría editar el fichero \sfilename{series} a mano,
+por tal motivo se admiten comentarios y líneas en blanco como se
+menciono anteriormente.  Por ejemplo, puede poner en comentario un
+parche temporalmente y \hgxcmd{mq}{qpush} omitirá tal parche cuando
+los aplique.  También puede cambiar el orden en el cual se aplican los
+parches, reordenando las entradas en el fichero \sfilename{series}.
+
+También es posible colocar el fichero \sfilename{series} bajo control
+de revisiones;  también es favorable colocar todos los parches que refiera
+bajo control de revisiones.  Si crea un directorio de parches con la
+opción \hgxopt{mq}{qinit}{-c} de \hgxcmd{mq}{qinit}, esto se hará
+automáticamente.
+
+\subsection{El fichero \sfilename{status}}
+
+El fichero \sfilename{status} contiene los nombres y los hashes de los
+conjuntos de cambios de todos los parches que MQ ha aplicado.  A
+diferencia del fichero \sfilename{series}, este NO ha sido diseñado
+para ser editado.  No debería colocar este fichero bajo el control de
+revisiones o modificarlo de forma alguna.  MQ lo usa estrictamente
+para administración interna.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/mq-stack.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="mq-stack.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2525" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4142136"
+     inkscape:cx="299.33323"
+     inkscape:cy="815.646"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1014"
+     inkscape:window-height="689"
+     inkscape:window-x="89"
+     inkscape:window-y="25"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect1307"
+       width="202.93683"
+       height="24.243662"
+       x="230.01944"
+       y="221.70146" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89606"
+       y="237.13383"
+       id="text1309"><tspan
+         sodipodi:role="line"
+         id="tspan1311"
+         x="237.89606"
+         y="237.13383">prevent-compiler-reorder.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect1320"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="251.34325" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="266.77563"
+       id="text1322"><tspan
+         sodipodi:role="line"
+         id="tspan1324"
+         x="237.89598"
+         y="266.77563">namespace-cleanup.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect2217"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="280.98505" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="296.41742"
+       id="text2219"><tspan
+         sodipodi:role="line"
+         id="tspan2221"
+         x="237.89598"
+         y="296.41742">powerpc-port-fixes.patch</tspan></text>
+    <rect
+       style="fill:#7979ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#3c3c3c;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect3114"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="310.6268" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="326.05917"
+       id="text3116"><tspan
+         sodipodi:role="line"
+         id="tspan3118"
+         x="237.89598"
+         y="326.05917">report-devinfo-correctly.patch</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="200.01021"
+       y="191.68094"
+       id="text3170"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3172"
+         x="200.01021"
+         y="191.68094"
+         style="font-size:48px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:15.25329685px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="255.26627"
+       y="248.79449"
+       id="text3190"
+       sodipodi:linespacing="125%"
+       transform="scale(0.786716,1.271107)"><tspan
+         sodipodi:role="line"
+         id="tspan3192"
+         x="255.26627"
+         y="248.79449"
+         style="font-size:61.01318741px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Bitstream Vera Sans">{</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.86807"
+       y="173.17117"
+       id="text4085"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4087"
+         x="195.86807"
+         y="173.17117"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">presente en la serie,</tspan><tspan
+         sodipodi:role="line"
+         x="195.86807"
+         y="188.17117"
+         id="tspan4089"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">pero no aplicado</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.0712"
+       y="288.91745"
+       id="text4091"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4093"
+         x="195.0712"
+         y="288.91745"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">parches aplicados,</tspan><tspan
+         sodipodi:role="line"
+         x="195.0712"
+         y="303.91745"
+         id="tspan4111"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">Conjuntos de cambios presentes</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="195.0712"
+       y="229.28813"
+       id="text4095"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4097"
+         x="195.0712"
+         y="229.28813"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">parche aplicado</tspan><tspan
+         sodipodi:role="line"
+         x="195.0712"
+         y="244.28813"
+         id="tspan4109"
+         style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;writing-mode:lr-tb;text-anchor:end;font-family:Bitstream Vera Sans">más recientemente</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.4975"
+       y="238.29692"
+       id="text4137"><tspan
+         sodipodi:role="line"
+         id="tspan4139"
+         x="450.4975"
+         y="238.29692">201ad3209902</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.05804"
+       y="267.93872"
+       id="text4141"><tspan
+         sodipodi:role="line"
+         id="tspan4143"
+         x="450.05804"
+         y="267.93872">126b84e593ae</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.6557"
+       y="297.58051"
+       id="text4145"><tspan
+         sodipodi:role="line"
+         id="tspan4147"
+         x="450.6557"
+         y="297.58051">a655daf15409</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;opacity:1;fill:#989898;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="450.71429"
+       y="327.22226"
+       id="text4149"><tspan
+         sodipodi:role="line"
+         id="tspan4151"
+         x="450.71429"
+         y="327.22226">e50d59aaea3a</tspan></text>
+    <rect
+       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect3106"
+       width="202.93683"
+       height="24.243662"
+       x="230.01936"
+       y="150.41792" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="237.89598"
+       y="165.8503"
+       id="text3108"><tspan
+         sodipodi:role="line"
+         id="tspan3110"
+         x="237.89598"
+         y="165.8503">forbid-illegal-params.patch</tspan></text>
+    <rect
+       style="fill:#d7d7ff;fill-opacity:0.875;fill-rule:evenodd;stroke:#a6a6a6;stroke-width:1.05063355px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="rect2241"
+       width="202.93683"
+       height="24.243662"
+       x="230.16466"
+       y="180.05968" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="238.04128"
+       y="195.49205"
+       id="text2243"><tspan
+         sodipodi:role="line"
+         id="tspan2245"
+         x="238.04128"
+         y="195.49205">fix-memory-leak.patch</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/mq.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1103 @@
+\chapter{Administración de cambios con Colas de Mercurial}
+\label{chap:mq}
+
+\section{El problema de la administración de parches}
+\label{sec:mq:patch-mgmt}
+
+Un escenario frecuente: usted necesita instalar un paquete de software
+desde las fuentes, pero encuentra un fallo que debe arreglar antes de
+poder comenzar a usarlo.  Hace sus cambios, y se olvida del paquete
+por un tiempo, unos meses después necesita actualizar a una nueva
+versión del paquete.  Si la nueva versión del paquete todavía tiene el
+fallo, debe extraer su arreglo del árbol de fuentes anteriores y
+aplicarlo a la nueva versión.  Una tarea tediosa en la cual es fácil
+equivocarse.
+
+Este es un caso simple del problema del ``manejo de parches''.  Usted
+tiene un árbol de fuentes del ``mantenedor principal'' que no puede
+cambiar: necesita hacer algunos cambios locales sobre el árbol
+principal; y desearía poder mantener tales cambios separados, de forma
+tal que pueda aplicarlos a versiones más nuevas del árbol principal.
+
+El problema de administración de parches surge en muchas situaciones.
+Probablemente la más visible es cuando un usuario de un proyecto de
+software de fuentes abiertas contribuye con un arreglo de un fallo o
+una nueva característica a los mantenedores del proyecto en la forma
+de un parche.
+
+Aquellos que distribuyen sistemas operativos que incluyen programas
+abiertos usualmente requieren hacer cambios en los paquetes que
+distribuyen de tal forma que se armen apropiadamente en sus ambientes.
+
+Cuando hay pocos cambios por mantener, es muy sencillo administrar un
+solo parche con los programas estándar \command{diff} y
+\command{patch} (ver la sección~\ref{sec:mq:patch} para ver cómo
+emplear tales herramientas). Cuando la cantidad de cambios comienza a
+crecer, tiene sentido mantener parches como ``porciones de trabajo''
+individual, de forma que cada cambio contiene solamente un arreglo de
+un fallo (el parche puede modificar varios ficheros, pero está
+``haciendo una sola cosa''), y puede tener cierta cantidad de tales
+parches para diferentes fallos y cambios locales.  En esta situación,
+si envía un parche que arregla un fallo a los mantenedores principales
+de un paquete y ellos incluyen su arreglo en una publicación
+posterior, puede deshacerse de tal parche cuando se actualice a la
+nueva versión.
+
+Mantener un solo parche frente a un árbol principal es algo tedioso y
+es fácil equivocarse, pero no es difícil.  Aunque, la complejidad del
+problema crece rápidamente a medida que la cantidad de parches que
+tiene que mantener crece.  Con más que una pequeña cantidad de
+cambios, entender cuáles ha aplicado se convierte de algo desordenado
+a algo avasallante.
+
+Afortunadamente Mercurial provee una extensión poderos: Colas de
+Mercurial (o simplemente ``MQ''), que simplifica en gran medida el
+problema de administración de parches.
+
+\section{La prehistoria de las Colas de Mercurial}
+\label{sec:mq:history}
+
+A finales de los 90s, muchos desarrolladores del núcleo de Linux
+comenzaron a mantener ``series de parches'' que modificaron el
+comportamiento del núcleo de Linux.  Algunos se enfocaban en
+estabilidad, otros en aumentar las características, y otros un poco
+más especulativos.
+
+Los tamaños de las series de parches crecieron rápidamente.  En el
+2002, Andrew Morton publicó algunos guiones de línea de órdenes que
+estuvo usando para automatizar la tarea de administrar su cola de
+parches.  Andrew usó exitósamente tales guiones para administrar
+centenas (a veces millares) de parches en el núcleo de Linux.
+
+\subsection{Trabajar parches con quilt}
+\label{sec:mq:quilt}
+
+A comienzos del 2003, Andreas Gruenbacher y Martin Quinson tomaron la
+aproximación de los guiones de Andrew y publicaron una herramienta
+llamada
+``patchwork quilt''~\cite{web:quilt}, o simplemente ``quilt''
+(ver~\cite{gruenbacher:2005} el paper que lo describe).  Dado que
+quilt automatizaba sustancialmente la administración de parches, fue
+adoptado en gran medida por desarrolladores de programas abiertos.
+
+Quilt maneja una \emph{pila de parches} sobre un árbol de directorios.
+Para comenzar, usted le indica a quilt que administre un árbol de
+directorios, le indica qué ficheros manejar; Este almacena los nombres
+y los contenidos de estos ficheros.  Para arreglar un fallo, usted
+crea un nuevo parche (con una sola orden), edita los ficheros que está
+arreglando y ``refresca'' el parche.
+
+El paso de refresco hace que quilt revise el árbol de directorios;
+actualiza el parche con todos los cambios que usted haya hecho.  Puede
+crear otro parche sobre el primero, que hará seguimiento de los
+cambios requeridos para modificar el árbol desde ``el árbol con un
+parch aplicado'' a un ``árbol con dos parches aplicados''.
+
+Usted puede \emph{elegir} qué cambios desea aplicar al árbol.  Si
+``pop''\ndt{saca} un parche, los cambios hechos por tal parchve
+desapareceŕan del árbol de directorios.  Quilt recuerda qué parches ha
+sacado, para que pueda ``introducirlos''\ndt{push} posteriormente, así el
+árbol de directorios se restaurará con las modificaciones que vienen
+del parche.  Lo más importante es que puede ejecutar la orden
+``refresh'' en cualquier momento, y el último parche será
+actualizado.  Esto significa que puede, en cualquier momento, cambiar
+qué parches serán aplicados y qué modificaciones hacen ellos.
+
+Quilt no tiene nada que ver con herramientas de control de versiones,
+y puede trabajar bien sobre un conjunto de fuentes que viene de un
+fichero comprimido y empaquetado o una copia de trabajo de Subversion.
+
+\subsection{Pasar de trabajo con parches con Quilt hacia Colas de Mercurial}
+\label{sec:mq:quilt-mq}
+
+A mediados de 2005, Chris Mason tomó las características de quilt y
+escribió una extensión que llamó Colas de Mercurial\ndt{Mercurial
+Queues}, que proporcionó un comportamiento a Mercurial al estilo
+quilt.
+
+La diferencia clave entre quilt y MQ es que quilt no sabe nada acerca
+del sistema de control de revisiones, mientras que MQ está
+\emph{integrado} con Mercurial.  Cada parche que usted introduce se
+representa como un conjunto de cambios en Mercurial.  Si sustrae un
+parche, el conjunto de cambios desaparece.\ndt{introduce originalmente es
+push y pop es sustraer en este contexto, usaremos el original en inglés
+cuando encontremos que facilita la comprensión}
+
+Dado que quilt no se preocupa por las herramientas de control de
+revisiones, continúa siendo una porción de software tremendamente útil
+para aquellas situaciones en las cuales no puede usar Mercurial y MQ.
+
+\section{La gran ventaja de MQ}
+
+No puedo sobreestimar el valor que MQ ofrece en la unificación de
+parches y el control de revisiones.
+
+La principal razón por la cual los parches han persistido en el mundo
+del software libre y de fuentes abiertas--a pesar de la creciente
+disponibilidad de herramientas poderosas de control de revisiones-- es
+la \emph{agilidad} que ofrecen.
+
+Las herramientas tradicionales de control de revisiones llevan un
+registro permanente e irreversible de todo lo que usted hace.  A pesar
+de que esto tiene gran valor, también es bastante sutil.  Si requiere
+realizar un experimento ((((wild-eyed)))), debe ser cuidadoso en cómo
+lo hace, o puede dejar trazas innecesarias--o peor aún,
+desconcertantes o desestabilizantes--- de los pasos y errores en el
+registro de revisiones de forma permanente.
+
+En contraste, con la cohesión de MQ con el control de revisiones
+distribuidos y los parches, resulta más sencillo aislar su trabajo.
+Sus parches viven encima del historial de revisiones normales, y
+puede hacer que ellos desaparezcan o reaparezcan cuando lo desee.  Si
+no le gusta un parche, puede desecharlo.  Si un parche no satisface
+todo lo que usted desea, puede arreglarlo---tantas veces como lo
+requiera, hasta que lo haya refinado lo suficiente hacia sus
+expectativas.
+
+Por ejemplo, la integración de parches con el control de revisiones
+hace que el entender los parches y revisar sus efectos---y sus
+interacciones con el código en el cuál están enlazados--- sea
+\emph{mucho} más sencillo.  Dado que todo parche que se aplique tiene
+un conjunto de cambios asociado, puede usar
+\hgcmdargs{log}{\emph{filename}} para ver qué conjuntos de cambios y
+parches afectaron un fichero.  Puede usar la orden \hgext{bisect} para
+hacer una búsqueda binaria sobre todos los conjuntos de cambios y
+parches aplicados para ver dónde se introdujo un fallo o dónde fue
+arreglado.  Puede usar la orden \hgcmd{annotate} para ver qué
+conjuntos de cambios o parches modificaron una línea particular de un
+fichero fuente. Y mucho más.
+
+\section{Entender los parches}
+\label{sec:mq:patch}
+
+Dado que MQ no esconde su naturaleza parche-céntrica, es muy útil para
+entender de qué se tratan los parches, y un poco acerca de las
+herramientas que trabajan con ellos.
+
+La orden de Unix tradicional \command{diff} compara dos ficheros, e
+imprime una lista de diferencias de sus líneas.  La orden
+\command{patch} entiende esas diferencias como \emph{modificaciones}
+para construir un fichero.  Vea en la figura~\ref{ex:mq:diff} un
+ejemplo sencillo de tales órdenes en acción.
+
+\begin{figure}[ht]
+  \interaction{mq.dodiff.diff}
+  \caption{Uso sencillo de las órdenes \command{diff} y \command{patch}}
+  \label{ex:mq:diff}
+\end{figure}
+
+El tipo de fichero que \command{diff} genera (y que \command{patch}
+toma como entrada) se llama un ``parche'' o un ``diff''; no hay
+diferencia entre un parche y un diff.  (Usaremos el término ``parche'',
+dado que es el que más comunmente se usa.)
+
+Un parche puede comenzar con un texto arbitrario; la orden \command{patch}
+ignora este texto, pero MQ lo usa como el mensaje de consignación
+cuando se crean conjuntos de cambios.  Para encontrar el inicio del
+contenido de un parche, la orden \command{patch} busca la primera
+línea que comience con la cadena ``\texttt{diff~-}''.
+
+MQ trabaja con diffs \emph{unificados} (\command{patch} acepta varios
+formatos de diff adicionales, pero MQ no).  Un diff unificado contiene
+dos clases de encabezados.  El \emph{encabezado de fichero} describe
+el fichero que se está modificando; contiene el nombre del fichero a
+modificar.  Cuando \command{patch} ve un nuevo encabezado de fichero,
+busca un fichero con ese nombre para modificarlo.
+
+Después del encabezaado vienen varios \emph{trozos}.  Cada trozo
+comienza con un encabezado; que identifica el rango de líneas del
+fichero que el trozo debe modificar.  Después del encabezado, un trozo
+comienza y termina con unas pocas líneas (usualmente tres) de texto del
+fichero que no han sido modificadas; las cuales llamamos el
+\emph{contexto} del trozo.  Si solamente hay una pequeña cantidad de
+contexto entre trozos sucesivos, \command{diff} no imprime un nuevo
+encabezado para el trozo, continua integrando los trozos, con unas
+líneas de contexto entre las modificaciones.
+
+Cada línea de contexto comienza con un caracter de espacio.  En el
+trozo, si una línea comienza con ``\texttt{-}'' significa ``elimine
+esta línea'', si la línea comienza con un ``\texttt{+}'' significa
+``inserte esta línea''.  Por ejemplo, una línea que se modifica se
+representa con una línea eliminada y una línea insertada.
+
+Retomaremos aspectos más sutiles acerca de parches posteriormente (en
+la sección~\ref{sec:mq:adv-patch}), pero en el momento usted ya
+debería tener suficiente información para usar MQ.
+
+\section{Comenzar a usar Colas de Mercurial}
+\label{sec:mq:start}
+
+Dado que MQ está implementado como una extensión, debe habilitarla
+explícitamente antes de comenzar a usarla.  (No necesita descargar
+nada; MQ viene con la distribución estándar de Mercurial.)  Para
+habilitar MQ, edite su fichero \tildefile{.hgrc}, y añada las líneas
+de la figura~\ref{ex:mq:config}.
+
+\begin{figure}[ht]
+  \begin{codesample4}
+    [extensions]
+    hgext.mq =
+  \end{codesample4}
+  \label{ex:mq:config}
+  \caption{Líneas a añadir en \tildefile{.hgrc} para habilitar la extensión MQ}
+\end{figure}
+
+Cuando la extensión esté habilitada, aparecerán varios comandos.  Para
+verificar que la extensión está trabajando, puede usar \hgcmd{help}
+para ver si la orden \hgxcmd{mq}{qinit} está disponible; vea un
+ejemplo en la figura~\ref{ex:mq:enabled}.
+
+\begin{figure}[ht]
+  \interaction{mq.qinit-help.help}
+  \caption{Cómo verificar que MQ está habilitado}
+  \label{ex:mq:enabled}
+\end{figure}
+
+Puede usar MQ en \emph{cualquier} repositorio de Mercurial, y sus
+comandos solamente operarán con tal repositorio.  Para comenzar, basta
+con preparar el repositorio con la orden \hgxcmd{mq}{qinit} (ver la
+figura~\ref{ex:mq:qinit}).  Esta orden crea un directorio vacío
+llamado \sdirname{.hg/patches}, donde MQ mantendrá sus metadatos. Como
+otras ordenes de Mercurial, la orden \hgxcmd{mq}{qinit} no imprime
+nada cuando es exitosa.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qinit}
+  \caption{Preparar un repositorio para usar MQ}
+  \label{ex:mq:qinit}
+\end{figure}
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qnew}
+  \caption{Crear un nuevo parche}
+  \label{ex:mq:qnew}
+\end{figure}
+
+\subsection{Crear un nuevo parche}
+
+Para comenzar a trabajar en un nuevo parche use la orden
+\hgxcmd{mq}{qnew}. Esta orden recibe un argumento, el nombre del
+parche a crear.  MQ lo usará como el nombre del fichero en el
+directorio \sdirname{.hg/patches}, como puede apreciarlo en la
+figura~\ref{ex:mq:qnew}.
+
+También hay otros dos nuevos ficheros en el directorio
+\sdirname{.hg/patches}:  \sfilename{series} y \sfilename{status}.  El
+fichero \sfilename{series} lista todos los parches de los cuales MQ
+tiene noticia para este repositorio, con un parche por línea.
+Mercurial usa el fichero \sfilename{status} para mantener registros
+interns; da seguimiento a todos los parches que MQ ha \emph{aplicado}
+en el repositorio.
+
+\begin{note}
+  En ciertas ocasiones usted querrá editar el fichero
+  \sfilename{series} a mano; por ejemplo, cambiar el orden en que se
+  aplican ciertos parches.  A pesar de esto, es una mala idea editar
+  manualmente  el fichero \sfilename{status}, dado que es fácil
+  desorientar a MQ acerca de lo que está pasando.
+\end{note}
+
+Una vez que haya creado un nuevo parche, puede editar los ficheros en
+el directorio de trabajo, como lo haría usualmente.  Toda las órdenes
+que de a Mercurial, tales como \hgcmd{diff} y \hgcmd{annotate},
+trabajarán de la misma forma como lo han hecho antes.
+
+\subsection{Refrescar un parche}
+
+Cuando usted llega a un punto en el cual desea guardar su trabajo, use
+la orden \hgxcmd{mq}{qrefresh} (figura~\ref{ex:mq:qnew}) para
+actualizar el parche en el cual está trabajando.  Esta orden almacena
+los cambios que haya hecho al directorio actual de trabajo en su
+parche, y almacena el conjunto de cambios correspondiente que contiene
+los cambios.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qrefresh}
+  \caption{Refrescar un parche}
+  \label{ex:mq:qrefresh}
+\end{figure}
+
+Puede ejecutar la orden \hgxcmd{mq}{qrefresh} tan seguido como quiera,
+y es una buena forma de ``colocar marcas'' a su trabajo.  Refresque su
+parche en momentos oportunos; intente un experimento; si el
+experimento no funciona, Use \hgcmd{revert} sobre sus modificaciones
+para volver al refresco anterior.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qrefresh2}
+  \caption{Refrescar un parche muchas veces para acumular cambios}
+  \label{ex:mq:qrefresh2}
+\end{figure}
+
+\subsection{Aplicar un parche tras otro y dar seguimiento}
+
+Cuando haya terminado de trabajar en un parche, o necesite trabajar en
+otro, puede usar la orden \hgxcmd{mq}{qnew} para crear un nuevo
+parche.  Mercurial aplicará este parche sobre su parche anterior.
+Para un ejemplo, ver la figura~\ref{ex:mq:qnew2}.  Note que el parche
+contiene los cambios en nuestro parche anterior como parte de su
+contexto (lo verá más claramente en la salida de \hgcmd{annotate}).
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qnew2}
+  \caption{Aplicar un parche después del primero}
+  \label{ex:mq:qnew2}
+\end{figure}
+
+Hasta ahora, con excepción de \hgxcmd{mq}{qnew} y
+\hgxcmd{mq}{qrefresh}, hemos sido cuidadosos para aplicar únicamente
+órdenes usuaales de Mercurial.  De todas maneras, MQ ofrece muchos
+comandos que son más sencillos de usar cuando esté pensando acerca de
+parches, como se puede ver en la figura~\ref{ex:mq:qseries}:
+
+\begin{itemize}
+\item La orden \hgxcmd{mq}{qseries} lista cada parche del cual MQ
+  tiene noticia en este repositorio, desde el más antiguo hasta el más
+  nuevo (El último \emph{creado}).
+\item La orden \hgxcmd{mq}{qapplied} lista cada parche que MQ haya
+  \emph{aplicado} en este repositorio, de nuevo, desde el más antiguo
+  hasta el más nuevo (El aplicado más recientemente).
+\end{itemize}
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qseries}
+  \caption{Entender la pila de parches con \hgxcmd{mq}{qseries} y
+    \hgxcmd{mq}{qapplied}}
+  \label{ex:mq:qseries}
+\end{figure}
+
+\subsection{Manipular la pila de parches}
+
+La discusión previa indicó que debe haber una diferencia entre los
+parches ``conocidos'' y ``aplicados'', y efectivamente la hay.  MQ
+puede manejar un parche sin que este haya sido aplicado al
+repositorio.
+
+Un parche \emph{aplicado} tiene su correspondiente conjunto de cambios
+en el repositorio, y los efectos del parche y el conjunto de cambios
+son visibles en el directorio de trabajo.  Puede deshacer la
+aplicación de un parche con la orden \hgxcmd{mq}{qpop}.  MQ 
+\emph{sabe acerca de}, o maneja un parche sustraído, pero el parche ya
+no tendrá un conjunto de cambios correspondientes en el repositorio, y
+el directorio de trabajo no contendrá los cambios hechos por el
+parche.  La figura~\ref{fig:mq:stack} ilustra la diferencia entre
+parches aplicados y seguidos.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{mq-stack}
+  \caption{Parches aplicados y no aplicados en la pila de parches de MQ}
+  \label{fig:mq:stack}
+\end{figure}
+
+Puede reaplicar un parche no aplicado o sustraído con la orden
+\hgxcmd{mq}{qpush}.  Esto crea un nuevo conjunto de cambios
+correspondiente al parche, y los cambios del parche estarán presentes
+de nuevo en el directorio de trabajo.  Vea ejemplos de
+\hgxcmd{mq}{qpop} y \hgxcmd{mq}{qpush} en acción en la
+figura~\ref{ex:mq:qpop}.  Vea que hemos sustraído uno o dos parches,
+la salida de\hgxcmd{mq}{qseries} continúa igual, mientras que
+\hgxcmd{mq}{qapplied} ha  cambiado.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qpop}
+  \caption{Modificar la pila de parches aplicados}
+  \label{ex:mq:qpop}
+\end{figure}
+
+\subsection{Introducir y sustraer muchos parches}
+
+Mientras que \hgxcmd{mq}{qpush} y \hgxcmd{mq}{qpop} operan sobre un
+único parche cada vez, puede introducir y sustraer varios parches de
+una vez.  La opción \hgxopt{mq}{qpush}{-a} de \hgxcmd{mq}{qpush}
+introduce todos los cambios que no hayan sido aplicados, mientras que
+la opción \hgxopt{mq}{qpop}{-a} de \hgxcmd{mq}{qpop} sustrae todos los
+cambios aplicados.  (Vea la sección~\ref{sec:mq:perf} más adelante
+en la cual se explican otras formas de de introducir y sustraer varios
+cambios.)
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.qpush-a}
+  \caption{Pushing all unapplied patches}
+  \label{ex:mq:qpush-a}
+\end{figure}
+
+\subsection{Medidas de seguridad y cómo saltarlas}
+
+Muchas órdenes MQ revisan el directorio de trabajo antes de hacer
+cualquier cosa, y fallan si encuentran alguna modificación.  Lo hacen
+para garantizar que usted no pierda cambio alguno de los que haya
+hecho, pero que no hayan sido incorporados en algún parche.  La
+figura~\ref{ex:mq:add} ilusta esto; la orden \hgxcmd{mq}{qnew} no
+creará un nuevo parche si hay cambios notorios, causados en este caso
+por aplicado la orden \hgcmd{add} a \filename{file3}.
+
+\begin{figure}[ht]
+  \interaction{mq.tutorial.add}
+  \caption{Crear un parche a la fuerza}
+  \label{ex:mq:add}
+\end{figure}
+
+Las órdenes que revisan el directorio actual cuentan con una opción
+``Se lo que estoy haciendo'', que siempre está nombrada como
+\option{-f}.  El significado exacto de \option{-f} depende de la
+orden.  Por ejemplo, \hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}}
+incorporarán cualquier cambio notorio en el nuevo parche que crea pero
+\hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} revertirá las modificaciones a
+cualquier fichero que haya sido afectado por el parche que está siendo
+sustraído. ¡Asegúrese de leer la documentación de la opción \option{-f}
+de cada comando antes de usarla!
+
+\subsection{Trabajar con varios parches a la vez}
+
+La orden \hgxcmd{mq}{qrefresh} siempre refresca el \emph{último}
+parche aplicado.  Esto significa que usted puede suspender su trabajo
+en un parche (refrescándolo), sustraerlo o introducirlo para lograr
+que otro parche esté de último y trabajar en \emph{ese} parche por un
+rato.
+
+A continuación un ejemplo que ilustra cómo puede usar esta habilidad.
+Digamos que está desarrollando una nueva característica en dos
+parches.  El primero es un cambio en la parte fundamental de su
+programa, y el segundo--sobre el primero---cambia la interfaz de
+usuario para usar el código que ha añadido a la parte fundamental.  Si
+ve que hay un fallo en la parte fundamental mientras está trabajando
+en el parche de UI\ndt{Interfaz de Usuario, User Interface en inglés}, es fácil arreglar la parte fundamental.
+Simplemente use \hgxcmd{mq}{qrefresh} sobre el parche de la UI para
+guardar los cambios de su trabajo en progreso, y use \hgxcmd{mq}{qpop}
+para sacar sustraer el parche de la parte fundamental.  Arregla el
+fallo sobre la parte fundamental, aplique \hgxcmd{mq}{qrefresh} sobre
+el parche fundamental, y aplique \hgxcmd{mq}{qpush} sobre el parche de
+UI para continuar donde había quedado.
+
+\section{Más acerca de parches}
+\label{sec:mq:adv-patch}
+
+MQ usa la orden GNU \command{patch} para aplicar los parches, por lo
+tanto es útil conocer ciertos detalles de cómo trabaja
+\command{patch}, y también acerca de los parches.
+
+\subsection{La cantidad de franjas}
+
+Si ve el encabezado de un parche, notará que la ruta al fichero tiene
+un componente adicional al principio, que no está presente en la
+ruta. Esta es una traza de cómo generaba anteriormente los parches la
+gente (algunos aún lo hacen, pero es raro con las herramientas de
+control de revisiones del actuales).
+
+Alicia desempaquetaría un comprimido, editaría sus ficheros, y querría
+crear un parche.  Por lo tanto ella renombraría su directorio de
+trabajo, desempacaría el comprimido de nuevo (para lo cual necesitó el
+renombramiento), y usaría las opciones \cmdopt{diff}{-r} y
+\cmdopt{diff}{-N} de \command{diff} para generar recursivamente un
+parche entre el directorio original y el modificado.  El resultado
+sería que el nombre del directorio original estaría al principio de
+toda ruta en cada encabezado de fichero, y el nombre del directorio
+modificado estaría al frente de la porción derecha de la ruta del
+fichero.
+
+Como alguien que reciba un parche de Alicia en la red podría obtener
+dos directorios, uno original y el otro modificado con exactamente los
+mismos nombres, la orden \command{patch} tiene la opción
+\cmdopt{patch}{-p} que indica la cantidad de componentes de la ruta
+a eliminar cuando se vaya a aplicar el parche.  Este número se
+llama la \emph{cantidad de eliminaciones}.
+
+La opción con ``\texttt{-p1}'' significa ``elimine uno''.  Si
+\command{patch} ve un nombre de fichero \filename{foo/bar/baz} en el
+encabezado del fichero, eliminará \filename{foo} y tratará de parchar
+un fichero llamado \filename{bar/baz}.  (Hablando estrictamente, la
+cantidad de eliminaciones se refiere a la cantidad de \emph{separadores de
+ ruta} (y los componentes que vayan con ellos) a eliminar.  Si el
+contador es uno volverá \filename{foo/bar} en \filename{bar}, pero
+\filename{/foo/bar} (note la barra extra) en \filename{foo/bar}.)
+
+La cantidad a eliminar``estándar'' para parches es uno; casi todos los
+parches contienen un componente inicial de la ruta que necesita ser
+eliminado.  La orden \hgcmd{diff} de Mercurial genera nombres de ruta
+de esta forma, y la orden \hgcmd{import} y MQ esperan parches que
+tengan a uno como cuenta de eliminaciones.
+
+Si recibe un parche de alguien de quien desea adicionar adicionar a su
+cola de parches, y el parche necesita una cuenta de eliminación que no
+sea uno, no podrá aplicar \hgxcmd{mq}{qimport} en primera medida,
+porque \hgxcmd{mq}{qimport} no tiene todavía una opción \texttt{-p}
+option (ver~\bug{311}).  Lo mejor que puede hacer es aplicar
+\hgxcmd{mq}{qnew} por su cuenta, y después usar \cmdargs{patch}{-p\emph{N}}
+para aplicar tal parche, seguido de \hgcmd{addremove} para tener en
+cuenta cualquier fichero adicionado o eliminado por el parche, seguido
+de \hgxcmd{mq}{qrefresh}.  Esta complejidad puede ser innecesaria;
+consulte~\bug{311} para más información.
+
+\subsection{Estrategias para aplicar parches}
+
+Cuando \command{patch} aplica un trozo, intenta varias estrategias
+sucesivas que decrecen en precisión para intentar aplicarlo.  Esta
+técnica de pruebas y error aveces permite que un parche que fue
+generado contra una versión anterior de un fichero, sea aplicada sobre
+una versión más nueva del mismo.
+
+Primero \command{patch} intenta una correspondencia perfecta donde los
+números de línea, el contexto y el texto a modificar deben coincidir
+perfectamente.  Si no lo logra, intenta encontrar una correspondencia
+exacta del contexto, sin tener en cuenta el número de línea.  Si es
+exitoso, imprime una línea indicando que el trozo fue aplicado, pero a
+un \emph{corrimiento} del número de línea original.
+
+Si falla la correspondencia por contexto, \command{patch} elimina la
+primera y la última línea del contexto, e intenta una correspondencia
+\emph{reducida} del contexto.  Si el trozo con contexto reducido es
+exitoso, imprime un mensaje indicando que aplicó el trozo con un
+\emph{factor difuso} (el número después del factor difuso indica
+cuántas líneas de contexto \command{patch} tuvo que eliminar antes de
+aplicar el parche).
+
+Cuando ninguna de estas técnicas funciona, \command{patch} imprime un
+mensaje indicando que el trozo en cuestión se desechó.  Almacena los
+trozos desechados (también llamados ``descartados'') en un fichero con
+el mismo nombre, y la extensión \sfilename{.rej} añadida.  También
+almacena una copia igual al fichero original con la extensión
+\sfilename{.orig}; la copia del fichero sin extensión contendrá
+cualquier cambio hecho por los trozos que \emph{sí} se aplicaron sin
+problema.  Si usted tiene un parche que modifica \filename{foo} con
+seis trozos, y uno de ellos falla al aplicarse, tendrá : un fichero
+original \filename{foo.orig}, un fichero \filename{foo.rej} que
+contiene el trozo, y \filename{foo}, que contiene los cambios que se
+aplicaron por los cinco trozos exitosos.
+
+\subsection{Algunos detalles de la representación de parches}
+
+Hay ciertas cosas útiles por saber acerca de cómo trabaja
+\command{patch} con los ficheros:
+\begin{itemize}
+\item Debería ser obvio que \command{patch} no puede manipular
+  ficheros binarios.
+\item No se preocupa por el bit ejecutable; crea ficheros nuevos en
+  modo lectura, pero no ejecutable.
+\item \command{patch} intenta eliminar un fichero como una diferencia
+  entre el fichero a eliminar y un fichero vacío.  Y por lo tanto su
+  idea de ``Borré este fichero'' debería pensarse como ``toda línea de
+  este fichero fue eliminada'' en un parche.
+\item Trata la adición de un fichero como un diff entre un fichero
+  vacío y el fichero a ser adicionado.  Por lo tanto en un parche su
+  idea de ``Añadí este fichero'' se vería como ``toda línea de este
+  fichero fue añadida''.
+\item Trata el renombramiento de un fichero como la eliminación del
+  nombre anterior y la adición del nuevo nombre.  Esto significa que
+  los ficheros renombrados dejan un rastro grande en los parches.
+  (Tenga en cuenta que Mercurial no trata de inferir cuando los
+  ficheros han sido renombrados o copiados en un parche en este
+  momento.)
+\item \command{patch} no puede representar ficheros vacíos, por lo
+  tanto no puede usar un parche para representar la noción ``Añadí
+  este fichero vacío al árbol''.
+\end{itemize}
+\subsection{Cuidado con los difusos}
+
+Cuando aplique un trozo con un corrimiento, o con un factor difuso,
+aveces será taotalmente exitoso, tales técnicas inexactas dejan
+claramente la posibilidad de corromper el fichero parchado.  Los casos
+más típicos involucran aplicar un parche dos veces o en un sitio
+incorrecto del fichero. Si \command{patch} o \hgxcmd{mq}{qpush} llegan
+a mencionar un corrimiento o un factor difuso, debería asegurarse que
+los ficheros modificados estén correctos después del suceso.
+
+Casi siempre es buena idea refrescar un parche que fue aplicado con un
+corrimiento o un factor difuso; refrescar el parche genera nueva
+información de contexto que permitirá aplicarlo limpiamente.  Digo
+``casi siempre,'' no ``siempre'', puesto que en ciertas ocasiones
+refrescar un parche lo hará fallar frente a una revisión diferente del
+fichero.  En algunos casos, como por ejemplo, cuando usted está
+manteniendo un parche que debe estar encima de múltiples revisiones de
+un árbol de fuentes, es aceptable tener un parche aplicado algo
+difuso, siempre que haya verificado los resultados del proceso de
+parchar.
+
+\subsection{Manejo de descartes}
+
+Si \hgxcmd{mq}{qpush} falla al aplicar un parche, mostrará un texto de
+error y saldrá.  Si ha dejado ficheros \sfilename{.rej}, es mejor
+arreglar los trozos descartados antes de introducir parches
+adicionales o hacer cualquier otra cosa.
+
+Si su parche \emph{solía} aplicarse limpiamente, y ya no lo hace
+porque ha cambiado código subyacente en el cual se basa su parche, las
+Colas de Mercurial pueden ayudar; consulte la sección~\ref{sec:mq:merge}.
+
+Desafortunadamente, no hay grandes técnicas para tratar los trozos
+descartados.  Casi siempre deberá consultar el fichero
+\sfilename{.rej} y editar el fichero objetivo, aplicando los trozos
+descartados a mano.
+
+Si es aventurero, Neil Brown, un hacker del núcleo Linux, escribió una
+herramienta llamada \command{wiggle}~\cite{web:wiggle}, que es más
+vigorosa que \command{patch} en su intento de hacer que se aplique un
+parche.
+
+Otro hacker del nucleo Linux, Chris Mason (el autor de las Colas de
+Mercurial), escribió una herramienta similar llamada
+\command{mpatch}~\cite{web:mpatch}, que sigue una aproximación
+sencilla para automatizar la aplicación de trozos descartados por
+\command{patch}.  La orden \command{mpatch} puede ayudar con cuatro
+razones comunes por las cuales un parche ha sido descartado:
+
+\begin{itemize}
+\item El contexto en la mitad de un trozo ha cambiado.
+\item Un trozo ha perdido cierto contexto al principio o al final.
+\item Un trozo largo podría aplicarse mejor---por completo o una
+  parte---si estaba cortado en trozos más pequeños.
+\item Un trozo remueve líneas con contenido ligeramente diferente que
+  aquellas que están presentes en el fichero.
+\end{itemize}
+
+Si usted usa \command{wiggle} o \command{mpatch}, debería ser
+doblemente cuidadoso al revisar sus resultados cuando haya terminado.
+De hecho, \command{mpatch} refuerza este método de revisar por partida
+doble su salida, dejándolo a usted en un programa de fusión cuando la
+herramienta haya terminado su trabajo, de tal forma que usted pueda
+verificar lo que ha hecho y pueda terminar de aplicar cualquier fusión
+faltante.
+
+\section{maximizar el rendimiento de MQ}
+\label{sec:mq:perf}
+
+MQ es muy eficiente al tratar con una gran cantidad de parches.  Corrí
+unos experimentos de desempeño a mediados del 2006 para una charla que
+dí en la conferencia EuroPython 2006~\cite{web:europython}.  Empleé la
+serie de parches para el núcleo Linux 2.6.17-mm1, que contaba con 1.738
+parches.  Los apliqué sobre un repositorio del núcleo de Linux con
+todas las 27.472 revisiones entre 2.6.12-rc2 y 2.6.17.
+
+En mi portátil antiguo y lento, logré aplicar 
+\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} a los 1.738 parches en 3.5
+minutos, y \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} en 30 segundos.
+(En un portátil más nuevo, el tiempo para introducir todos los
+parches, se logró en menos de dos minutos.)  Apliqué
+\hgxcmd{mq}{qrefresh} sobre uno de los parches más grandes (que hizo
+22.779 líneas de cambios en 287 ficheros) en 6,6 segundos.
+
+Claramente, MQ funciona adecuadamente en árboles grandes, y además hay
+unos trucos que pueden emplearse para obtener el máximo desempeño.
+
+En primer lugar, trate de hacer ``en lote'' las operaciones.  Cada vez
+que ejecute \hgxcmd{mq}{qpush} o \hgxcmd{mq}{qpop}, tales órdenes
+revisan el directorio de trabajo para asegurarse de que usted no ha
+hecho cambios y ha olvidado ejecutar \hgxcmd{mq}{qrefresh}.  En un
+árbol pequeño, el tiempo de esta revisión puede ser mínimo,  Pero en
+un árbol mediano (con decenas de miles de ficheros), puede tomar un
+segundo o más.
+
+Las órdenes \hgxcmd{mq}{qpush} y \hgxcmd{mq}{qpop} le permiten
+introducir o sustraer varios parches en una operación.  Puede
+identificar el ``parche destino'' que desee.  Cuando aplique
+\hgxcmd{mq}{qpush} con un destino, introducirá tantos parches como sea
+necesario hasta que el especificado esté en el tope de la pila.
+Cuando emplee \hgxcmd{mq}{qpop} con un destino, MQ sustraerá parches
+hasta que el parche destino esté en el tope.
+
+Puede identificar un parche destino con el nombre del parche o con el
+número.  Si se refiere al número, los parches se contarán desde cero;
+esto significa que el primer parche es cero, el segundo es uno y así
+sucesivamente.
+
+\section{Actualiar los parches cuando el código cambia}
+\label{sec:mq:merge}
+
+Es común contar con una pila de parches sobre un repositorio que usted
+no modifica directamente.  Si está trabajando en cambios de código de
+otros, o en una característica que tarda bastante en desarrollarse
+comparada con la tasa de cambio del código sobre la cual se está
+trabajando, necesitará sincronizarse con el código, y ajustar
+cualquier trozo en sus parches que ya no estén al día.  A esto se le
+llama hacer \emph{rebase} a su serie de parches.
+
+La vía más sencilla de hacerlo es con \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}}
+sobre sus parches, después hacer \hgcmd{pull} de los cambios en el
+repositorio, y finalmente hacer
+\hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} con sus parches de nuevo.  MQ
+dejará de de introducir parches siempre que llegue a un parche que no se pueda
+aplicar debido a un conflicto, permitiéndole a usted arreglarlo,
+aplicar \hgxcmd{mq}{qrefresh} al parche afectado y continuar
+introduciendo hasta que haya arreglado la pila completa.
+
+Esta aproximación es sencilla y funciona bien si no espera cambios en
+el código original que afecte en gran medida los parches que usted
+esté aplicando. Si su pila de parches toca código que es modificado
+frecuentemente o de forma invasiva sobre el código subyacente,
+arreglar trozos manualmente se vuelve desgastante.
+
+Es posible automatizar de forma parcial el proceso de rebase.  Si sus
+parches se aplican limpiamente sobre algunas revisiones del
+repositorio subyacente, MQ puede usar esta información para ayudarle a
+a resolver conflictos entre sus parches y una revisión distinta.
+
+El proceso resulta un poco complejo:
+\begin{enumerate}
+\item Para comenzar, haga \hgcmdargs{qpush}{-a} sobre todos los
+  parches que usted sepa se aplican limpiamente.
+\item Guarde una copia de seguridad de su directorio de parches  con
+  \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}.
+  Esto imprime el nombre del directorio en el cual se han guardado los
+  parches.  Guardará los parches en un directorio llamado
+  \sdirname{.hg/patches.\emph{N}}, donde \texttt{\emph{N}} es un
+  entero pequeño.  También consigna un ``conjunto de cambios de
+  seguridad'' sobre sus parches aplicados; esto es para mantener el
+  histórico, y guarda los estados de los ficheros  \sfilename{series}
+  y \sfilename{status}.
+\item Use \hgcmd{pull} para traer los nuevos cambios en el repositorio
+  subyacente. (No ejecute \hgcmdargs{pull}{-u}; vea más adelante por qué.)
+\item Actualice a la nueva revisión punta con 
+  \hgcmdargs{update}{\hgopt{update}{-C}} para sobreescribir los
+  parches que haya introducido.
+\item Fusione todos los parches con \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}
+    \hgxopt{mq}{qpush}{-a}}.  La opción \hgxopt{mq}{qpush}{-m} de \hgxcmd{mq}{qpush}
+  le indica a MQ que haga una fusión que involucra tres fuentes si el
+  parche falla al aplicarse.
+\end{enumerate}
+
+Durante el \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, cada parche en
+el fichero \sfilename{series} se aplica normalmente.  Si un parche se
+aplica difusamente o se niea a aplicarse, MQ consulta la cola que
+usted guardó con \hgxcmd{mq}{qsave}, y aplica una fusión de tres con
+el correspondiente conjunto de cambios.  Esta fusión usa la maquinaria
+de Mercurial, por lo tanto puede mostrar una herramienta de fusión GUI
+para ayudarle a resolver los problemas.
+
+Cuando termine de resolver los efectos de un parche, MQ refrescará su
+parche basado en el resultado de la fusión.
+
+Al final de este proceso, su repositorio tendrá una cabeza extra de la
+antigua cola de parches, y una copia de la cola de parches anterio
+estará en \sdirname{.hg/patches.\emph{N}}. Puede eliminar la cabeza
+extra con \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}}
+o \hgcmd{strip}.  Puede eliminar \sdirname{.hg/patches.\emph{N}} una
+vez que esté seguro de que no lo necesita más como copia de seguridad.
+
+\section{Identificar parches}
+
+Las órdenes de MQ le permiten trabajar refiriéndose al nombre del
+parche o al número.  Es obvio hacerlo por el nombre; por ejemplo se
+pasa el nombre \filename{foo.patch} a \hgxcmd{mq}{qpush}, que
+introducirá los parches hasta que \filename{foo.patch} se aplique.  
+
+Para hacerlo más corto, puede referirse a un parche con un nombre y un
+corrimiento de número; por ejemplo,  \texttt{foo.patch-2} significa
+``dos parches antes de \texttt{foo.patch}'', mientras que
+\texttt{bar.patch+4} significa ``cuatro parches después de \texttt{bar.patch}''.
+
+Referirse a un parche por su índice no es muy diferente.  El primer
+parche que se imprime en la salida de \hgxcmd{mq}{qseries} es el
+parche cero (si, es el primero en los sistemas que comienzan su conteo
+en cero); el segundo parche es uno y así sucesivamente.
+
+MQ facilita el trabajo cuando está usando órdenes normales de
+Mercurial.  Cada comando que acepte Identificadores de conjuntos de
+cambios también aceptará el nombre de un parche aplicado.  MQ aumenta
+las etiquetas normalmente en el repositorio con un distintivo para cada
+parche aplicado.  Adicionalmente, las etiquetas especiales \index{tags!special tag
+  names!\texttt{qbase}}\texttt{qbase} y \index{tags!special tag
+  names!\texttt{qtip}}\texttt{qtip} identifican los parches
+``primero'' y último, respectivamente.
+
+Junto con las capacidades de Mercurial para etiquetar, estas adiciones
+hacen que trabajar con parches sea muy sencillo.
+\begin{itemize}
+\item ¿Desea enviar una bomba de parches a una lista de correo con los
+  últimos cambios que ha hecho?
+  \begin{codesample4}
+    hg email qbase:qtip
+  \end{codesample4}
+  (¿No sabe qué es una ``bomba de parches''?  Consulte la
+  sección~\ref{sec:hgext:patchbomb}.)
+\item ¿Desea ver todos los parches desde que se aplicó
+  \texttt{foo.patch} sobre los ficheros de un subdirectorio en su
+  árbol?
+  \begin{codesample4}
+    hg log -r foo.patch:qtip \emph{subdir}
+  \end{codesample4}
+\end{itemize}
+
+Dado que MQ nombra los parches disponibles al resto de Mercurial con
+su maquinaria de etiquetas interna, usted no necesita teclear el
+nombre completo de un parche cuando desea identificarlo por su nombre.
+
+\begin{figure}[ht]
+  \interaction{mq.id.output}
+  \caption{Uso de las características de etiquetamiento al trabajar
+    con MQ}
+  \label{ex:mq:id}
+\end{figure}
+
+Otra consecuencia deseable al representar los nombres de parches como
+etiquetas es que cuando ejecute la orden \hgcmd{log}, desplegará el
+nombre del parche como una etiqueta, usualmente con la salida normal.
+Esto facilita distinguir visualmente los parches aplicados de las
+revisiones ``normales''.  La figura~\ref{ex:mq:id} muestra algunos
+comandos usuales de Mercurial al trabajar con parches.
+
+\section{Otra información útil}
+
+Hay una cantidad de aspectos que hacen que el uso de MQ no representen
+secciones en sí mismas, pero de los cuales es bueno estar
+enterado. Los presentamos en aquí:
+
+\begin{itemize}
+\item Usualmente cuando hace \hgxcmd{mq}{qpop} a un parche y vuelve a
+  hacerle \hgxcmd{mq}{qpush}, el conjunto de cambios que representa el
+  parche después de introducir/sustraer tendrá una  \emph{identidad
+    distinta} que aquella que representaba el conjunto de cambios
+  anteriormente. Consulte la  secctión~\ref{sec:mqref:cmd:qpush} para
+  obtener información del por qué de esto.
+\item No es una buena idea aplicar \hgcmd{merge} de cambios de otra
+  rama con un conjunto de cambios de parches, por lo menos si desea
+  mantener la ``información de parches'' de ese conjunto de cambios y
+  los conjuntos de cambios que se encuentran por debajo en la pila de
+  parches.  Si intenta hacerlo, parecerá que ha sido exitoso, pero MQ
+  se confundirá.
+\end{itemize}
+
+\section{Administrar parches en un repositorio}
+\label{sec:mq:repo}
+
+Dado que el directorio \sdirname{.hg/patches} de MQ reside fuera del
+repositorio de trabajo de Mercurial, el repositorio ``subyacente'' de
+Mercurial no sabe nada acerca de la administración o presencia de
+parches.
+
+Esto presenta la interesante posibilidad de administrar los contenidos
+del directorio de parches como un repositorio de Mercurial por su
+cuenta.  Puede ser una forma útil de trabajar.  Por ejemplo, puede
+trabajar en un parche por un rato, hacerle \hgxcmd{mq}{qrefresh} y
+después hacer \hgcmd{commit} al estado actual del parche.  Esto le
+permite ``devolverse'' a esa versión del parche posteriormente.
+
+Puede también compartir diferentes versiones de la misma pila de
+parches entre varios repositorios subyacentes.  Uso esto cuando estoy
+desarrollando una característica del núcleo Linux.  Tengo una copia
+original de las fuentes del núcleo para varias arquitecturas, y cloné
+un rpositorio en cada una que contiene los parches en los cuales
+estoy trabajando.  Cuando quiero probar un cambio en una arquitectura
+diferente, introduzco mis parches actuales al repositorio de parches
+asociado con el árbol del kernel, sustraigo e introduzco todos mis
+parches, armo y pruebo el núcleo.
+
+Llevar los parches en un repositorio permite que varios
+desarrolladores puedan trabajar en la misma serie de parches sin
+sobreponerse, todo sobre la fuente base subyacente que pueden o no
+controlar.
+
+\subsection{Soporte de MQ para repositorios de parches}
+
+MQ le ayuda a trabajar con el directorio \sdirname{.hg/patches} como
+un repositorio; cuando usted prepara un repositorio para trabajar con
+parches usando \hgxcmd{mq}{qinit}, puede pasarle la opción
+\hgxopt{mq}{qinit}{-c} para que se cree el directorio
+\sdirname{.hg/patches} como un repositorio de Mercurial.
+
+\begin{note}
+  Si olvida usar la opción \hgxopt{mq}{qinit}{-c} option, puede ir al
+  directorio \sdirname{.hg/patches} en cualquier momento y ejecutar
+  \hgcmd{init}.  No olvide añadir una entrada en el fichero
+  \sfilename{status} del fichero \sfilename{.hgignore}, a pesar de que
+  (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} hace estodo de forma
+  automática para usted); usted \emph{seguro} no quiere administrar el
+  fichero \sfilename{status}.
+\end{note}
+
+MQ nota convenientemente que el directorio \dirname{.hg/patches}
+es un repositorio, hará \hgcmd{add} automáticamente a cada parche que
+usted cree e importe.
+
+MQ provee una orden corta, \hgxcmd{mq}{qcommit}, que ejecuta
+\hgcmd{commit} en el directorio \sdirname{.hg/patches}.  Lo que ahorra
+tecleo recurrente.
+
+Finalmente, para administrar convenientemente el directorio de
+parches, puede definir el alias \command{mq} en sistemas Unix.  Por
+ejemplo, en sistemas Linux con el intérprete \command{bash}, puede
+incluir el siguiente recorte de código\ndt{snippet} en su fichero
+\tildefile{.bashrc}.
+
+\begin{codesample2}
+  alias mq=`hg -R \$(hg root)/.hg/patches'
+\end{codesample2}
+
+Puede aplicar las órdenes de la forma \cmdargs{mq}{pull} al
+repositorio principal.
+
+\subsection{Detalles a tener en cuenta}
+
+El soporte de MQ para trabajar con un repositorio de parches es
+limitado en ciertos aspectos:
+
+MQ no puede detectar automáticamente los cambios que haga al
+directorio de parches.  Si aplica \hgcmd{pull}, edita manualmente, o
+hace \hgcmd{update} a los parches o el fichero \sfilename{series},
+tendrá que aplicar \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} y después
+\hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} en el repositorio subyacente
+para que los cambios se reflejen allí.  Si olvida hacerlo, puede
+confundir a MQ en cuanto a qué parches se han aplicado.
+
+\section{Otras herramientas para trabajar con parches}
+\label{sec:mq:tools}
+
+Cuando haya trabajado por cierto tiempo con parches, deseará
+herramientas que le ayuden a entender y manipular los parches con los
+que esté tratando.
+
+La orden \command{diffstat}~\cite{web:diffstat} genera un histograma
+de modificaciones hechas a cada fichero en un parche.  Provee una
+interesante forma de ``dar un vistazo'' al parche---qué ficheros
+afecta, y cuántos cambios introduce a cada fichero y en total.  (Me ha
+parecido interesante usar la opción \cmdopt{diffstat}{-p} de
+\command{diffstat}, puesto que de otra forma intentará hacer cosas
+inteligentes con prefijos de ficheros que terminan confundiéndome.)
+
+\begin{figure}[ht]
+  \interaction{mq.tools.tools}
+  \caption{Las órdenes \command{diffstat}, \command{filterdiff}, y \command{lsdiff}}
+  \label{ex:mq:tools}
+\end{figure}
+
+El paquete \package{patchutils}~\cite{web:patchutils} es
+invaluable. Provee un conjunto de pequeñas utilidades que siguen la
+``filosofía Unix''; cada una hace una cosa muy bien hecha a un
+parche. La orden \package{patchutils} que más uso es
+\command{filterdiff}, que extrae subconjuntos de un fichero de
+parche.  Por ejemplo, dado un parche que modifica centenas de ficheros
+en docenas de directorios, una única invocación de
+\command{filterdiff} puede generear un parche más pequeño que
+solamente toca aquellos ficheros con un patrón.  Puede ver otro
+ejemplo en la sección~\ref{mq-collab:tips:interdiff}.
+
+\section{Buenas prácticas de trabajo con parches}
+
+En caso de que esté trabajando en una serie de parches para enviar a
+un proyecto de software libre o de fuentes abiertas, o en una serie
+que desea tratar como un conjunto de cambios regular, cuando haya
+terminado, puede usar técnicas sencillas para mantener su trabajo bien
+organizado.
+
+De nombres descriptivos a sus parches.  Un buen nombre para un parche
+podría ser \filename{rework-device-alloc.patch}, porque da de forma
+inmediata una pista del propósito del parche. Los nombres largos no
+deben ser un problema; no los estará tecleando repetidamente, pero
+\emph{estará} ejecutando regularmente órdenes como
+\hgxcmd{mq}{qapplied} y \hgxcmd{mq}{qtop}.  Los nombres adecuados son
+especialmente importantes cuando tiene bastantes parches con los
+cuales trabajar, o si está trabajando en diferentes tareas y sus
+parches toman solamente una porción de su atención.
+
+Tenga en cuenta en qué parche está trabajando.  Use la orden \hgxcmd{mq}{qtop}
+para dar un vistazo al texto de sus parches frecuentemente---por
+ejemplo, use \hgcmdargs{tip}{\hgopt{tip}{-p}})---para asegurarse en
+dónde está ubicado.  En distintas oportunidades me sucedió que apliqué
+\hgxcmd{mq}{qrefresh} a un parche distinto al que deseaba hacerlo, y
+usualmente es complejo migrar los cambios al parche correcto después
+de haberlo hecho mal.
+
+Por este motivo, vale la pena invertir ese poco tiempo para aprender
+cómo usar otras herramientas que describí en la
+sección~\ref{sec:mq:tools}, particularmente \command{diffstat} y
+\command{filterdiff}.  La primera le dará una idea de qué cambios está
+haciendo su parche, mientras que la segunda permite seleccionar trozos
+de un parche para colocarlos en otro.
+
+\section{Recetas de MQ}
+
+\subsection{Administrar parches ``triviales''}
+
+Puesto que colocar ficheros en un repositorio de Mercurial es tan
+sencillo, tiene bastante sentido administrar parches de esta forma
+incluso si desea hacer algunos cambios al paquete de ficheros que
+descargó.
+
+Para comenzar a descargar y desempaqueter un paquete de ficheros, y
+volverlo en un repositorio de Mercurial:
+\interaction{mq.tarball.download}
+
+Continue creando una pila de parches y haga sus cambios.
+\interaction{mq.tarball.qinit}
+
+Digamos que pasan unas semanas o meses, y el autor del paquete libera
+una nueva versión.  Primero se traen sus cambios al repositorio.
+\interaction{mq.tarball.newsource}
+La porción que comienza con \hgcmd{locate} mostrada más arriba, borra
+todos los ficheros en el directorio de trabajo, así que la opción
+\hgopt{commit}{--addremove} de \hgcmd{commit} puede indicar qué
+ficheros se han eliminado en la nueva versión del árbol de fuentes.
+
+Finalmente, puede aplicar sus parches encima del nuevo árbol de fuentes
+\interaction{mq.tarball.repush}
+
+\subsection{Combinar parches completos}
+\label{sec:mq:combine}
+
+MQ provee la orden \hgxcmd{mq}{qfold} que le permite combinar parches
+enteros.  Se ``integran''\ndt{fold} los parches que usted nombre, en
+el orden que especifique, en el último parche aplicado, y concatena
+sus descripciones al final de su descripción.  Deberá sustraer los
+cambios para poder integrarlos.
+
+El orden en el que integre los parches importa.  Si el parche
+últimamente aplicado es \texttt{foo}, e integra \hgxcmd{mq}{qfold} \texttt{bar} y
+\texttt{quux} en él, terminará con un parche que tiene el mismo efecto
+que si hubiera aplicado primero \texttt{foo}, y después \texttt{bar},
+seguido de \texttt{quux}.
+
+\subsection{Fusionar una porción de un parche dentro de otro}
+
+Fusionar \emph{partes} de un parche dentro de otro es más complejo que
+combinar completamente dos parches.
+
+Si desea mover cambios de ficheros completos, puede usar las opciones
+\command{filterdiff}'s \cmdopt{filterdiff}{-i} y
+\cmdopt{filterdiff}{-x} para elegir las modificaciones remover de un
+parche, concatenar su salida al final del parche donde desea
+fusionarlo.  Usualmente no necesitará modificar el parche del cuál ha
+fusionado los cambios.  En cambio, MQ reportará que hay unos trozos
+que se han desechado cuando usted aplique \hgxcmd{mq}{qpush} (de los
+trozos que haya movido al otro parche), y puede sencillamente aplicar
+\hgxcmd{mq}{qrefresh} para eliminar los trozos replicados.
+
+Si tiene un parche que tiene varios trozos que modifican un fichero, y
+desea mover solamente unos de ellos, el trabajo es un poco más
+enredado, pero puede automatizarlo parcialmente.  Use
+\cmdargs{lsdiff}{-nvv} para imprimir algunos metadatos del parche.
+\interaction{mq.tools.lsdiff}
+
+Esta orden imprime tres clases diferentes de números:
+\begin{itemize}
+\item (en la primera columna) un \emph{número de fichero} para
+  identificar cada fichero modificado en el parche;
+\item (En la siguiente línea, indentado) el número de línea dentro de
+  un fichero modificado donde comienza el trozo; y
+\item (en la misma línea) un \emph{número de trozo} que identifica el
+  trozo.
+\end{itemize}
+
+Tendrá que hacer una inspección visual, y leer el parche para
+identificar los números de fichero y trozo que desea, pero puede pasar
+posteriormente a las opciones \cmdopt{filterdiff}{--files} y 
+\cmdopt{filterdiff}{--hunks} de \command{filterdiff}, para seleccionar
+exactamente el fichero y el trozo que desea extraer.
+
+Cuando tenga el trozo, puede concatenarlo al final de su parche
+objetivo y continuar como en la sección~\ref{sec:mq:combine}.
+
+\section{Diferencias entre quilt y MQ}
+
+Si le es familiar quilt, MQ provee un conjunto similar de órdenes. Hay
+algunas diferencias en cómo funcionan.
+
+Debe haber notado que la mayoría de comandos de quilt tienen su
+contraparte en MQ, que simplemente comienzan con ``\texttt{q}''.  Las
+excepciones son las órdenes \texttt{add} y \texttt{remove} de quilt,
+que realmente son las órdenes \hgcmd{add} y \hgcmd{remove} de
+Mercurial.  No hay un equivalente en MQ para la orden
+\texttt{edit} de quilt.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
Binary file es/note.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/preface.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,74 @@
+\chapter*{Prefacio}
+\addcontentsline{toc}{chapter}{Prefacio}
+\label{chap:preface}
+
+El control distribuido de revisiones es un territorio relativamente 
+nuevo, y ha crecido hasta ahora 
+% TODO el original dice "due to", que sería "debido", pero creo que "gracias
+% a" queda mejor 
+gracias a  a la voluntad que tiene la gente de salir y explorar
+territorios desconocidos.
+% TODO revisar la frase anterior. me tomé muchas licencias para
+% traducirla
+
+Estoy escribiendo este libro acerca de control de revisiones
+distribuido porque creo que es un tema importante que merece una guía
+de campo. Escogí escribir acerca de Mercurial porque es la herramienta
+%TODO puse explorar en vez de aprender, you be the judge dear reviewer ;)
+más fácil para explorar el terreno, y sin embargo escala a las
+demandas de retadores ambientes reales donde muchas otras herramientas
+de control de revisiones fallan.
+
+\section{Este libro es un trabajo en progreso}
+Estoy liberando este libro mientras lo sigo escribiendo, con la
+esperanza de que pueda ser útil a otros. También espero que los
+lectores contribuirán como consideren adecuado.
+
+\section{Acerca de los ejemplos en este libro}
+Este libro toma un enfoque inusual hacia las muestras de código. Cada
+ejemplo está ``en directo''---cada uno es realmente el resultado de un
+% TODO shell script
+script de shell que ejecuta los comandos de Mercurial que usted ve.
+Cada vez que una copia del libro es construida desde su código fuente,
+% TODO scripts
+todos los scripts de ejemplo son ejecutados automáticamente, y sus
+resultados actuales son comparados contra los resultados esperados.
+
+La ventaja de este enfoque es que los ejemplos siempre son precisos;
+ellos describen \emph{exactamente} el comportamiento de la versión de
+Mercurial que es mencionada en la portada del libro. Si yo actualizo
+la versión de Mercurial que estoy documentando, y la salida de algún
+comando cambia, la construcción falla.
+
+Hay una pequeña desventaja de este enfoque, que las fechas y horas que
+usted verá en los ejemplos tienden a estar ``aplastadas'' juntas de una
+forma que no sería posible si los mismos comandos fueran escritos por
+un humano. Donde un humano puede emitir no más de un comando cada
+pocos segundos, con cualquier marca de tiempo resultante
+correspondientemente separada, mis scripts automatizados de ejemplos
+ejecutan muchos comandos en un segundo.
+
+% TODO commit
+Como un ejemplo de esto, varios commits consecutivos en un ejemplo
+pueden aparecer como habiendo ocurrido durante el mismo segundo. Usted
+puede ver esto en el ejemplo \hgext{bisect} en la
+sección~\ref{sec:undo:bisect}, por ejemplo.
+
+Así que cuando usted lea los ejemplos, no le dé mucha importancia a
+las fechas o horas que vea en las salidas de los comandos. Pero
+\emph{tenga} confianza en que el comportamiento que está viendo es
+consistente y reproducible.
+
+\section{Colofón---este libro es Libre}
+Este libro está licenciado bajo la Licencia de Publicación Abierta, y
+es producido en su totalidad usando herramientas de Software Libre. Es
+compuesto con \LaTeX{}; las ilustraciones son dibujadas y generadas
+con \href{http://www.inkscape.org/}{Inkscape}.
+
+El código fuente completo para este libro es publicado como un
+repositorio Mercurial, en \url{http://hg.serpentine.com/mercurial/book}.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/revlog.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="revlog.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2726" />
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3092">
+      <stop
+         style="stop-color:#44436f;stop-opacity:1;"
+         offset="0"
+         id="stop3094" />
+      <stop
+         style="stop-color:#abade5;stop-opacity:1;"
+         offset="1"
+         id="stop3096" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3118"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3120"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3129"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934"
+       gradientTransform="translate(-0.928574,-1.428574)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3133"
+       gradientUnits="userSpaceOnUse"
+       x1="176.16635"
+       y1="405.21934"
+       x2="417.11935"
+       y2="405.21934"
+       gradientTransform="translate(-0.928574,-1.428574)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient3708"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,138.874,-67.01732)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5164"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,247.4358)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5584"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,143.9081,371.2915)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5784"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5786"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.249,152.137)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5895"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,198.0215,261.7142)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3092"
+       id="linearGradient5958"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.423343,0,0,0.423343,137.1978,42.55987)"
+       x1="175.23776"
+       y1="509.98154"
+       x2="416.29077"
+       y2="297.49997" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.8101934"
+     inkscape:cx="199.78816"
+     inkscape:cy="863.27363"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="29"
+     inkscape:window-y="79"
+     inkscape:connector-spacing="11"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="168.74846"
+       x="211.58516"
+       height="89.506805"
+       width="101.60232"
+       id="rect3068"
+       style="fill:url(#linearGradient5958);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g3215"
+       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55985)">
+      <rect
+         y="447.71451"
+         x="299.67859"
+         height="48.571426"
+         width="103.14286"
+         id="rect2899"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2903"
+         y="464.8139"
+         x="308.89639"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.8139"
+           x="308.89639"
+           sodipodi:role="line"
+           id="tspan2905">Segundo padre</tspan></text>
+      <text
+         id="text2907"
+         y="485.50256"
+         x="308.20175"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.50256"
+           x="308.20175"
+           id="tspan2909"
+           sodipodi:role="line">32bf9a5f22c0</tspan></text>
+    </g>
+    <g
+       id="g3250"
+       transform="matrix(0.423343,0,0,0.423343,137.1977,42.55986)">
+      <rect
+         y="311.28598"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect2936"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2940"
+         y="328.38538"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="328.38538"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan2942">Hash de revisión</tspan></text>
+      <text
+         id="text2944"
+         y="349.07404"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="349.07404"
+           x="197.13031"
+           id="tspan2946"
+           sodipodi:role="line">34b8b7a15ea1</tspan></text>
+    </g>
+    <g
+       id="g3243"
+       transform="matrix(0.423343,0,0,0.423343,137.6664,43.91853)">
+      <rect
+         y="363.07654"
+         x="187.5"
+         height="75"
+         width="213.85715"
+         id="rect2950"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text2958"
+         y="400.86459"
+         x="196.02321"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:black;fill-opacity:1;font-family:Courier"
+           y="400.86459"
+           x="196.02321"
+           id="tspan2960"
+           sodipodi:role="line">...</tspan></text>
+      <text
+         id="text2954"
+         y="380.17593"
+         x="196.71785"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="380.17593"
+           x="196.71785"
+           sodipodi:role="line"
+           id="tspan2956"
+           style="fill:#000000;fill-opacity:1">Datos de Revisión (delta o snapshot)</tspan></text>
+    </g>
+    <g
+       id="g5529"
+       transform="translate(-6.710312,-8.165836e-6)">
+      <rect
+         style="fill:url(#linearGradient5584);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3509"
+         width="101.60232"
+         height="89.506805"
+         x="218.29547"
+         y="497.4801" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
+         id="g3513">
+        <g
+           id="g3515">
+          <rect
+             y="447.72418"
+             x="188.6071"
+             height="48.571426"
+             width="103.14286"
+             id="rect3517"
+             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text3519"
+             y="464.82358"
+             x="197.82495"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               y="464.82358"
+               x="197.82495"
+               sodipodi:role="line"
+               id="tspan3521">Primer padre</tspan></text>
+          <text
+             id="text3523"
+             y="485.51224"
+             x="197.13031"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="485.51224"
+               x="197.13031"
+               id="tspan3525"
+               sodipodi:role="line">000000000000</tspan></text>
+        </g>
+        <g
+           id="g3527">
+          <rect
+             y="447.71451"
+             x="299.67859"
+             height="48.571426"
+             width="103.14286"
+             id="rect3529"
+             style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <text
+             id="text3531"
+             y="464.8139"
+             x="308.89639"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               y="464.8139"
+               x="308.89639"
+               sodipodi:role="line"
+               id="tspan3533">Segundo padre</tspan></text>
+          <text
+             id="text3535"
+             y="485.50256"
+             x="308.20175"
+             style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+             xml:space="preserve"><tspan
+               style="font-family:Courier"
+               y="485.50256"
+               x="308.20175"
+               id="tspan3537"
+               sodipodi:role="line">000000000000</tspan></text>
+        </g>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,143.908,371.2915)"
+         id="g3539">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3541"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3543"><tspan
+             id="tspan3545"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Hash de revisión</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3547"><tspan
+             sodipodi:role="line"
+             id="tspan3549"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,144.3767,372.6502)"
+         id="g3551">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3553"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3555"><tspan
+             sodipodi:role="line"
+             id="tspan3557"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3559"><tspan
+             style="fill:#000000;fill-opacity:1"
+             id="tspan3561"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Datos de revisión (delta o snapshot)</tspan></text>
+      </g>
+    </g>
+    <g
+       id="g4868"
+       transform="translate(-1.676208,-2.342463e-5)">
+      <rect
+         style="fill:url(#linearGradient3708);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3567"
+         width="101.60232"
+         height="89.506805"
+         x="213.26137"
+         y="59.171272" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
+         id="g3573">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3575"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3577"><tspan
+             id="tspan3579"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">Primer padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3581"><tspan
+             sodipodi:role="line"
+             id="tspan3583"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">34b8b7a15ea1</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01734)"
+         id="g3585">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3587"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3589"><tspan
+             id="tspan3591"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Segundo padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3593"><tspan
+             sodipodi:role="line"
+             id="tspan3595"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,138.8739,-67.01733)"
+         id="g3597">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3599"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3601"><tspan
+             id="tspan3603"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Hash de revisión</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3605"><tspan
+             sodipodi:role="line"
+             id="tspan3607"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">1b67dc96f27a</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,139.3426,-65.65866)"
+         id="g3609">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3611"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3613"><tspan
+             sodipodi:role="line"
+             id="tspan3615"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3617"><tspan
+             style="fill:#000000;fill-opacity:1"
+             id="tspan3619"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Datos de revisión (delta o snapshot)</tspan></text>
+      </g>
+    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Mend)"
+       d="M 240.78255,143.08593 L 241.42595,171.75349"
+       id="path3801"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3573"
+       inkscape:connection-end="#g3250" />
+    <g
+       id="g5677">
+      <rect
+         style="fill:url(#linearGradient5784);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3393"
+         width="101.60232"
+         height="89.506805"
+         x="150.76137"
+         y="278.32565" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3399">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3401"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3403"><tspan
+             id="tspan3405"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">Primer padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3407"><tspan
+             sodipodi:role="line"
+             id="tspan3409"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">ff9dc8bc2a8b</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3411">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3413"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3415"><tspan
+             id="tspan3417"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Segundo padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3419"><tspan
+             sodipodi:role="line"
+             id="tspan3421"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.37397,152.137)"
+         id="g3423">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3425"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3427"><tspan
+             id="tspan3429"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Hash de revisión</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3431"><tspan
+             sodipodi:role="line"
+             id="tspan3433"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">5b80c922ebdd</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,76.84265,153.4957)"
+         id="g3435">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3437"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3439"><tspan
+             sodipodi:role="line"
+             id="tspan3441"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3443"><tspan
+             style="fill:#000000;fill-opacity:1"
+             id="tspan3445"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Datos de revisión (delta o snapshot)</tspan></text>
+      </g>
+    </g>
+    <g
+       id="g5646"
+       transform="translate(-0.227432,0)">
+      <rect
+         style="fill:url(#linearGradient5786);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect3451"
+         width="101.60232"
+         height="89.506805"
+         x="272.63638"
+         y="278.32565" />
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3457">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3459"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="447.72418" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="464.82358"
+           id="text3461"><tspan
+             id="tspan3463"
+             sodipodi:role="line"
+             x="197.82495"
+             y="464.82358">Primer padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="485.51224"
+           id="text3465"><tspan
+             sodipodi:role="line"
+             id="tspan3467"
+             x="197.13031"
+             y="485.51224"
+             style="font-family:Courier">ecacb6b4c9fd</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3469">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3471"
+           width="103.14286"
+           height="48.571426"
+           x="299.67859"
+           y="447.71451" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.89639"
+           y="464.8139"
+           id="text3473"><tspan
+             id="tspan3475"
+             sodipodi:role="line"
+             x="308.89639"
+             y="464.8139">Segundo padre</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="308.20175"
+           y="485.50256"
+           id="text3477"><tspan
+             sodipodi:role="line"
+             id="tspan3479"
+             x="308.20175"
+             y="485.50256"
+             style="font-family:Courier">000000000000</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.2489,152.137)"
+         id="g3481">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3483"
+           width="103.14286"
+           height="48.571426"
+           x="188.6071"
+           y="311.28598" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.82495"
+           y="328.38538"
+           id="text3485"><tspan
+             id="tspan3487"
+             sodipodi:role="line"
+             x="197.82495"
+             y="328.38538">Hash de revisión</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="197.13031"
+           y="349.07404"
+           id="text3489"><tspan
+             sodipodi:role="line"
+             id="tspan3491"
+             x="197.13031"
+             y="349.07404"
+             style="font-family:Courier">32bf9a5f22c0</tspan></text>
+      </g>
+      <g
+         transform="matrix(0.423343,0,0,0.423343,198.7176,153.4957)"
+         id="g3493">
+        <rect
+           style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="rect3495"
+           width="213.85715"
+           height="75"
+           x="187.5"
+           y="363.07654" />
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.02321"
+           y="400.86459"
+           id="text3497"><tspan
+             sodipodi:role="line"
+             id="tspan3499"
+             x="196.02321"
+             y="400.86459"
+             style="fill:black;fill-opacity:1;font-family:Courier">...</tspan></text>
+        <text
+           xml:space="preserve"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           x="196.71785"
+           y="380.17593"
+           id="text3501"><tspan
+             style="fill:#000000;fill-opacity:1"
+             id="tspan3503"
+             sodipodi:role="line"
+             x="196.71785"
+             y="380.17593">Datos de revisión (delta o snapshot)</tspan></text>
+      </g>
+    </g>
+    <rect
+       y="387.90286"
+       x="272.40894"
+       height="89.506805"
+       width="101.60232"
+       id="rect5081"
+       style="fill:url(#linearGradient5895);fill-opacity:1;stroke:black;stroke-width:0.48811448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g5087"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="447.72418"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect5089"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5091"
+         y="464.82358"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.82358"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan5093">Primer padre</tspan></text>
+      <text
+         id="text5095"
+         y="485.51224"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.51224"
+           x="197.13031"
+           id="tspan5097"
+           sodipodi:role="line">ff9dc8bc2a8b</tspan></text>
+    </g>
+    <g
+       id="g5099"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="447.71451"
+         x="299.67859"
+         height="48.571426"
+         width="103.14286"
+         id="rect5101"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5103"
+         y="464.8139"
+         x="308.89639"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="464.8139"
+           x="308.89639"
+           sodipodi:role="line"
+           id="tspan5105">Segundo padre</tspan></text>
+      <text
+         id="text5107"
+         y="485.50256"
+         x="308.20175"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="485.50256"
+           x="308.20175"
+           id="tspan5109"
+           sodipodi:role="line">000000000000</tspan></text>
+    </g>
+    <g
+       id="g5111"
+       transform="matrix(0.423343,0,0,0.423343,198.0214,261.7142)">
+      <rect
+         y="311.28598"
+         x="188.6071"
+         height="48.571426"
+         width="103.14286"
+         id="rect5113"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5115"
+         y="328.38538"
+         x="197.82495"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="328.38538"
+           x="197.82495"
+           sodipodi:role="line"
+           id="tspan5117">Hash de revisión</tspan></text>
+      <text
+         id="text5119"
+         y="349.07404"
+         x="197.13031"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="349.07404"
+           x="197.13031"
+           id="tspan5121"
+           sodipodi:role="line">ecacb6b4c9fd</tspan></text>
+    </g>
+    <g
+       id="g5123"
+       transform="matrix(0.423343,0,0,0.423343,198.4901,263.0729)">
+      <rect
+         y="363.07654"
+         x="187.5"
+         height="75"
+         width="213.85715"
+         id="rect5125"
+         style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5127"
+         y="400.86459"
+         x="196.02321"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:black;fill-opacity:1;font-family:Courier"
+           y="400.86459"
+           x="196.02321"
+           id="tspan5129"
+           sodipodi:role="line">...</tspan></text>
+      <text
+         id="text5131"
+         y="380.17593"
+         x="196.71785"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="380.17593"
+           x="196.71785"
+           sodipodi:role="line"
+           id="tspan5133"
+           style="fill:#000000;fill-opacity:1">Datos de revisión (delta o snapshot)</tspan></text>
+    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 299.69935,362.24027 L 299.69931,393.49494"
+       id="path5203"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3457"
+       inkscape:connection-end="#g5111" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 182.35357,362.22647 L 241.2842,503.07224"
+       id="path5271"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3399"
+       inkscape:connection-end="#g3539" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 287.63109,471.81747 L 250.9438,503.07223"
+       id="path5285"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g5087"
+       inkscape:connection-end="#g3539" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 290.80419,250.07192 L 297.80065,283.90394"
+       id="path5077"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g3215"
+       inkscape:connection-end="#g3481" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 229.63373,250.07601 L 190.07484,283.90394"
+       id="path5075"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g3423" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="100.79968"
+       id="text5897"><tspan
+         sodipodi:role="line"
+         id="tspan5899"
+         x="131.5625"
+         y="100.79968"
+         style="text-align:end;text-anchor:end">Revisión principal</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="115.79968"
+         id="tspan5901"
+         style="text-align:end;text-anchor:end">(sin hijos)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="207.04968"
+       id="text5903"><tspan
+         sodipodi:role="line"
+         id="tspan5905"
+         x="131.5625"
+         y="207.04968"
+         style="text-align:end;text-anchor:end">Revisión de fusión</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="222.04968"
+         id="tspan5907"
+         style="text-align:end;text-anchor:end">(dos padres)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.92578"
+       y="451.58093"
+       id="text5909"><tspan
+         sodipodi:role="line"
+         id="tspan5911"
+         x="131.92578"
+         y="451.58093"
+         style="text-align:end;text-anchor:end">Ramas</tspan><tspan
+         sodipodi:role="line"
+         x="131.92578"
+         y="466.58093"
+         id="tspan5913"
+         style="text-align:end;text-anchor:end">(dos revisiones,</tspan><tspan
+         sodipodi:role="line"
+         x="131.92578"
+         y="481.58093"
+         id="tspan5915"
+         style="text-align:end;text-anchor:end">mismo padre)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 111.71875,433.61218 L 154.7268,368.52294"
+       id="path5917"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 134.375,464.86218 L 277.86691,440.37816"
+       id="path5919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g5123" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:end;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="131.5625"
+       y="536.73718"
+       id="text5927"><tspan
+         sodipodi:role="line"
+         id="tspan5929"
+         x="131.5625"
+         y="536.73718">Primera revisión</tspan><tspan
+         sodipodi:role="line"
+         x="131.5625"
+         y="551.73718"
+         id="tspan5931">(ambos padres nulos)</tspan></text>
+    <rect
+       style="fill:#bbb4ff;fill-opacity:1;stroke:none;stroke-width:0.95291203;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2830"
+       width="43.664806"
+       height="20.562374"
+       x="217.0432"
+       y="232.10075" />
+    <text
+       xml:space="preserve"
+       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="220.94551"
+       y="239.33966"
+       id="text2832"><tspan
+         id="tspan2836"
+         sodipodi:role="line"
+         x="220.94551"
+         y="239.33966">Primer padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:5.0801158px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="220.65144"
+       y="248.09805"
+       id="text2879"><tspan
+         sodipodi:role="line"
+         id="tspan2881"
+         x="220.65144"
+         y="248.09805"
+         style="font-family:Courier">5b80c922ebdd</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 139.84375,107.83093 L 210.15625,107.83093"
+       id="path5965"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 137.5,213.29968 L 210.49036,214.09055"
+       id="path5967"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 1;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 136.34375,544.54968 L 206.65625,544.54968"
+       id="path5969"
+       inkscape:connector-type="polyline"
+       inkscape:transform-center-y="-171.09375"
+       inkscape:transform-center-x="53.90625" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/snapshot.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2807"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="snapshot.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs2809">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2759" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="252.04111"
+     inkscape:cy="605.75448"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="721"
+     inkscape:window-x="141"
+     inkscape:window-y="57"
+     showgrid="false" />
+  <metadata
+     id="metadata2812">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#d3ceff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.88795626;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2817"
+       width="118.18347"
+       height="245.32632"
+       x="243.05112"
+       y="315.4133"
+       inkscape:transform-center-x="136.84403"
+       inkscape:transform-center-y="-66.529183" />
+    <rect
+       y="315.04153"
+       x="46.965065"
+       height="97.803009"
+       width="108.92702"
+       id="rect2815"
+       style="fill:#ffced6;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.14441991;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g3814">
+      <rect
+         y="348.94302"
+         x="59.285713"
+         height="30"
+         width="84.285713"
+         id="rect2819"
+         style="fill:#ff6e86;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         ry="0" />
+      <text
+         id="text2821"
+         y="368.02701"
+         x="72.717636"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="368.02701"
+           x="72.717636"
+           id="tspan2823"
+           sodipodi:role="line">Índice, rev 7</tspan></text>
+    </g>
+    <text
+       id="text3722"
+       y="303.43359"
+       x="22.61635"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       xml:space="preserve"><tspan
+         y="303.43359"
+         x="22.61635"
+         id="tspan3724"
+         sodipodi:role="line">Índice de bitácora de revisiones (archivo .i)</tspan></text>
+    <text
+       id="text3726"
+       y="301.29074"
+       x="241.90207"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       xml:space="preserve"><tspan
+         y="301.29074"
+         x="241.90207"
+         id="tspan3728"
+         sodipodi:role="line">Datos de Bitacora de revisiones (archivo .d)</tspan></text>
+    <path
+       style="fill:#c695ff;fill-opacity:0.60109288;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 143.57143,348.07647 L 255,368.07646 L 255.71429,544.50504 L 142.85714,379.50504 L 143.57143,348.07647 z "
+       id="path3839"
+       sodipodi:nodetypes="ccccc" />
+    <rect
+       style="fill:#4733ff;fill-opacity:1;stroke:#a7a7a7;stroke-width:2.35124183;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3752"
+       width="92.720184"
+       height="67.005905"
+       x="255.42564"
+       y="368.64264" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="264.45859"
+       y="387.30099"
+       id="text3754"><tspan
+         sodipodi:role="line"
+         id="tspan3756"
+         x="264.45859"
+         y="387.30099">Snapshot, rev 4</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3761"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="442.04395" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="460.17206"
+       id="text3763"><tspan
+         sodipodi:role="line"
+         id="tspan3765"
+         x="263.2662"
+         y="460.17206">Delta, rev 4 a 5</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3774"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="477.97485" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="496.10297"
+       id="text3776"><tspan
+         sodipodi:role="line"
+         id="tspan3778"
+         x="263.2662"
+         y="496.10297">Delta, rev 5 a 6</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3782"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="513.90576" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="532.03387"
+       id="text3784"><tspan
+         sodipodi:role="line"
+         id="tspan3786"
+         x="263.2662"
+         y="532.03387">Delta, rev 6 a 7</tspan></text>
+    <rect
+       style="fill:#7c6eff;fill-opacity:1;stroke:#a7a7a7;stroke-width:1.57776296;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3889"
+       width="93.49366"
+       height="29.922237"
+       x="255.03891"
+       y="332.32489" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="263.2662"
+       y="350.453"
+       id="text3891"><tspan
+         sodipodi:role="line"
+         id="tspan3893"
+         x="263.2662"
+         y="350.453">Delta, rev 2 a 3</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/srcinstall.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,55 @@
+\chapter{Instalar Mercurial desde las fuentes}
+\label{chap:srcinstall}
+
+\section{En un sistema tipo Unix}
+\label{sec:srcinstall:unixlike}
+
+Si usa un sistema tipo Unix que tiene una versión suficientemente
+reciente de Python (2.3~o superior) disponible, es fácil instalar
+Mercurial desde las fuentes.
+\begin{enumerate}
+\item Descargue un paquete fuente reciente de
+  \url{http://www.selenic.com/mercurial/download}.
+\item Descomprímalo:
+  \begin{codesample4}
+    gzip -dc mercurial-\emph{version}.tar.gz | tar xf -
+  \end{codesample4}
+\item Vaya al directorio fuente y ejecute el guión de instalación.
+  Esto armará Mercurial y lo instalará en su directorio casa:
+  \begin{codesample4}
+    cd mercurial-\emph{version}
+    python setup.py install --force --home=\$HOME
+  \end{codesample4}
+\end{enumerate}
+Cuando termine la instalación, Mercurial estará en el subdirectorio
+\texttt{bin} de su directorio casa.  No olvide asegurarse de que este
+directorio esté presente en el camino de búsqueda de su intérprete de
+órdenes.
+
+Probablemente necesitará establecer la variable de ambiente
+\envar{PYTHONPATH} de tal forma que los ejecutables de Mercurial
+puedan encontrar el resto de los paquetes de Mercurial.  Por ejemplo,
+en mi portátil, la establecía a \texttt{/home/bos/lib/python}.  La
+ruta exacta que usted use dependerá de como ha sido construído Python
+en su sistema, pero debería ser fácil deducirla.  Si no está seguro,
+mire lo que haya mostrado el script en el paso anterior, y vea dónde
+se instalaron los contenidos del directorio \texttt{mercurial} se
+instalaron.
+
+\section{En Windows}
+
+Armar e instalar Mercurial en Windows requiere una variedad de
+herramientas, cierta suficiencia técnica y paciencia considerable.
+Personalmente, \emph{no le recomiendo} hacerlo si es un ``usuario
+casual''.  A menos que intente hacer hacks a Mercurial, le recomiendo
+que mejor use un paquete binario.
+
+Si está decidido a construir Mercurial desde las fuentes en Windows,
+siga el ``camino difícil'' indicado en el wiki de Mercurial en
+\url{http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall},
+y espere que el proceso sea realmente un trabajo duro.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/template.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,497 @@
+\chapter{Personalizar los mensajes de Mercurial}
+\label{chap:template}
+
+Mercurial provee un poderoso mecanismo que permite controlar como
+despliega la información.  El mecanismo se basa en plantillas.  Puede
+usar plantillas para generar salida específica para una orden
+particular o para especificar la visualización completa de la interfaz
+web embebida.
+
+\section{Usar estilos que vienen con Mercurial}
+\label{sec:style}
+
+Hay ciertos estilos listos que vienen con Mercurial.  Un estilo es
+simplemente una plantilla predeterminada que alguien escribió e
+instaló en un sitio en el cual Mercurial puede encontrarla.
+
+Antes de dar un vistazo a los estilos que trae Mercurial, revisemos su
+salida usual.
+
+\interaction{template.simple.normal}
+
+Es en cierta medida informativa, pero ocupa mucho espacio---cinco
+líneas de salida por cada conjunto de cambios.  El estilo
+\texttt{compact} lo reduce a tres líneas, presentadas de forma
+suscinta.
+
+\interaction{template.simple.compact}
+
+El estilo de la \texttt{bitácora de cambios} vislumbra el poder
+expresivo del sistema de plantillas de Mercurial.  Este estilo busca
+seguir los estándares de bitácora de cambios del proyecto
+GNU\cite{web:changelog}.
+
+\interaction{template.simple.changelog}
+
+No es una sorpresa que el estilo predeterminado de Mercurial se llame
+\texttt{default}\ndt{predeterminado}.
+
+\subsection{Especificar un estilo predeterminado}
+
+Puede modificar el estilo de presentación que Mercurial usará para
+toda orden vía el fichero \hgrc\, indicando el estilo que prefiere
+usar.
+
+\begin{codesample2}
+  [ui]
+  style = compact
+\end{codesample2}
+
+Si escribe un estilo, puede usarlo bien sea proveyendo la ruta a su
+fichero de estilo o copiando su fichero de estilo a un lugar en el
+cual Mercurial pueda encontrarlo (típicamente el subdirectorio
+\texttt{templates} de su directorio de instalación de Mercurial).
+
+\section{Órdenes que soportan estilos y plantillas}
+
+Todas las órdenes de Mercurial``relacionadas con \texttt{log}'' le
+permiten usar estilos y plantillas: \hgcmd{incoming}, \hgcmd{log},
+\hgcmd{outgoing} y \hgcmd{tip}.
+
+Al momento de la escritura del manual estas son las únicas órdenes que
+soportan estilos y plantillas.  Dado que son las órdenes más
+importantes que necesitan personalización, no ha habido muchas
+solicitudes desde la comunidad de usuarios de Mercurial para añadir
+soporte de plantillas y estilos a otras órdenes.
+
+\section{Cuestiones básicas de plantillas}
+
+Una plantilla de Mercurial es sencillamente una pieza de texto.
+Cierta porción nunca cambia, otras partes se \emph{expanden}, o
+reemplazan con texto nuevo cuando es necesario.
+
+Antes de continuar, veamos de nuevo un ejemplo sencillo de la salida
+usual de Mercurial:
+
+\interaction{template.simple.normal}
+
+Ahora, ejecutemos la misma orden, pero usemos una plantilla para
+modificar su salida:
+
+\interaction{template.simple.simplest}
+
+El ejemplo anterior ilustra la plantilla más sencilla posible;  es
+solamente una porción estática de código que se imprime una vez por
+cada conjunto de cambios.  La opción \hgopt{log}{--template} de la
+orden \hgcmd{log} indica a Mercurial usar el texto dado como la
+plantilla cuando se imprime cada conjunto de cambios.
+
+Observe que la cadena de plantilla anterior termina con el texto
+``\Verb+\n+''.  Es una \emph{secuencia de control}, que le indica a
+Mercurial imprimira una nueva línea al final de cada objeto de la
+plantilla.  Si omite esta nueva línea, Mercurial colocará cada pieza
+de salida seguida.  Si desea más detalles acerca de secuencias de
+control, vea la sección~\ref{sec:template:escape}.
+
+Una plantilla que imprime una cadena fija de texto siempre no es muy
+útil; intentemos algo un poco más complejo.
+
+\interaction{template.simple.simplesub}
+
+Como puede ver, la cadena ``\Verb+{desc}+'' en la plantilla ha sido
+reemplazada en la salida con la descricipción de cada conjunto de
+cambios.  Cada vez que Mercurial encuentra texto encerrado entre
+corchetes (``\texttt{\{}'' y ``\texttt{\}}''), intentará reemplazar los
+corchetes y el texto con la expansión de lo que sea está adentro.
+Para imprimir un corchete de forma literal, debe escaparlo, como se
+describe en la sección~\ref{sec:template:escape}.
+
+\section{Palabras claves más comunes en las plantillas}
+\label{sec:template:keyword}
+
+Puede empezar a escribir plantillas sencillas rápidamente con las
+palabras claves descritas a continuación:
+
+\begin{itemize}
+\item[\tplkword{author}] Cadena.  El autor NO modificado del conjunto
+  de cambios.
+\item[\tplkword{branches}] Cadena.  El nombre de la rama en la cual se
+  consignó el conjunto de cambios.  Será vacía si el nombre de la rama es
+  \texttt{default}.
+\item[\tplkword{date}] Información de fecha.  La fecha en la cual se
+  consignó el conjunto de cambios.  \emph{No} es legible por un
+  humano, debe pasarla por un firltro que la desplegará
+  apropiadamente.  En la sección~\ref{sec:template:filter} hay más
+  detalles acerca de filtros.  La fecha se expresa como un par de
+  números.  El primer número corresponde a una marca de tiempo UNIX
+  UTC (segundos desde el primero de enero de 1970); la segunda es el
+  corrimiento horario de la zona horaria del UTC en la cual se encontraba
+  quien hizo la consignación, en segundos.
+\item[\tplkword{desc}] Cadena.  La descripción en texto del conjunto
+  de cambios.
+\item[\tplkword{files}] Lista de cadenas.  Todos los ficheros
+  modificados, adicionados o eliminados por este conjunto de cambios.
+\item[\tplkword{file\_adds}] Lista de cadenas.  Ficheros adicionados
+  por este conjunto de cambios.
+\item[\tplkword{file\_dels}] Lista de cadenas.  Ficheros eliminados
+  por este conjunto de cambios.
+\item[\tplkword{node}] Cadena.  El hash de identificación de este
+  conjunto de cambios como una cadena hexadecimal de 40 caracteres.
+\item[\tplkword{parents}] Lista de cadenas.  Los ancestros del
+  conjunto de cambios.
+\item[\tplkword{rev}] Entero.  El número de revisión del repositorio
+  local.
+\item[\tplkword{tags}] Lista de cadenas.  Todas las etiquetas
+  asociadas al conjunto de cambios.
+\end{itemize}
+
+Unos experimentos sencillos nos mostrarán qué esperar cuando usamos
+estas palabras claves; puede ver los resultados en la
+figura~\ref{fig:template:keywords}.
+
+\begin{figure}
+  \interaction{template.simple.keywords}
+  \caption{Template keywords in use}
+  \label{fig:template:keywords}
+\end{figure}
+
+Como mencionamos anteriormente, la palabra clave de fecha no produce
+salida legible por un humano, debemos tratarla de forma especial.
+Esto involucra usar un \emph{filtro}, acerca de lo cual hay más en la
+sección~\ref{sec:template:filter}.
+
+\interaction{template.simple.datekeyword}
+
+\section{Secuencias de Control}
+\label{sec:template:escape}
+
+El motor de plantillas de Mercurial reconoce las secuencias de control
+más comunmente usadas dentro de las cadenas.  Cuando ve un backslash
+(``\Verb+\+''), ve el caracter siguiente y sustituye los dos
+caracteres con un reemplazo sencillo, como se describe a continuación:
+
+\begin{itemize}
+\item[\Verb+\textbackslash\textbackslash+] Backslash, ``\Verb+\+'',
+  ASCII~134.
+\item[\Verb+\textbackslash n+] Nueva línea, ASCII~12.
+\item[\Verb+\textbackslash r+] Cambio de línea, ASCII~15.
+\item[\Verb+\textbackslash t+] Tab, ASCII~11.
+\item[\Verb+\textbackslash v+] Tab Vertical, ASCII~13.
+\item[\Verb+\textbackslash \{+] Corchete abierto, ``\Verb+{+'', ASCII~173.
+\item[\Verb+\textbackslash \}+] Corchete cerrado, ``\Verb+}+'', ASCII~175.
+\end{itemize}
+
+Como se indicó arriba, si desea que la expansión en una plantilla
+contenga un caracter literal ``\Verb+\+'', ``\Verb+{+'', o
+  ``\Verb+{+'', debe escaparlo.
+
+\section{Uso de filtros con palabras claves}
+\label{sec:template:filter}
+
+Algunos de los resultados de la expansión de la plantilla no son
+fáciles de usar de inmediato.  Mercurial le permite especificar una
+cadena de \emph{filtros} opcionales para modificar el resultado de
+expandir una palabra clave.  Ya ha visto el filtro usual
+\tplkwfilt{date}{isodate} en acción con anterioridad para hacer
+legible la fecha.
+
+A continuación hay una lista de los filtros de Mercurial más
+comunmente usados.  Ciertos filtros pueden aplicarse a cualquier
+texto, otros pueden usarse únicamente en circunstancias específicas.
+El nombre de cada filtro está seguido de la indicación de dónde puede
+ser usado y una descripción de su efecto.
+
+\begin{itemize}
+\item[\tplfilter{addbreaks}] Cualquier texto. Añade una etiqueta XHTML
+  ``\Verb+<br/>+'' antes del final de cada línea excepto en la final.
+  Por ejemplo, ``\Verb+foo\nbar+'' se convierte en ``\Verb+foo<br/>\nbar+''.
+\item[\tplkwfilt{date}{age}] palabra clave \tplkword{date}.  Muestra
+  la edad de la fecha, relativa al tiempo actual. Ofrece una cadena como
+  ``\Verb+10 minutes+''.
+\item[\tplfilter{basename}] Cualquier texto, pero de utilidad sobre
+  todo en palabras claves relativas a \tplkword{ficheros}.  Trata el
+  texto como una ruta, retornando el nombre base.  Por ejemplo,
+  ``\Verb+foo/bar/baz+'', se convierte en ``\Verb+baz+''.
+\item[\tplkwfilt{date}{date}] \tplkword{date} palabra clave.  Mostrar
+  la fecha en un formato similar a la orden \tplkword{date} de 
+  in a similar format to the Unix, pero con la zona horaria incluída.
+  Una cadena como ``\Verb+Mon Sep 04 15:13:13 2006 -0700+''.
+\item[\tplkwfilt{author}{domain}] Cualquier texto, pero de mayor
+  utilidad para la palabra clave \tplkword{author}.  Encuentra la
+  primera cadena que luce como una dirección de correo electrónico, y
+  extrae solamente el componente del dominio.  Por ejemplo, de 
+  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' se extrae
+  ``\Verb+serpentine.com+''.
+\item[\tplkwfilt{author}{email}] Cualquier texto, pero de mayor
+  utilidad para la palabra clave \tplkword{author}.  Extrae la primera
+  cadena que luce como una dirección de correo. Por ejemplo, de
+  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' extrae 
+  ``\Verb+bos@serpentine.com+''.
+\item[\tplfilter{escape}] Cualquier texto.  Reemplaza los caracteres
+  especiales de XML/XHTML: ``\Verb+&+'', ``\Verb+<+'' y ``\Verb+>+''
+  con las entidades XML.
+\item[\tplfilter{fill68}] Cualquier texto. Lograr que el texto ocupe
+  las primeras 68 columnas.  Es útil emplearlo antes de pasar el texto
+  por el filtro \tplfilter{tabindent}, y queremos que aún quepa en una
+  ventana de fuente fija y 80 columnas.
+\item[\tplfilter{fill76}] Cualquier texto.  Lograr que el texto quepa
+  en 76 columnas.
+\item[\tplfilter{firstline}] Cualquier texto.  Mostrar la primera
+  línea de texto sin saltos de línea.
+\item[\tplkwfilt{date}{hgdate}] \tplkword{date} palabra clave.
+  Mostrar la fecha como un par de números legibles.  Muestra una
+  cadena como ``\Verb+1157407993 25200+''.
+\item[\tplkwfilt{date}{isodate}] \tplkword{date} palabra clave.
+  Mostrar la fecha como una cadena de texto en el formato.  Muestra
+  una cadena como ``\Verb+2006-09-04 15:13:13 -0700+''.
+\item[\tplfilter{obfuscate}] Cualquier texto, pero de mayor utilidad
+  para la palabra clave \tplkword{author}.  Muestra el campo de texto
+  como una secuencia de entidades XML.  Esto ayuda a eliminar ciertos
+  robots estúpidos de adquisición de correo.
+\item[\tplkwfilt{author}{person}] Cualquier texto, útil sobre todo
+  para la palabra clave \tplkword{author}.  Muestra el texto que hay
+  antes de la dirección de correo electrónico.  Por ejemplo,
+  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' mostraría
+  ``\Verb+Bryan O'Sullivan+''.
+\item[\tplkwfilt{date}{rfc822date}] \tplkword{date} palabra clave.
+  Muestra una fecha con el mismo formato que se usa en los encabezados
+  de correo.  Mostraría una cadena como
+ ``\Verb+Mon, 04 Sep 2006 15:13:13 -0700+''.
+\item[\tplkwfilt{node}{short}] Hash del conjunto de cambios.  Muestra
+  la forma corta de un hash de conjunto de cambios, 
+  of a changeset hash, p.e.~una cadena hexadecimal de 12 bytes.
+\item[\tplkwfilt{date}{shortdate}] \tplkword{date} palabra clave.
+  Mostrar año, mes y día de una fecha.  Muestrauna cadena como
+  ``\Verb+2006-09-04+''.
+\item[\tplfilter{strip}] Cualquier texto.  Elimina todos los espacios
+  en blanco al principio y al final de la cadena.
+\item[\tplfilter{tabindent}] Cualquier texto.  Muestra el texto con
+  todas las líneas excepto la primera que comience con el caracter tab.
+\item[\tplfilter{urlescape}] Cualquier texto.  Escapa todos los
+  caracteres que se consideren como ``especiales'' por los parsers de
+  URL.  Por ejemplo, \Verb+foo bar+ se convierte en \Verb+foo%20bar+.
+\item[\tplkwfilt{author}{user}] Cualquier texto, útil sobre todo para
+  la palabra clave \tplkword{author}.  Retorna el ``usuario'' de una
+  dirección de correo.  Por ejemplo, 
+  ``\Verb+Bryan O'Sullivan <bos@serpentine.com>+'' se convierte en 
+  ``\Verb+bos+''.
+\end{itemize}
+
+\begin{figure}
+  \interaction{template.simple.manyfilters}
+  \caption{Filtros de plantilla en acción}
+  \label{fig:template:filters}
+\end{figure}
+
+\begin{note}
+  Si trata de aplicar un filtro a una porción de datos que no puede
+  procesarse, Mercurial fallará e imprimirá una excepción de Python.
+  Por ejemplo, el tratar de usar la salida de la palabra clave
+  \tplkword{desc} con el filtro \tplkwfilt{date}{isodate} no resultará
+  algo útil.
+\end{note}
+
+\subsection{Combinar filtros}
+
+Combinar filtros es para generar una salida en la forma como usted lo
+desea es muy sencillo.  La cadena de filtros siguientes arman una
+descripción, después aseguran que cabe limpiamente en 68 columnas, y
+las indenta con 8~caracteres (por lo menos en sistemas tipo Unix, en
+los que el tab por convención se extiende en 8~caracteres).
+
+\interaction{template.simple.combine}
+
+Observe el uso de ``\Verb+\t+'' (un caracter tab) en la plantilla para
+forzar que la primera línea se indente; esto es necesario para lograr
+que la primera línea luzca indentada;  es necesario debido a que
+\tplkword{tabindent} indenta todas las líneas \emph{excepto} la primera.
+
+Tenga en cuenta que el orden de los filtros importa.  El primer filtro
+se aplica primero al resultado de la palabra clave; el segundo al
+resultado de la aplicación del primer filtro y así sucesivamente.  Por
+ejemplo, usar \Verb+fill68|tabindent+ es muy distinto al resultado de
+usar \Verb+tabindent|fill68+.
+
+
+\section{De plantillas a estilos}
+
+Una plantilla provee una forma rápida y sencilla para dar formato a
+una salida.  Las plantillas pueden volvers verbosas, y es útil poder
+darle un nombre a una plantilla.  Un fichero de estilo es una
+plantilla con un nombre, almacenado en un fichero.
+
+Más aún, al usar un fichero de estilo se dispara el poder del motor de
+plantillas en un nivel imposible de alcanzar usando las opción
+\hgopt{log}{--template} desde la línea de órdenes.
+
+
+\subsection{Los ficheros de estilo más sencillos}
+
+Nuestro fichero sencillo de estilo contiene una sola línea:
+
+\interaction{template.simple.rev}
+
+Se le indica a Mercurial, ``si está imprimiendo un conjunto de
+cambios, use el texto de la derecha como la plantilla''.
+
+\subsection{Sintaxis de ficheros de estilo}
+
+Las reglas de sintaxis para un fichero de estilo son sencillas:
+
+\begin{itemize}
+\item El fichero se procesa línea por línea.
+
+\item Se ignoran el espacio en blanco circundante.
+
+\item Se omiten las líneas en blanco.
+
+\item Si una línea comienza con los caracteres ``\texttt{\#}'' o
+  ``\texttt{;}'', la línea completa se trata como un comentario, y se
+  omite como si fuera vacía.
+
+\item Una línea comienza con una palabra clave.  Esta debe comenzar
+  con una caracter alfabético o una raya al piso, y puede contener
+  subsecuentemente cualquier caracter alfanumérico o una raya al
+  piso.  (En notación de expresiones regulares debe coincidir con
+  \Verb+[A-Za-z_][A-Za-z0-9_]*+.)
+
+\item El próximo elemento debe ser un caracter ``\texttt{=}'', que
+  puede estar precedido o seguido por una cantidad arbitraria de
+  espacio.
+
+\item Si el resto de la línea comienza y termina con caracteres
+  encerrados entre caracteres de comillas (bien sea sencillas o
+  dobles),  se trata como cuerpo de la plantilla.
+
+\item Si el resto de la línea \emph{no} comienza con una comilla, se
+  trata como el nombre de un fichero; los contenidos de este fichero
+  se leerán y se usarán como cuerpo de la plantilla.
+\end{itemize}
+
+\section{Ejemplos de ficheros de estilos}
+
+Para ilustrar la creación de un fichero de estilo, construiremos
+algunos ejemplos.  En lugar de ofrecer un fichero completo de estilo y
+analizarlo, replicaremos el proceso usual de desarrollo de un fichero
+de estilo comenzando con algo muy sencillo, y avanzando por una serie
+de ejemplos sucesivos más completos.
+
+\subsection{Identificar equivocaciones en ficheros de estilo}
+
+Si Mercurial encuentra un problema en un fichero de estilo en el cual
+usted está trabajando, imprime un mensaje de error suscinto, cuando
+usted identifique lo que significa, resulta muy útil.
+
+\interaction{template.svnstyle.syntax.input}
+
+Tenga en cuenta que \filename{broken.style} trata de definir la
+palabra clave \texttt{changeset}, pero omite dar un contenido para esta.
+Cuando se le indica a Mercurial que use este fichero de estilo, se
+queja inmediatamente.
+
+\interaction{template.svnstyle.syntax.error}
+
+Este mensaje de error luce intimidante, pero no es muy difícil de
+seguir:
+
+\begin{itemize}
+\item El primer componente es la forma como Mercurial dice ``me rindo''.
+  \begin{codesample4}
+    \textbf{abort:} broken.style:1: parse error
+  \end{codesample4}
+
+\item A continuación viene el nombre del fichero que contiene el error.
+  \begin{codesample4}
+    abort: \textbf{broken.style}:1: parse error
+  \end{codesample4}
+
+\item Siguendo el nombre del fichero viene el número de línea en la
+  que se encontró el error.
+  \begin{codesample4}
+    abort: broken.style:\textbf{1}: parse error
+  \end{codesample4}
+
+\item Finalmente, la descripción de lo que falló.
+  \begin{codesample4}
+    abort: broken.style:1: \textbf{parse error}
+  \end{codesample4}
+  La descripción del problema no siempre es clara (como en este caso),
+  pero aunque sea críptica, casi siempre es trivial la inspección
+  visual de la línea en el fichero de estilo y encontrar lo que está
+  mal.
+\end{itemize}
+
+\subsection{Identificar de forma única un repositorio}
+
+Si desea identificar un repositorio de Mercurial ``de forma única''
+con una cadena corta como identificador, puede usar la primera
+revisión en el repositorio.
+\interaction{template.svnstyle.id} 
+No es garantía de unicidad, pero no es útill en ciertos casos:
+many cases.
+\begin{itemize}
+\item No funcionará en un repositorio completamente vacío, porque un
+  repositorio así no tiene una revisión~zero.
+\item Tampoco funcionará en caso (muy raro) cuando el repositorio sea
+  una fusión de dos repositorios independientes y tiene los dos
+  directorios por ahí.
+\end{itemize}
+Hay ciertos casos en los cuales podría colocar el identificador:
+\begin{itemize}
+\item Como una llave en la tabla de una base de datos que administra
+  repositorios en un servidor.
+\item Como una parte del par \{\emph{ID~repositorio}, \emph{ID~revisión}\}.
+  Almacene esta información de forma independiente cuando ejecute
+  construcciones automatizadas u otras actividades, de forma que pueda
+  ``reconstruir'' posteriormente en caso de ser necesario.
+\end{itemize}
+
+\subsection{Mostrando salida parecida a Subversion}
+
+Intentemos emular la salida usual que usa otro sistema de control de
+revisiones,  Subversion.
+\interaction{template.svnstyle.short}
+
+Dado que la salida de Subversion es sencilla, es fácil copiar y pegar
+una porción de su salida en un fichero, y reemplazar el texto
+producido previamente por Subversion con valores base que quisiéramos
+ver expandidos.
+\interaction{template.svnstyle.template}
+
+Esta plantilla difiere en algunos detalles de la salida producida por
+Subversion:
+\begin{itemize}
+\item Subversion imprime una fecha ``legible'' (el ``\texttt{Wed, 27 Sep
+    2006}'' en el ejemplo de salida anterior) en paréntesis.  El motor
+  de plantillas de Mercurial no ofrece una forma sencilla de desplegar
+  una fecha en este formato sin imprimir también la hora y la zona horaria.
+\item Emulamos las líneas de ``separación'' de subversion con caracteres
+  ``\texttt{-}'' en una línea.  Usamos la palabra clave
+  \tplkword{header} del motor de plantillas para imprimir una línea de
+  separación como la primera línea de salida (ver más abajo), para
+  lograr una salida similara a la de Subversion.
+\item La salida de subversion incluye un conteo en el encabezado del
+  número de líneas en el mensaje de consinación.  No podemos
+  replicarlo en Mercurial; el motor de plantilla no ofrece en la
+  actualidad un filtro que cuente la cantidad de objetos que se le
+  pasen.
+\end{itemize}
+No me tomó más de un minuto o dos de trabajo para reemplazar texto
+literal de un ejemplo de salida de la salida de Subversion con ciertas
+palabras claves y filtros para ofrecer la plantilla anterior.  El
+fichero de estilo se refiere sencillamente a la plantilla.
+\interaction{template.svnstyle.style}
+
+Podríamos haber incluído el texto del fichero plantilla directamente
+en el fichero de estilo encerrando entre comillas y reemplazando las
+nuevas líneas con secuencias ``\verb!\n!'', pero haría muy difícil de
+leer el fichero de estilos.  La facilidad para leer es importante
+cuando está decidiendo si un texto pertenece a un fichero de estilo o
+a un fichero de plantilla incluído en el estilo.  Si el fichero de
+estilo luce muy grande o complicado, si inserta una pieza de texto
+literal, mejor colóquelo en una plantilla.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-basic.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,690 @@
+\chapter{Una gira de Mercurial: lo básico}
+\label{chap:tour-basic}
+
+\section{Instalar Mercurial en su sistema}
+\label{sec:tour:install}
+Hay paquetes binarios precompilados de Mercurial disponibles para cada
+sistema operativo popular. Esto hace fácil empezar a usar Mercurial
+en su computador inmediatamente.
+
+\subsection{Linux}
+
+Dado que cada distribución de Linux tiene sus propias herramientas de
+manejo de paquetes, políticas, y ritmos de desarrollo, es difícil dar
+un conjunto exhaustivo de instrucciones sobre cómo instalar el paquete
+de Mercurial. La versión de Mercurial que usted tenga a disposición
+puede variar dependiendo de qué tan activa sea la persona que mantiene
+el paquete para su distribución.
+
+Para mantener las cosas simples, me enfocaré en instalar Mercurial
+desde la línea de comandos en las distribuciones de Linux más
+populares. La mayoría de estas distribuciones proveen administradores
+de paquetes gráficos que le permitirán instalar Mercurial con un solo
+clic; el nombre de paquete a buscar es \texttt{mercurial}.
+
+\begin{itemize}
+\item[Debian]
+  \begin{codesample4}
+    apt-get install mercurial
+  \end{codesample4}
+
+\item[Fedora Core]
+  \begin{codesample4}
+    yum install mercurial
+  \end{codesample4}
+
+\item[Gentoo]
+  \begin{codesample4}
+    emerge mercurial
+  \end{codesample4}
+
+\item[OpenSUSE]
+  \begin{codesample4}
+    yum install mercurial
+  \end{codesample4}
+
+\item[Ubuntu] El paquete de Mercurial de Ubuntu está basado en el de
+    Debian. Para instalarlo, ejecute el siguiente comando.
+  \begin{codesample4}
+    apt-get install mercurial
+  \end{codesample4}
+  El paquete de Mercurial para Ubuntu tiende a atrasarse con respecto
+  a la versión de Debian por un margen de tiempo considerable
+  (al momento de escribir esto, 7 meses), lo que en algunos casos
+  significará que usted puede encontrarse con problemas que ya habrán
+  sido resueltos en el paquete de Debian.
+\end{itemize}
+
+\subsection{Solaris}
+
+SunFreeWare, en \url{http://www.sunfreeware.com}, es una buena fuente
+para un gran número de paquetes compilados para Solaris para las
+arquitecturas Intel y Sparc de 32 y 64 bits, incluyendo versiones
+actuales de Mercurial.
+
+\subsection{Mac OS X}
+
+Lee Cantey publica un instalador de Mercurial para Mac OS~X en 
+\url{http://mercurial.berkwood.com}.  Este paquete funciona en tanto
+en Macs basados en Intel como basados en PowerPC. Antes de que pueda
+usarlo, usted debe instalar una versión compatible de Universal
+MacPython~\cite{web:macpython}. Esto es fácil de hacer; simplemente
+siga las instrucciones del sitio de Lee.
+
+También es posible instalar Mercurial usando Fink o MacPorts, dos
+administradores de paquetes gratuitos y populares para Mac OS X. Si
+usted tiene Fink, use \command{sudo apt-get install mercurial-py25}.
+Si usa MacPorts, \command{sudo port install mercurial}.
+
+\subsection{Windows}
+
+Lee Cantey publica un instalador de Mercurial para Windows en
+\url{http://mercurial.berkwood.com}. Este paquete no tiene
+% TODO traducción de it just works. Agreed?
+dependencias externas; ``simplemente funciona''.
+
+\begin{note}
+    La versión de Windows de Mercurial no convierte automáticamente
+    los fines de línea entre estilos Windows y Unix. Si usted desea
+    compartir trabajo con usuarios de Unix, deberá hacer un trabajo
+    adicional de configuración. XXX Terminar esto.
+\end{note}
+
+\section{Arrancando}
+
+Para empezar, usaremos el comando \hgcmd{version} para revisar si
+Mercurial está instalado adecuadamente. La información de la versión
+que es impresa no es tan importante; lo que nos importa es si imprime
+algo en absoluto.
+
+\interaction{tour.version}
+
+% TODO builtin-> integrado?
+\subsection{Ayuda integrada}
+
+Mercurial provee un sistema de ayuda integrada. Esto es invaluable
+para ésas ocasiones en la que usted está atorado tratando de recordar
+cómo ejecutar un comando. Si está completamente atorado, simplemente
+ejecute \hgcmd{help}; esto imprimirá una breve lista de comandos,
+junto con una descripción de qué hace cada uno. Si usted solicita
+ayuda sobre un comando específico (como abajo), se imprime información
+más detallada.
+\interaction{tour.help}
+Para un nivel más impresionante de detalle (que usted no va a
+necesitar usualmente) ejecute \hgcmdargs{help}{\hggopt{-v}}. La opción
+\hggopt{-v} es la abreviación para \hggopt{--verbose}, y le indica a
+Mercurial que imprima más información de lo que haría usualmente.
+
+\section{Trabajar con un repositorio}
+
+En Mercurial, todo sucede dentro de un \emph{repositorio}. El
+repositorio para un proyecto contiene todos los ficheros que
+``pertenecen a'' ése proyecto, junto con un registro histórico de los
+ficheros de ese proyecto.
+
+No hay nada particularmente mágico acerca de un repositorio; es
+simplemente un árbol de directorios en su sistema de ficheros que
+Mercurial trata como especial. Usted puede renombrar o borrar un
+repositorio en el momento que lo desee, usando bien sea la línea de
+comandos o su explorador de ficheros.
+
+\subsection{Hacer una copia local de un repositorio}
+
+\emph{Copiar} un repositorio es sólo ligeramente especial. Aunque
+usted podría usar un programa normal de copia de ficheros para hacer
+una copia del repositorio, es mejor usar el comando integrado que
+Mercurial ofrece. Este comando se llama \hgcmd{clone}\ndt{Del término
+``clonar'' en inglés.}, porque crea una copia idéntica de un
+repositorio existente.
+\interaction{tour.clone}
+Si nuestro clonado tiene éxito, deberíamos tener un directorio local
+llamado \dirname{hello}. Este directorio contendrá algunos ficheros.
+\interaction{tour.ls}
+Estos ficheros tienen el mismo contenido e historial en nuestro
+repositorio y en el repositorio que clonamos.
+
+Cada repositorio Mercurial está completo, es autocontenido e
+independiente. Contiene su propia copia de los ficheros y el historial
+de un proyecto. Un repositorio clonado recuerda la ubicación de la que
+fue clonado, pero no se comunica con ese repositorio, ni con ningún
+otro, a menos que usted le indique que lo haga.
+
+Lo que esto significa por ahora es que somos libres de experimentar
+con nuestro repositorio, con la tranquilidad de saber que es una
+% TODO figure out what to say instead of sandbox
+``caja de arena'' privada que no afectará a nadie más.
+
+\subsection{Qué hay en un repositorio?}
+
+Cuando miramos en detalle dentro de un repositorio, podemos ver que
+contiene un directorio llamado \dirname{.hg}. Aquí es donde Mercurial
+mantiene todos los metadatos del repositorio.
+\interaction{tour.ls-a}
+
+Los contenidos del directorio \dirname{.hg} y sus subdirectorios son
+exclusivos de Mercurial. Usted es libre de hacer lo que desee con
+cualquier otro fichero o directorio en el repositorio.
+
+Para introducir algo de terminología, el directorio \dirname{.hg} es
+el repositorio ``real'', y todos los ficheros y directorios que
+coexisten con él están en el \emph{directorio de trabajo}. Una forma
+sencilla de recordar esta distinción es que el \emph{repositorio}
+contiene el \emph{historial} de su proyecto, mientras que el
+\emph{directorio de trabajo} contiene una \emph{instantánea} de su
+proyecto en un punto particular del historial.
+
+\section{Vistazo rápido al historial}
+
+Una de las primeras cosas que se desea hacer con un repositorio nuevo,
+poco conocido, es conocer su historial. El comando \hgcmd{log} nos
+permite ver el mismo.
+\interaction{tour.log}
+Por defecto este programa imprime un párrafo breve por cada cambio al
+proyecto que haya sido grabado. Dentro de la terminología de
+Mercurial, cada uno de estos eventos es llamado \emph{conjunto de
+cambios}, porque pueden contener un registro de cambios a varios
+ficheros.
+
+Los campos de la salida de \hgcmd{log} son los siguientes.
+\begin{itemize}
+    \item[\texttt{changeset}]\hspace{-0.5em}\ndt{Conjunto de cambios.} Este campo
+        tiene un número, seguido por un
+        % TODO digo mejor seguido por un dos puntos ? string =>
+        % cadena?
+        \texttt{:}, seguido por una cadena hexadecimal. Ambos son
+        \emph{identificadores} para el conjunto de cambios. Hay dos
+        identificadores porque el número es más corto y más fácil de
+        recordar que la cadena hexadecimal.
+        
+\item[\texttt{user}]\hspace{-0.5em}\ndt{Usuario.} La identidad de la
+    persona que creó el conjunto de cambios. Este es un campo en el
+    que se puede almacenar cualquier valor, pero en la mayoría de los
+    casos contiene el nombre de una persona y su dirección de correo
+    electrónico.
+    
+\item[\texttt{date}]\hspace{-0.5em}\ndt{Fecha.} La fecha y hora en la
+    que el conjunto de cambios fue creado, y la zona horaria en la que
+    fue creado. (La fecha y hora son locales a dicha zona horaria;
+    ambos muestran la fecha y hora para la persona que creó el
+    conjunto de cambios).
+    
+\item[\texttt{summary}]\hspace{-0.5em}\ndt{Sumario.} 
+    La primera línea del texto que usó la persona que creó el conjunto
+    de cambios para describir el mismo.
+\end{itemize}
+El texto impreso por \hgcmd{log} es sólo un sumario; omite una gran
+cantidad de detalles.
+
+La figura~\ref{fig:tour-basic:history} es una representación
+gráfica del historial del repositorio \dirname{hello}, para hacer más
+fácil ver en qué dirección está ``fluyendo'' el historial. Volveremos
+a esto varias veces en este capítulo y en los siguientes.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-history}
+  \caption{Historial gráfico del repositorio \dirname{hello}}
+  \label{fig:tour-basic:history}
+\end{figure}
+
+\subsection{Conjuntos de cambios, revisiones, y comunicándose con
+otras personas}
+
+%TODO sloppy => desordenado ?  TODO hablar del inglés? o de español?
+Ya que el inglés es un lenguaje notablemente desordenado, y el área de
+ciencias de la computación tiene una notable historia de confusión de
+% TODO insertar ? al revés. no sé cómo en un teclado de estos.
+términos (porqué usar sólo un término cuando cuatro pueden servir?),
+el control de revisiones tiene una variedad de frases y palabras que
+tienen el mismo significado. Si usted habla acerca del historial de
+Mercurial con alguien, encontrará que la expresión ``conjunto de
+cambios'' es abreviada a menudo como ``cambio'' o (por escrito)
+``cset''\ndt{Abreviatura para la expresión ``changeset'' en inglés.},
+y algunas veces un se hace referencia a un conjunto de cambios como
+una ``revisión'' o ``rev''\ndt{De nuevo, como abreviación para el
+término en inglés para ``revisión'' (``revision'').}.
+
+Si bien no es relevante qué \emph{palabra} use usted para referirse al
+concepto ``conjunto de cambios'', el \emph{identificador} que usted
+use para referise a ``un \emph{conjunto de cambios} particular'' es
+muy importante. Recuerde que el campo \texttt{changeset} en la salida
+de \hgcmd{log} identifica un conjunto de cambios usando tanto un
+número como una cadena hexadecimal.
+
+\begin{itemize}
+    \item El número de revisión \emph{sólo es válido dentro del
+        repositorio}.
+    \item Por otro lado, la cadena hexadecimal es el
+        \emph{identificador permanente e inmutable} que siempre
+        identificará ése conjunto de cambios en \emph{todas} las
+        copias del repositorio.
+\end{itemize}
+La diferencia es importante. Si usted le envía a alguien un correo
+electrónico hablando acerca de la ``revisión~33'', hay una
+probabilidad alta de que la revisión~33 de esa persona \emph{no sea la
+misma suya}. Esto sucede porque el número de revisión depende del
+orden en que llegan los cambios al repositorio, y no hay ninguna
+garantía de que los mismos cambios llegarán en el mismo orden en
+diferentes repositorios. Tres cambios dados $a,b,c$ pueden aparecer en
+un repositorio como $0,1,2$, mientras que en otro aparecen como
+$1,0,2$.
+
+Mercurial usa los números de revisión simplemente como una abreviación
+conveniente. Si usted necesita hablar con alguien acerca de un
+conjunto de cambios, o llevar el registro de un conjunto de cambios
+por alguna otra razón (por ejemplo, en un reporte de fallo), use el
+identificador hexadecimal.
+
+\subsection{Ver revisiones específicas}
+
+Para reducir la salida de \hgcmd{log} a una sola revisión, use la  
+opción \hgopt{log}{-r} (o \hgopt{log}{--rev}).  Puede usar un número
+de revisión o un identificador hexadecimal de conjunto de cambios, y
+puede pasar tantas revisiones como desee.
+
+\interaction{tour.log-r}
+
+Si desea ver el historial de varias revisiones sin tener que mencionar
+cada una de ellas, puede usar la \emph{notación de rango}; esto le
+permite expresar el concepto ``quiero ver todas las revisiones entre
+$a$ y $b$, inclusive''.
+\interaction{tour.log.range}
+Mercurial también respeta el orden en que usted especifica las
+revisiones, así que \hgcmdargs{log}{-r 2:4} muestra $2,3,4$ mientras
+que \hgcmdargs{log}{-r 4:2} muestra $4,3,2$.
+
+\subsection{Información más detallada}
+Aunque la información presentada por \hgcmd{log} es útil si usted sabe
+de antemano qué está buscando, puede que necesite ver una descripción
+completa del cambio, o una lista de los ficheros que cambiaron, si
+está tratando de averiguar si un conjunto de cambios dado es el que
+usted está buscando. La opción \hggopt{-v} (or \hggopt{--verbose}) del
+comando \hgcmd{log} le da este nivel extra de detalle.
+\interaction{tour.log-v}
+
+Si desea ver tanto la descripción como el contenido de un cambio,
+añada la opción \hgopt{log}{-p} (o \hgopt{log}{--patch}). Esto muestra
+% TODO qué hacemos con diff unificado? convervarlo, por ser la
+% acepción usual?
+el contenido de un cambio como un \emph{diff unificado} (si usted
+nunca ha visto un diff unificado antes, vea la
+sección~\ref{sec:mq:patch} para un vistazo global).
+\interaction{tour.log-vp}
+
+\section{Todo acerca de las opciones para comandos}
+
+Tomemos un breve descanso de la tarea de explorar los comandos de
+Mercurial para hablar de un patrón en la manera en que trabajan; será
+útil tener esto en mente a medida que avanza nuestra gira.
+
+Mercurial tiene un enfoque directo y consistente en el manejo de las
+opciones que usted le puede pasar a los comandos. Se siguen las
+convenciones para opciones que son comunes en sistemas Linux y Unix
+modernos.
+\begin{itemize}
+\item Cada opción tiene un nombre largo. Por ejemplo, el comando
+    \hgcmd{log} acepta la opción \hgopt{log}{--rev}, como ya hemos
+    visto.
+\item Muchas opciones tienen también un nombre corto. En vez de
+    \hgopt{log}{--rev}, podemos usar \hgopt{log}{-r}.  (El motivo para
+    que algunas opciones no tengan nombres cortos es que dichas
+    opciones se usan rara vez.)
+\item Las opciones largas empiezan con dos guiones (p.ej.~\hgopt{log}{--rev}),
+    mientras que las opciones cortas empiezan con uno (e.g.~\hgopt{log}{-r}).
+\item El nombre  y uso de las opciones es consistente en todos los
+    comandos. Por ejemplo, cada comando que le permite pasar un ID de
+    conjunto de cambios o un número de revisión acepta tanto la opción
+    \hgopt{log}{-r} como la \hgopt{log}{--rev}.
+\end{itemize}
+En los ejemplos en este libro, uso las opciones cortas en vez de las
+largas. Esto sólo muestra mis preferencias, así que no le dé
+significado especial a eso.
+
+Muchos de los comandos que generan salida de algún tipo mostrarán más
+salida cuando se les pase la opción \hggopt{-v} (o
+\hggopt{--verbose}\ndt{Prolijo.}), y menos cuando se les pase la opción \hggopt{-q}
+(o \hggopt{--quiet}\ndt{Silencioso.}).
+
+\section{Hacer y repasar cambios}
+
+Ahora que tenemos una comprensión adecuada sobre cómo revisar el
+historial en Mercurial, hagamos algunos cambios y veamos cómo
+examinarlos.
+
+Lo primero que haremos será aislar nuestro experimento en un
+repositorio propio. Usaremos el comando \hgcmd{clone}, pero no hace
+falta clonar una copia del repositorio remoto. Como ya contamos con
+una copia local del mismo, podemos clonar esa. Esto es mucho más
+rápido que clonar a través de la red, y en la mayoría de los casos
+clonar un repositorio local usa menos espacio en disco también.
+\interaction{tour.reclone}
+A manera de recomendación, es considerado buena práctica mantener una
+copia ``prístina'' de un repositorio remoto a mano, del cual usted
+puede hacer clones temporales para crear cajas de arena para cada
+tarea en la que desee trabajar. Esto le permite trabajar en múltiples
+tareas en paralelo, teniendo cada una de ellas aislada de las otras
+hasta que estén completas y usted esté listo para integrar los cambios
+de vuelta. Como los clones locales son tan baratos, clonar y destruir
+repositorios no consume demasiados recursos, lo que facilita hacerlo
+en cualquier momento.
+
+En nuestro repositorio \dirname{my-hello}, hay un fichero
+\filename{hello.c} que contiene el clásico programa ``hello,
+world''\ndt{Hola, mundo.}. Usaremos el clásico y venerado comando
+\command{sed} para editar este fichero y hacer que imprima una segunda
+línea de salida. (Estoy usando el comando \command{sed} para hacer
+esto sólo porque es fácil escribir un ejemplo automatizado con él.
+Dado que usted no tiene esta restricción, probablemente no querrá usar
+\command{sed}; use su editor de texto preferido para hacer lo mismo).
+\interaction{tour.sed}
+
+El comando \hgcmd{status} de Mercurial nos dice lo que Mercurial sabe
+acerca de los ficheros en el repositorio.
+\interaction{tour.status}
+El comando \hgcmd{status} no imprime nada para algunos ficheros, sólo
+una línea empezando con ``\texttt{M}'' para el fichero
+\filename{hello.c}. A menos que usted lo indique explícitamente,
+\hgcmd{status} no imprimirá nada respecto a los ficheros que no han
+sido modificados.
+
+La ``\texttt{M}'' indica que Mercurial se dio cuenta de que nosotros
+modificamos \filename{hello.c}.  No tuvimos que \emph{decirle} a
+Mercurial que íbamos a modificar ese fichero antes de hacerlo, o que
+lo modificamos una vez terminamos de hacerlo; él fue capaz de darse
+cuenta de esto por sí mismo.
+
+Es algo útil saber que hemos modificado el fichero \filename{hello.c},
+pero preferiríamos saber exactamente \emph{qué} cambios hicimos.
+Para averiguar esto, usamos el comando \hgcmd{diff}.
+\interaction{tour.diff}
+
+\section{Grabar cambios en un nuevo conjunto de cambios}
+
+Podemos modificar, compilar y probar nuestros cambios, y usar
+\hgcmd{status} y \hgcmd{diff} para revisar los mismos, hasta que
+estemos satisfechos con los resultados y lleguemos a un momento en el
+que sea natural que querramos guardar nuestro trabajo en un nuevo
+conjunto de cambios.
+
+El comando \hgcmd{commit} nos permite crear un nuevo conjunto de
+cambios. Nos referiremos usualmente a esto como ``hacer una consigna''
+o consignar.
+
+\subsection{Definir un nombre de usuario}
+
+Cuando usted trata de ejecutar \hgcmd{commit}\ndt{Hacer una
+consignación} por primera vez, no está garantizado que lo logre.
+Mercurial registra su nombre y dirección en cada cambio que usted
+consigna, para que más adelante otros puedan saber quién es el
+responsable de cada cambio. Mercurial trata de encontrar un nombre de
+% TODO consigna o consignación?
+usuario adecuado con el cual registrar la consignación. Se intenta con
+cada uno de los siguientes métodos, en el orden presentado.
+\begin{enumerate}
+\item Si usted pasa la opción \hgopt{commit}{-u} al comando \hgcmd{commit}
+  en la línea de comandos, seguido de un nombre de usuario, se le da a
+  esto la máxima precedencia.
+\item A continuación se revisa si usted ha definido la variable de
+    entorno \envar{HGUSER}.
+\item Si usted crea un fichero en su directorio personal llamado
+  \sfilename{.hgrc}, con una entrada \rcitem{ui}{username}, se usa
+  luego. Para revisar cómo debe verse este fichero, refiérase a la
+  sección~\ref{sec:tour-basic:username} más abajo.
+\item Si usted ha definido la variable de entorno \envar{EMAIL}, será
+    usada a continuación.
+\item Mercurial le pedirá a su sistema buscar su nombre de usuario
+    % TODO host => máquina
+    local, y el nombre de máquina, y construirá un nombre de usuario a
+    partir de estos componentes. Ya que esto generalmente termina
+    generando un nombre de usuario no muy útil, se imprimirá una
+    advertencia si es necesario hacerlo.
+\end{enumerate}
+Si todos estos procedimientos fallan, Mercurial fallará, e imprimirá
+un mensaje de error. En este caso, no le permitirá hacer la
+consignación hasta que usted defina un nombre de usuario.
+
+Trate de ver la variable de entorno \envar{HGUSER} y la opción
+\hgopt{commit}{-u} del comando \hgcmd{commit} como formas de
+\emph{hacer caso omiso} de la selección de nombre de usuario que
+Mercurial hace normalmente.  Para uso normal, la manera más simple y
+sencilla de definir un nombre de usuario para usted es crear un
+fichero \sfilename{.hgrc}; los detalles se encuentran más adelante.
+
+\subsubsection{Crear el fichero de configuración de Mercurial}
+\label{sec:tour-basic:username}
+
+Para definir un nombre de usuario, use su editor de texto favorito
+para crear un fichero llamado \sfilename{.hgrc} en su directorio
+personal. Mercurial usará este fichero para obtener las
+configuraciones personalizadas que usted haya hecho. El contenido
+inicial de su fichero \sfilename{.hgrc} debería verse así.
+\begin{codesample2}
+  # Este es un fichero de configuración de Mercurial.
+  [ui]
+  username = Primernombre Apellido <correo.electronico@dominio.net>
+\end{codesample2}
+La línea ``\texttt{[ui]}'' define una \emph{section} del fichero de
+configuración, así que usted puede leer la línea ``\texttt{username =
+...}'' como ``defina el valor del elemento \texttt{username} en la
+sección \texttt{ui}''.
+Una sección continua hasta que empieza otra nueva, o se llega al final
+del fichero. Mercurial ignora las líneas vacías y considera cualquier
+texto desde el caracter ``\texttt{\#}'' hasta el final de la línea
+como un comentario.
+
+\subsubsection{Escoger un nombre de usuario}
+
+Usted puede usar el texto que desee como el valor del campo de
+configuración \texttt{username}, ya que esta información será leída
+por otras personas, e interpretada por Mercurial. La convención que
+sigue la mayoría de la gente es usar su nombre y dirección de correo,
+como en el ejemplo anterior.
+
+\begin{note}
+    % TODO web
+    El servidor web integrado de Mercurial ofusca las direcciones de
+    correo, para dificultar la tarea de las herramientas de
+    recolección de direcciones de correo que usan los
+    spammers\ndt{Personas que envían correo no solicitado, también
+    conocido como correo basura}. Esto reduce la probabilidad de que
+    usted empiece a recibir más correo basura si publica un
+    repositorio en la red.
+\end{note}
+
+\subsection{Escribir un mensaje de consignación}
+
+Cuando consignamos un cambio, Mercurial nos ubica dentro de un editor
+de texto, para ingresar un mensaje que describa las modificaciones que
+hemos introducido en este conjunto de cambios. Esto es conocido como
+un \emph{mensaje de consignación}. Será un registro de lo que hicimos
+y porqué lo hicimos, y será impreso por \hgcmd{log} una vez hayamos
+hecho la consignación.
+\interaction{tour.commit}
+
+El editor en que \hgcmd{commit} nos ubica contendrá una línea vacía,
+seguida de varias líneas que empiezan con la cadena ``\texttt{HG:}''.
+\begin{codesample2}
+  \emph{línea vacía}
+  HG: changed hello.c
+\end{codesample2}
+Mercurial ignora las líneas que empiezan con ``\texttt{HG:}''; sólo
+las usa para indicarnos para cuáles ficheros está registrando los
+cambios. Modificar o borrar estas líneas no tiene ningún efecto.
+
+\subsection{Escribir un buen mensaje de consignación}
+
+Ya que por defecto \hgcmd{log} sólo muestra la primera línea de un
+mensaje de consignación, lo mejor es escribir un mensaje cuya primera
+línea tenga significado por sí misma. A continuación se encuentra un
+ejemplo de un mensaje de consignación que \emph{no} sigue esta
+pauta, y debido a ello tiene un sumario que no es legible.
+\begin{codesample2}
+  changeset:   73:584af0e231be
+  user:        Persona Censurada <persona.censurada@ejemplo.org>
+  date:        Tue Sep 26 21:37:07 2006 -0700
+  summary:     se incluye buildmeister/commondefs.   Añade un módulo
+\end{codesample2}
+
+Con respecto al resto del contenido del mensaje de consignación, no
+hay reglas estrictas-y-rápidas. Mercurial no interpreta ni le da
+importancia a los contenidos del mensaje de consignación, aunque es
+posible que su proyecto tenga políticas que definan una manera
+particular de escribirlo.
+
+Mi preferencia personal es usar mensajes de consignación cortos pero
+informativos, que me digan algo que no puedo inferir con una mirada
+rápida a la salida de \hgcmdargs{log}{--patch}.
+
+\subsection{Cancelar una consignación}
+
+Si usted decide que no desea hacer la consignación mientras está
+editando el mensaje de la misma, simplemente cierre su editor sin
+guardar los cambios al fichero que está editando. Esto hará que no
+pase nada ni en el repositorio ni en el directorio de trabajo.
+
+Si ejecutamos el comando \hgcmd{commit} sin ningún argumento, se
+registran todos los cambios que hemos hecho, como lo indican
+\hgcmd{status} y \hgcmd{diff}.
+
+\subsection{Admirar nuestro trabajo}
+
+Una vez hemos terminado la consignación, podemos usar el comando
+\hgcmd{tip}\ndt{Punta.} para mostrar el conjunto de cambios que acabamos de crear.
+La salida de este comando es idéntica a la de \hgcmd{log}, pero sólo
+muestra la revisión más reciente en el repositorio.
+\interaction{tour.tip}
+Nos referimos a la revisión más reciente en el repositorio como la
+revisión de punta, o simplemente la punta.
+
+\section{Compartir cambios}
+
+Anteriormente mencionamos que los repositorios en Mercurial están auto
+contenidos. Esto quiere decir que el conjunto de cambios que acabamos
+de crear sólo existe en nuestro repositorio \dirname{my-hello}. Veamos
+unas cuantas formas de propagar este cambio a otros repositorios.
+
+\subsection{Jalar cambios desde otro repositorio}
+\label{sec:tour:pull}
+
+Para empezar, clonemos nuestro repositorio \dirname{hello} original,
+el cual no contiene el cambio que acabamos de consignar. Llamaremos a
+este repositorio temporal \dirname{hello-pull}.
+\interaction{tour.clone-pull}
+
+Usaremos el comando \hgcmd{pull} para traer los cambios de
+\dirname{my-hello} y ponerlos en \dirname{hello-pull}.  Sin embargo,
+traer cambios desconocidos y aplicarlos en un repositorio es una
+perspectiva que asusta al menos un poco.  Mercurial cuenta con el
+comando \hgcmd{incoming}\ndt{Entrante, o cambios entrantes.} para
+decirnos qué cambios \emph{jalaría} el comando \hgcmd{pull} al
+repositorio, sin jalarlos.
+\interaction{tour.incoming}
+(Por supuesto, alguien podría enviar más conjuntos de cambios al
+repositorio en el tiempo que pasa entre la ejecución de
+\hgcmd{incoming} y la ejecución de \hgcmd{pull} para jalar los
+cambios, así que es posible que terminemos jalando cambios que no
+esperábamos.)
+
+Traer cambios al repositorio simplemente es cuestión de ejecutar el
+comando \hgcmd{pull}, indicándole de qué repositorio debe jalarlos.
+\interaction{tour.pull}
+Como puede verse por las salidas antes-y-después de \hgcmd{tip}, hemos
+jalado exitosamente los cambios en nuestro repositorio. Aún falta un
+paso para que podamos ver estos cambios en nuestro directorio de
+trabajo.
+
+\subsection{Actualizar el directorio de trabajo}
+
+Hasta ahora hemos pasado por alto la relación entre un repositorio y
+su directorio de trabajo. El comando \hgcmd{pull} que ejecutamos en la
+sección~\ref{sec:tour:pull} trajo los cambios al repositorio, pero si
+revisamos, no hay rastro de esos cambios en el directorio de trabajo.
+Esto pasa porque \hgcmd{pull} (por defecto) no modifica el directorio de
+trabajo. En vez de eso, usamos el comando
+\hgcmd{update}\ndt{Actualizar.} para hacerlo.
+\interaction{tour.update}
+
+Puede parecer algo raro que \hgcmd{pull} no actualice el directorio de
+trabajo automáticamente. De hecho, hay una buena razón para esto:
+usted puede usar \hgcmd{update} para actualizar el directorio de
+trabajo al estado en que se encontraba en \emph{cualquier revisión}
+del historial del repositorio. Si usted hubiera actualizado el
+directorio de trabajo a una revisión anterior---digamos, para buscar
+el origen de un fallo---y hubiera corrido un \hgcmd{pull} que hubiera
+actualizado el directorio de trabajo automáticamente a la nueva
+revisión, puede que no estuviera particularmente contento.
+
+Sin embargo, como jalar-y-actualizar es una secuencia de operaciones
+muy común, Mercurial le permite combinarlas al pasar la opción
+\hgopt{pull}{-u}
+a \hgcmd{pull}.
+\begin{codesample2}
+  hg pull -u
+\end{codesample2}
+Si mira de vuelta la salida de \hgcmd{pull} en la
+sección~\ref{sec:tour:pull} cuando lo ejecutamos sin la opción \hgopt{pull}{-u},
+verá que el comando imprimió un amable recordatorio de que tenemos que
+encargarnos explícitamente de actualizar el directorio de trabajo:
+\begin{codesample2}
+  (run 'hg update' to get a working copy)
+\end{codesample2}
+
+Para averiguar en qué revisión se encuentra el directorio de trabajo,
+use el comando \hgcmd{parents}.
+\interaction{tour.parents}
+Si mira de nuevo la figura~\ref{fig:tour-basic:history}, verá flechas
+conectando cada conjunto de cambios. En cada caso, el nodo del que la flecha
+\emph{sale} es un padre, y el nodo al que la flecha \emph{llega} es 
+su hijo. El directorio de trabajo tiene un padre exactamente de la
+misma manera; ése es el conjunto de cambios que contiene actualmente
+el directorio de trabajo.
+
+Para actualizar el conjunto de trabajo a una revisión particular, pase
+un número de revisión o un ID de conjunto de cambios al comando
+\hgcmd{update}.
+\interaction{tour.older}
+Si no indica explícitamente una revisión, \hgcmd{update} actualizará
+hasta la revisión de punta, como se vio en la segunda llamada a
+\hgcmd{update} en el ejemplo anterior.
+
+\subsection{Empujar cambios a otro repositorio}
+
+Mercurial nos permite empujar cambios a otro repositorio, desde el
+% TODO cambié "visitando" por "usando"
+repositorio que estemos usando actualmente. De la misma forma que en
+el ejemplo de \hgcmd{pull} arriba, crearemos un repositorio temporal
+para empujar allí nuestros cambios.
+\interaction{tour.clone-push}
+El comando \hgcmd{outgoing}\ndt{Saliente. Cambios salientes.} nos dice
+qué cambios serían empujados en el otro repositorio.
+\interaction{tour.outgoing}
+Y el comando \hgcmd{push} se encarga de empujar dichos cambios.
+\interaction{tour.push}
+Al igual que \hgcmd{pull}, el comando \hgcmd{push} no actualiza el
+directorio de trabajo del repositorio en el que estamos empujando los
+cambios.  (A diferencia de \hgcmd{pull}, \hgcmd{push} no ofrece la
+opción \texttt{-u} para actualizar el directorio de trabajo del otro
+repositorio.)
+
+% TODO poner interrogante de apertura
+Qué pasa si tratamos de jalar o empujar cambios y el repositorio
+receptor ya tiene esos cambios? Nada emocionante.
+\interaction{tour.push.nothing}
+
+\subsection{Compartir cambios a través de una red}
+
+Los comandos que hemos presentando en las pocas secciones anteriores
+no están limitados a trabajar con repositorios locales. Cada uno de
+ellos funciona exactamente de la misma manera a través de una conexión
+% TODO poner ndt para URL
+de red. Simplemente pase una URL en vez de una ruta local.
+\interaction{tour.outgoing.net}
+En este ejemplo, podemos ver qué cambios empujaríamos al repositorio
+remoto, aunque, de manera entendible, el repositorio remoto está
+configurado para no permitir a usuarios anónimos empujar cambios a él.
+\interaction{tour.push.net}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-history.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="tour-history.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2812" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="232.14286"
+     inkscape:cy="672.75296"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="5"
+     inkscape:window-y="49"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="opacity:1;fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="244.60992"
+       y="305.245"
+       id="text1902"><tspan
+         sodipodi:role="line"
+         id="tspan1904"
+         x="244.60992"
+         y="305.245">(la más nueva)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="244.60992"
+       y="492.745"
+       id="text1906"><tspan
+         sodipodi:role="line"
+         id="tspan1908"
+         x="244.60992"
+         y="492.745">(la más antigua)</tspan></text>
+    <rect
+       style="opacity:1;fill:#d2e1e4;fill-opacity:1;stroke:#b1cbd0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1907"
+       width="94.285713"
+       height="20.714285"
+       x="309.28571"
+       y="324.86218" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="333.38464"
+       y="338.48334"
+       id="text1909"><tspan
+         sodipodi:role="line"
+         id="tspan1911"
+         x="333.38464"
+         y="338.48334"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1913">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 332.14286,375.21932 L 335.71429,347.36218"
+       id="path2802" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 372.69968,375.21932 L 369.12825,347.36218"
+       id="path2986" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="335.14285"
+       y="387.21933"
+       id="text2988"><tspan
+         sodipodi:role="line"
+         x="335.14285"
+         y="387.21933"
+         id="tspan3020"
+         style="text-align:end;text-anchor:end">número de</tspan><tspan
+         sodipodi:role="line"
+         x="335.14285"
+         y="402.21933"
+         id="tspan3014"
+         style="text-align:end;text-anchor:end">revisión</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times"
+       x="368.71429"
+       y="387.21933"
+       id="text2994"><tspan
+         sodipodi:role="line"
+         id="tspan2996"
+         x="368.71429"
+         y="387.21933">identificador del</tspan><tspan
+         sodipodi:role="line"
+         x="368.71429"
+         y="402.21933"
+         id="tspan2998">conjunto de cambios</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-merge-conflict.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="tour-merge-conflict.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2861" />
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3053"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="251.65243"
+     inkscape:cy="733.42197"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="5"
+     inkscape:window-y="49"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g1988"
+       transform="translate(84.85711,0)">
+      <g
+         id="g1876">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1872"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1874"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1898"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1900"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1902" /></flowRegion><flowPara
+           id="flowPara1904">Saludos!</flowPara><flowPara
+           id="flowPara1906" /><flowPara
+           id="flowPara1908">Soy Mariam Abacha, la esposa del anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot>    </g>
+    <g
+       id="g1966"
+       transform="translate(82,0.35715)">
+      <g
+         transform="translate(-77.85718,-140.0714)"
+         id="g1910">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1912"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1914"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         transform="translate(-77.85718,-140.0714)"
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1916"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1918"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1920" /></flowRegion><flowPara
+           id="flowPara1922">Saludos!</flowPara><flowPara
+           id="flowPara1924" /><flowPara
+           id="flowPara1926">Soy <flowSpan
+   style="font-style:italic;fill:#ff0000"
+   id="flowSpan3094">Shehu Musa Abacha, sobrina del</flowSpan> anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot>    </g>
+    <g
+       id="g1977"
+       transform="translate(81.99999,-0.35715)">
+      <g
+         transform="translate(83.57141,-139.3571)"
+         id="g1932">
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 118.57143,458.21933 L 118.57143,563.79075 L 191.42857,563.79075 L 204.28571,550.93361 L 203.57142,459.6479 L 118.57143,458.21933 z "
+           id="path1934"
+           sodipodi:nodetypes="cccccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 191.55484,563.36862 L 191.6923,560.98794 L 192.69126,552.44884 L 203.80416,551.31242"
+           id="path1936"
+           sodipodi:nodetypes="cccc" />
+      </g>
+      <flowRoot
+         transform="translate(83.57141,-139.3571)"
+         style="font-size:8px;font-family:Times New Roman"
+         id="flowRoot1938"
+         xml:space="preserve"><flowRegion
+           id="flowRegion1940"><rect
+             style="font-size:8px;font-family:Times New Roman"
+             y="464.50504"
+             x="122.85714"
+             height="93.571426"
+             width="76.428574"
+             id="rect1942" /></flowRegion><flowPara
+           id="flowPara1944">Saludos!</flowPara><flowPara
+           id="flowPara1946" /><flowPara
+           id="flowPara1948">Soy <flowSpan
+   style="font-style:italic;fill:#ff0000"
+   id="flowSpan3096">Alhaji Abba Abacha, hijo del</flowSpan> anterior dictador de Nigeria Sani Abacha. Le contacto en secreto, buscando los medios para desarrollar</flowPara></flowRoot>    </g>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 215.502,457.71933 L 196.35507,424.5765"
+       id="path1999"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g1988"
+       inkscape:connection-end="#g1966" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 277.06936,457.71933 L 296.21629,424.5765"
+       id="path2001"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g1988"
+       inkscape:connection-end="#g1977" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="302.42859"
+       y="515.08905"
+       id="text1905"><tspan
+         sodipodi:role="line"
+         id="tspan1907"
+         x="302.42859"
+         y="515.08905">Versión inicial</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="30.57143"
+       y="374.1619"
+       id="text1917"><tspan
+         sodipodi:role="line"
+         id="tspan1919"
+         x="30.57143"
+         y="374.1619">Nuestros cambios</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="385.71429"
+       y="374.1619"
+       id="text1921"><tspan
+         sodipodi:role="line"
+         id="tspan1923"
+         x="385.71429"
+         y="374.1619">Sus cambios</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-merge-merge.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="tour-merge-merge.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2928" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="328.35015"
+     inkscape:cy="790.24518"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1278"
+     inkscape:window-height="756"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2995"
+       width="94.285713"
+       height="20.714285"
+       x="532.85718"
+       y="203.0479" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="297.76227" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="311.38342"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="311.38342"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,343.63731 L 185.14286,319.47656"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="91.428574"
+       y="250.47656" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="116.09886"
+       y="264.56592"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="116.09886"
+         y="264.56592"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 173.95727,296.76228 L 149.75702,272.19085"
+       id="path1971"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2863"
+       inkscape:connection-start="#rect2830" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="186.71414"
+       y="204.40514" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="210.81311"
+       y="218.02673"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="210.81311"
+         y="218.02673"
+         style="font-family:Courier"><tspan
+   id="tspan1966"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 191.06908,296.76228 L 227.93092,226.11942"
+       id="path2919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2830" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;text-anchor:start;text-align:start;writing-mode:lr;line-height:125%"
+       x="295.28571"
+       y="217.56711"
+       id="text2871"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2441">punta (y frente)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="57.817253"
+       y="263.90753"
+       id="text2875"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2439"
+         x="57.817253"
+         y="263.90753">frente</tspan></text>
+    <rect
+       style="fill:#c8aaa5;fill-opacity:1;stroke:#a07163;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2, 4;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1913"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="156.90514" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 144.22399,249.47657 L 179.49029,178.61943"
+       id="path1915"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2863"
+       inkscape:connection-end="#rect1913" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 222.20966,203.40514 L 196.79033,178.61943"
+       id="path1917"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2911"
+       inkscape:connection-end="#rect1913" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="166.16823"
+       y="168.52228"
+       id="text2806"><tspan
+         sodipodi:role="line"
+         id="tspan2808"
+         x="166.16823"
+         y="168.52228"
+         style="font-family:Courier">fusión</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="246"
+       y="162.63338"
+       id="text2810"><tspan
+         sodipodi:role="line"
+         x="246"
+         y="162.63338"
+         id="tspan2814">directorio de trabajo</tspan><tspan
+         sodipodi:role="line"
+         x="246"
+         y="177.63338"
+         id="tspan3538">durante la fusión</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2816"
+       width="94.285713"
+       height="20.714285"
+       x="483.14636"
+       y="297.76227" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="507.24527"
+       y="311.38342"
+       id="text2818"><tspan
+         sodipodi:role="line"
+         id="tspan2820"
+         x="507.24527"
+         y="311.38342"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2822">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 530.28921,343.6373 L 530.28921,319.47655"
+       id="path2824"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2826"
+       width="94.285713"
+       height="20.714285"
+       x="436.57492"
+       y="250.47656" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="461.24484"
+       y="264.56613"
+       id="text2828"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2830"
+         x="461.24484"
+         y="264.56613"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2832">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 519.10362,296.76227 L 494.90337,272.19084"
+       id="path2834"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2836"
+       width="94.285995"
+       height="20.714283"
+       x="483.14001"
+       y="156.548" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="555.95911"
+       y="218.02698"
+       id="text2838"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2840"
+         x="555.95911"
+         y="218.02698"
+         style="font-family:Courier"><tspan
+   id="tspan2842"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 536.21543,296.76227 L 574.03453,224.76218"
+       id="path2844"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="452.00058"
+       y="167.76765"
+       id="text2846"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2443"
+         x="452.00058"
+         y="167.76765">punta</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 489.37034,249.47656 L 524.65575,178.26229"
+       id="path2856"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2836" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+       d="M 567.85714,202.0479 L 542.42591,178.26229"
+       id="path2858"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2836"
+       inkscape:connection-start="#rect2995" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="490.40295"
+       y="170.39714"
+       id="text2860"><tspan
+         sodipodi:role="line"
+         id="tspan2863"
+         x="490.40295"
+         y="170.39714"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2997">7</tspan>: REV7_my_new_hello</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="90.323105"
+       y="120.21933"
+       id="text2929"><tspan
+         sodipodi:role="line"
+         id="tspan2931"
+         x="90.323105"
+         y="120.21933"
+         style="font-weight:bold">Directorio de trabajo durante la fusión</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="435.35226"
+       y="120.21933"
+       id="text2937"><tspan
+         sodipodi:role="line"
+         id="tspan2939"
+         x="435.35226"
+         y="120.21933"
+         style="font-weight:bold">Repositorio después de consignar la fusión</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-merge-pull.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="tour-merge-pull.svg"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2979" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="233.63208"
+     inkscape:cy="704.83702"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="237"
+     inkscape:window-y="103"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="91.428574"
+       y="244.71933" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="116.09886"
+       y="258.80865"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="116.09886"
+         y="258.80865"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 173.95727,291.00504 L 149.75702,266.43361"
+       id="path1971"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#rect2863"
+       inkscape:connection-start="#rect2830" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="186.71414"
+       y="198.6479" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="210.81311"
+       y="212.26949"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="210.81311"
+         y="212.26949"
+         style="font-family:Courier"><tspan
+   id="tspan1966"
+   style="font-weight:bold">6</tspan>: REV6_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       d="M 191.06908,291.00504 L 227.93092,220.36218"
+       id="path2919"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#rect2830" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="291"
+       y="225.3813"
+       id="text2871"><tspan
+         sodipodi:role="line"
+         id="tspan2873"
+         x="291"
+         y="225.3813">tip (y principal)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="76"
+       y="259.16046"
+       id="text2875"><tspan
+         sodipodi:role="line"
+         id="tspan2877"
+         x="76"
+         y="259.16046"
+         style="text-align:end;text-anchor:end">principal</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-merge-sep-repos.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,480 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="tour-merge-sep-repos.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3067" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path2973"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path3066"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="307.20351"
+     inkscape:cy="683.39831"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="5"
+     inkscape:window-y="49"
+     showgrid="false" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="173.57143"
+       y="443.79074"
+       id="text2832"><tspan
+         sodipodi:role="line"
+         id="tspan2834"
+         x="173.57143"
+         y="443.79074" /></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1878"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="479.50504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="493.12619"
+       id="text1872"><tspan
+         sodipodi:role="line"
+         id="tspan1874"
+         x="162.09892"
+         y="493.12619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1876">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2800"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="432.63004" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="446.25119"
+       id="text2794"><tspan
+         sodipodi:role="line"
+         id="tspan2796"
+         x="162.09892"
+         y="446.25119"
+         style="font-family:Courier"><tspan
+   id="tspan2868"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2810"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="385.75504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="399.37619"
+       id="text2804"><tspan
+         sodipodi:role="line"
+         id="tspan2806"
+         x="162.09892"
+         y="399.37619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2866">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2820"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="338.88007" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="352.50122"
+       id="text2814"><tspan
+         sodipodi:role="line"
+         id="tspan2816"
+         x="162.09892"
+         y="352.50122"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2864">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2830"
+       width="94.285713"
+       height="20.714285"
+       x="138"
+       y="292.00504" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09892"
+       y="305.62619"
+       id="text2824"><tspan
+         sodipodi:role="line"
+         id="tspan2826"
+         x="162.09892"
+         y="305.62619"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2862">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,478.50504 L 185.14286,454.34432"
+       id="path2894"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,431.63004 L 185.14286,407.46932"
+       id="path2896"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,384.75504 L 185.14286,360.59435"
+       id="path2898"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.14286,337.88007 L 185.14286,313.71932"
+       id="path2900"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect1963"
+       width="94.285995"
+       height="20.714283"
+       x="138"
+       y="245.18723" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="162.09877"
+       y="258.80865"
+       id="text1965"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan1967"
+         x="162.09877"
+         y="258.80865"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan1973">5</tspan>: REV_my_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 185.143,291.06218 L 185.143,266.90143"
+       id="path1971"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="136.90039"
+       y="232.25546"
+       id="text2921"><tspan
+         sodipodi:role="line"
+         id="tspan2923"
+         x="136.90039"
+         y="232.25546">my-hello</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2863"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="479.49289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="493.11404"
+       id="text2865"><tspan
+         sodipodi:role="line"
+         id="tspan2867"
+         x="394.81305"
+         y="493.11404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2869">0</tspan>: REV0</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2871"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="432.61789" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="446.23904"
+       id="text2873"><tspan
+         sodipodi:role="line"
+         id="tspan2875"
+         x="394.81305"
+         y="446.23904"
+         style="font-family:Courier"><tspan
+   id="tspan2877"
+   style="font-weight:bold">1</tspan>: REV1</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2879"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="385.74289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="399.36404"
+       id="text2881"><tspan
+         sodipodi:role="line"
+         id="tspan2883"
+         x="394.81305"
+         y="399.36404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2885">2</tspan>: REV2</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2887"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="338.86792" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="352.48907"
+       id="text2889"><tspan
+         sodipodi:role="line"
+         id="tspan2891"
+         x="394.81305"
+         y="352.48907"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2893">3</tspan>: REV3</tspan></text>
+    <rect
+       style="fill:#a5c3c8;fill-opacity:1;stroke:#6396a0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2895"
+       width="94.285713"
+       height="20.714285"
+       x="370.71414"
+       y="291.99289" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81305"
+       y="305.61404"
+       id="text2897"><tspan
+         sodipodi:role="line"
+         id="tspan2899"
+         x="394.81305"
+         y="305.61404"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2901">4</tspan>: REV4</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,478.4929 L 417.85701,454.33218"
+       id="path2903"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,431.6179 L 417.85701,407.45718"
+       id="path2905"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,384.7429 L 417.85701,360.58221"
+       id="path2907"
+       inkscape:connector-type="polyline" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85701,337.86793 L 417.85701,313.70718"
+       id="path2909"
+       inkscape:connector-type="polyline" />
+    <rect
+       style="fill:#78a5ad;fill-opacity:1;stroke:#507b84;stroke-width:2.00000286;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2911"
+       width="94.285995"
+       height="20.714283"
+       x="370.71414"
+       y="245.17511" />
+    <text
+       xml:space="preserve"
+       style="font-size:12.00001812px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Courier"
+       x="394.81274"
+       y="258.79678"
+       id="text2913"
+       transform="scale(1.000002,0.999998)"><tspan
+         sodipodi:role="line"
+         id="tspan2915"
+         x="394.81274"
+         y="258.79678"
+         style="font-family:Courier"><tspan
+   style="font-weight:bold"
+   id="tspan2917">5</tspan>: REV_my_new_hello</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.00000143px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+       d="M 417.85715,291.05004 L 417.85715,266.88929"
+       id="path2919"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="369.61453"
+       y="232.25546"
+       id="text2925"><tspan
+         sodipodi:role="line"
+         id="tspan2927"
+         x="369.61453"
+         y="232.25546">my-new-hello</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="300.54352"
+       y="252.12723"
+       id="text2933"><tspan
+         sodipodi:role="line"
+         id="tspan2935"
+         x="300.54352"
+         y="252.12723"
+         style="text-align:center;text-anchor:middle">Los cambios</tspan><tspan
+         sodipodi:role="line"
+         x="300.54352"
+         y="267.12723"
+         style="text-align:center;text-anchor:middle"
+         id="tspan3494">más recientes</tspan><tspan
+         sodipodi:role="line"
+         x="300.54352"
+         y="282.12723"
+         style="text-align:center;text-anchor:middle"
+         id="tspan3132">difieren</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="262.15436"
+       y="398.37112"
+       id="text2929"><tspan
+         sodipodi:role="line"
+         x="262.15436"
+         y="398.37112"
+         id="tspan3013"
+         style="text-align:start;text-anchor:start">historia común</tspan></text>
+    <g
+       id="g3107"
+       transform="translate(0,0.855744)">
+      <path
+         id="path3101"
+         d="M 300.35713,381.29075 L 300.35713,304.50504"
+         style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" />
+      <path
+         id="path3105"
+         d="M 291.07142,301.64789 L 309.28571,301.64789"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+    <path
+       style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 300.53571,486.38926 L 300.53571,409.60355"
+       id="path3113" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#bfbfbf;stroke-width:0.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 291.25,488.49641 L 309.46429,488.49641"
+       id="path3115" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="480.71429"
+       y="250.91507"
+       id="text1949"><tspan
+         sodipodi:role="line"
+         id="tspan1951"
+         x="480.71429"
+         y="250.91507"
+         style="text-align:start;text-anchor:start">revisión principal</tspan><tspan
+         sodipodi:role="line"
+         x="480.71429"
+         y="265.91507"
+         id="tspan1953"
+         style="text-align:start;text-anchor:start">     (sin hijos)</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/tour-merge.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,308 @@
+\chapter{Una gira de Mercurial: fusionar trabajo}
+\label{chap:tour-merge}
+
+Hasta ahora hemos cubierto cómo clonar un repositorio, hacer cambios,
+y jalar o empujar dichos cambios de un repositorio a otro. Nuestro
+siguiente paso es \emph{fusionar} cambios de repositorios separados.
+
+% TODO cambié streams por líneas. check please
+\section{Fusionar líneas de trabajo}
+
+Fusionar es una parte fundamental de trabajar con una herramienta 
+de control distribuido de versiones.
+\begin{itemize}
+\item Alicia y Roberto tienen cada uno una copia personal del
+    repositorio de un proyecto en el que están trabajando. Alicia
+    arregla un fallo en su repositorio; Roberto añade una nueva
+    característica en el suyo. Ambos desean que el repositorio
+    compartido contenga el arreglo del fallo y la nueva
+    característica.
+\item Frecuentemente trabajo en varias tareas diferentes en un mismo
+    proyecto al mismo tiempo, cada una aislada convenientemente de las
+    otras en su propio repositorio. Trabajar de esta manera significa
+    que a menudo debo fusionar una parte de mi propio trabajo con
+    otra.
+\end{itemize}
+
+Como fusionar es una operación tan necesaria y común, Mercurial la
+facilita. Revisemos el proceso. Empezaremos clonando (otro)
+% TODO poner interrogante de apertura
+repositorio (ve lo seguido que aparecen?) y haciendo un cambio en él.
+\interaction{tour.merge.clone}
+Ahora deberíamos tener dos copias de \filename{hello.c} con contenidos
+diferentes.  El historial de los dos repositorios diverge ahora, como
+se ilustra en la figura~\ref{fig:tour-merge:sep-repos}.
+\interaction{tour.merge.cat}
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-merge-sep-repos}
+  \caption{Historial reciente divergente de los repositorios
+      \dirname{my-hello} y \dirname{my-new-hello}}
+  \label{fig:tour-merge:sep-repos}
+\end{figure}
+
+Ya sabemos que jalar los cambios desde nuestro repositorio
+\dirname{my-hello} no tendrá efecto en el directorio de trabajo.
+\interaction{tour.merge.pull}
+Sin embargo, el comando \hgcmd{pull} dice algo acerca de
+``frentes''\ndt{El autor se refiere a \emph{heads} aquí.}.  
+
+\subsection{Conjuntos de cambios de frentes}
+
+Un frente es un cambio que no tiene descendientes, o hijos, como
+también se les conoce. La revisión de punta es, por tanto, un frente,
+porque la revisión más reciente en un repositorio no tiene ningún
+% TODO cambio en la redacción de la frase, pero espero que conserve el
+% sentido. Querido human@, apruebe o corrija :D
+hijo. Sin embargo, un repositorio puede contener más de un frente.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-merge-pull}
+  \caption{Contenidos del repositorio después de jalar
+      \dirname{my-hello} a \dirname{my-new-hello}}
+  \label{fig:tour-merge:pull}
+\end{figure}
+
+En la figura~\ref{fig:tour-merge:pull} usted puede ver el efecto que
+tiene jalar los cambios de \dirname{my-hello} a \dirname{my-new-hello}.
+El historial que ya existía en \dirname{my-new-hello} se mantiene
+intacto, pero fue añadida una nueva revisión. Refiriéndonos a la
+figura~\ref{fig:tour-merge:sep-repos}, podemos ver que el \emph{ID del
+conjunto de cambios} se mantiene igual en el nuevo repositorio, pero
+el \emph{número de revisión} ha cambiado.  (Incidentalmente, éste es un
+buen ejemplo de porqué no es seguro usar números de revisión cuando se
+habla de conjuntos de cambios).  Podemos ver los frentes en un
+repositorio usando el comando \hgcmd{heads}\ndt{Frentes.}.
+\interaction{tour.merge.heads}
+
+\subsection{Hacer la fusión}
+
+% TODO poner interrogante de apertura
+Qué pasa si tratamos de usar el comando usual, \hgcmd{update}, para
+actualizar el nuevo frente?
+\interaction{tour.merge.update}
+Mercurial nos indica que el comando \hgcmd{update} no hará la fusión;
+no actualizará el directorio de trabajo cuando considera que lo que
+deseamos hacer es una fusión, a menos que lo obliguemos a hacerlo.
+En vez de \hgcmd{update}, usamos el comando \hgcmd{merge} para hacer
+la fusión entre los dos frentes.
+\interaction{tour.merge.merge}
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-merge-merge}
+  \caption{Directorio de trabajo y repositorio durante la fusión, y
+  consignación consecuente}
+  \label{fig:tour-merge:merge}
+\end{figure}
+
+Esto actualiza el directorio de trabajo, de tal forma que contenga los
+cambios de \emph{ambos} frentes, lo que se ve reflejado tanto en la
+salida de \hgcmd{parents} como en los contenidos de \filename{hello.c}.
+\interaction{tour.merge.parents}
+
+\subsection{Consignar los resultados de la fusión}
+
+Siempre que hacemos una fusión, \hgcmd{parents} mostrará dos padres
+hasta que consignemos (\hgcmd{commit}) los resultados de la fusión.
+\interaction{tour.merge.commit}
+Ahora tenemos una nueva revisión de punta; note que tiene \emph{los
+dos} frentes anteriores como sus padres. Estos son las mismas
+revisiones que mostró previamente el comando \hgcmd{parents}.
+\interaction{tour.merge.tip}
+En la figura~\ref{fig:tour-merge:merge} usted puede apreciar una
+representación de lo que pasa en el directorio de trabajo durante la
+fusión cuando se hace la consignación. Durante la fusión, el
+directorio de trabajo tiene dos conjuntos de cambios como sus padres,
+y éstos se vuelven los padres del nuevo conjunto de cambios.
+
+\section{Fusionar cambios con conflictos}
+
+La mayoría de las fusiones son algo simple, pero a veces usted se
+encontrará fusionando cambios donde más de uno de ellos afecta las
+mismas secciones de los mismos ficheros. A menos que ambas
+modificaciones sean idénticas, el resultado es un \emph{conflicto}, en
+donde usted debe decidir cómo reconciliar ambos cambios y producir un
+resultado coherente.
+
+\begin{figure}[ht]
+  \centering
+  \grafix{tour-merge-conflict}
+  \caption{Cambios con conflictos a un documento}
+  \label{fig:tour-merge:conflict}
+\end{figure}
+
+La figura~\ref{fig:tour-merge:conflict} ilustra un ejemplo con dos
+cambios generando conflictos en un documento. Empezamos con una sola
+versión del fichero; luego hicimos algunos cambios; mientras tanto,
+alguien más  hizo cambios diferentes en el mismo texto. Lo que debemos
+hacer para resolver el conflicto causado por ambos cambios es decidir
+cómo debe quedar finalmente el fichero.
+
+Mercurial no tiene ninguna utilidad integrada para manejar conflictos.
+En vez de eso, ejecuta un programa externo llamado \command{hgmerge}.
+Es un guión de línea de comandos que es instalado junto con Mercurial;
+usted puede modificarlo para que se comporte como usted lo desee. Por
+defecto, lo que hace es tratar de encontrar una de varias herramientas
+para fusionar que es probable que estén instaladas en su sistema.
+Primero se intenta con unas herramientas para fusionar cambios
+automáticamente; si esto no tiene éxito (porque la fusión demanda
+una guía humana) o dichas herramientas no están presentes, el guión
+intenta con herramientas gráficas para fusionar.
+
+También es posible hacer que Mercurial ejecute otro programa o guión
+en vez de \command{hgmerge}, definiendo la variable de entorno
+\envar{HGMERGE} con el nombre del programa de su preferencia.
+
+\subsection{Usar una herramienta gráfica para fusión}
+
+Mi herramienta favorita para hacer fusiones es \command{kdiff3}, y la
+usaré para describir las características comunes de las herramientas
+gráficas para hacer fusiones. Puede ver una captura de pantalla de
+\command{kdiff3} ejecutándose, en la
+figura~\ref{fig:tour-merge:kdiff3}.  El tipo de fusión que la
+herramienta hace se conoce como \emph{fusión de tres vías}, porque hay
+tres versiones diferentes del fichero en que estamos interesados.
+Debido a esto la herramienta divide la parte superior de la ventana en
+tres paneles.
+\begin{itemize}
+\item A la izquierda está la revisión \emph{base} del fichero, p.ej.~la
+    versión más reciente de la que descienden las dos versiones que
+    estamos tratando de fusionar.
+\item En la mitad está ``nuestra'' versión del fichero, con las
+    modificaciones que hemos hecho.
+\item A la derecha está la versión del fichero de ``ellos'', la que
+    forma parte del conjunto de cambios que estamos tratando de
+    fusionar.
+\end{itemize}
+En el panel inferior se encuentra el \emph{resultado} actual de la
+fusión. Nuestra tarea es reemplazar todo el texto rojo, que muestra
+los conflictos sin resolver, con una fusión adecuada de ``nuestra''
+versión del fichero y la de ``ellos''.
+
+Los cuatro paneles están \emph{enlazados}; si avanzamos vertical o
+horizontalmente en cualquiera de ellos, los otros son actualizados
+para mostrar las secciones correspondientes del fichero que tengan
+asociado.
+
+\begin{figure}[ht]
+  \centering
+  \grafix[width=\textwidth]{kdiff3}
+  \caption{Usando \command{kdiff3} para fusionar versiones de un
+  fichero}
+  \label{fig:tour-merge:kdiff3}
+\end{figure}
+
+En cada conflicto del fichero podemos escoger resolverlo usando
+cualquier combinación del texto de la revisión base, la nuestra, o la
+de ellos. También podemos editar manualmente el fichero en que queda
+la fusión, si es necesario hacer cambios adicionales.
+
+Hay \emph{muchas} herramientas para fusionar ficheros disponibles. Se
+diferencian en las plataformas para las que están disponibles, y en
+sus fortalezas y debilidades particulares. La mayoría están afinadas
+para fusionar texto plano, mientras que otras están pensadas para
+formatos de ficheros especializados (generalmente XML).
+
+% TODO traduje "worked" como "real"
+\subsection{Un ejemplo real}
+
+En este ejemplo, reproduciremos el historial de modificaciones al
+fichero de la figura~\ref{fig:tour-merge:conflict} mostrada
+anteriormente.  Empecemos creando un repositorio con la versión base
+de nuestro documento.
+\interaction{tour-merge-conflict.wife}
+Clonaremos el repositorio y haremos un cambio al fichero.
+\interaction{tour-merge-conflict.cousin}
+Y haremos otro clon, para simular a alguien más haciendo un cambio al
+mismo fichero. (Esto introduce la idea de que no es tan inusual hacer
+fusiones consigo mismo, cuando usted aísla tareas en repositorios
+separados, y de hecho encuentra conflictos al hacerlo.)
+\interaction{tour-merge-conflict.son}
+Ahora que tenemos dos versiones diferentes de nuestro fichero,
+crearemos un entorno adecuado para hacer la fusión.
+\interaction{tour-merge-conflict.pull}
+
+En este ejemplo, no usaré el comando normal de Mercurial para hacer la
+fusión (\command{hgmerge}), porque lanzaría mi linda herramienta
+automatizada para correr ejemplos dentro de una interfaz gráfica de
+usuario. En vez de eso, definiré la variable de entorno
+\envar{HGMERGE} para indicarle a Mercurial que use el comando
+\command{merge}. Este comando forma parte de la instalación base de
+muchos sistemas Unix y similares. Si usted está ejecutando este
+ejemplo en su computador, no se moleste en definir \envar{HGMERGE}.
+\interaction{tour-merge-conflict.merge}
+Debido a que \command{merge} no puede resolver los conflictos que
+aparecen, él deja \emph{marcadores de fusión} en el fichero con
+conflictos, indicando si provienen de nuestra versión o de la de
+ellos.
+
+Mercurial puede saber ---por el código de salida del comando
+\command{merge}--- que no fue posible hacer la fusión exitosamente,
+así que nos indica qué comandos debemos ejecutar si queremos rehacer
+la fusión. Esto puede ser útil si, por ejemplo, estamos ejecutando una
+herramienta gráfica de fusión y salimos de ella porque nos confundimos
+o cometimos un error.
+
+Si la fusión ---automática o manual--- falla, no hay nada que nos
+impida ``arreglar'' los ficheros afectados por nosotros mismos, y
+consignar los resultados de nuestra fusión:
+% TODO este mercurial no tiene el comando resolve. Revisar si sigue
+% siendo necesario
+\interaction{tour-merge-conflict.commit}
+
+\section{Simplificar el ciclo jalar-fusionar-consignar}
+\label{sec:tour-merge:fetch}
+
+El proceso de fusionar cambios delineado anteriomente es directo, pero
+requiere la ejecución de tres comandos en sucesión.
+\begin{codesample2}
+  hg pull
+  hg merge
+  hg commit -m 'Fusionados cambios remotos'
+\end{codesample2}
+En la consignación final usted debe proveer un mensaje adecuado, que
+casi siempre es un fragmento de texto ``de relleno'' carente de valor
+particular.
+
+Sería agradable reducir la cantidad de pasos necesarios, si fuera
+posible. De hecho, Mercurial es distribuido junto con una extensión
+llamada \hgext{fetch}\ndt{Descargar, traer.} que hace precisamente
+esto.
+
+Mercurial cuenta con un mecanismo de extensión flexible que le permite
+% TODO lets people => permite a usuarios
+a sus usuarios extender su funcionalidad, manteniendo el núcleo de
+Mercurial pequeño y fácil de manejar. Algunas extensiones añaden
+nuevos comandos que usted puede usar desde la línea de comandos,
+mientras que otros funcionan ``tras bambalinas'', por ejemplo,
+añadiendo funcionalidad al servidor.
+
+La extensión \hgext{fetch} añade un comando llamado, no
+sorpresivamente, \hgcmd{fetch}.  Esta extensión actúa como una
+combinación de \hgcmd{pull}, \hgcmd{update} y \hgcmd{merge}.  Empieza
+jalando cambios de otro repositorio al repositorio actual. Si
+encuentra que los cambios añaden un nuevo frente en el repositorio
+actual, inicia una fusión, y luego consigna el resultado de la misma
+con un mensaje generado automáticamente. Si no se añadieron nuevos
+frentes, actualiza el directorio de trabajo con el nuevo conjunto de
+cambios de punta.
+
+Activar la extensión \hgext{fetch} es fácil. Edite su
+\sfilename{.hgrc}, y vaya a (o cree) la sección
+\rcsection{extensions}.  Luego añada una línea que diga simplemente
+``\Verb+fetch +''.
+\begin{codesample2}
+  [extensions]
+  fetch =
+\end{codesample2}
+(Normalmente, a la derecha del ``\texttt{=}'' debería aparecer la
+ubicación de la extensión, pero como el comando \hgext{fetch} es parte
+de la distribución estándar, Mercurial sabe dónde buscarla.)
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-manual-merge.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+digraph undo_manual {
+	"primer cambio" -> "segundo cambio";
+	"segundo cambio" -> "tercer cambio";
+	reversar [label="reversar\nsegundo cambio", shape=box];
+	"segundo cambio" -> reversar;
+	"tercer cambio" -> "fusión\nmanual";
+	reversar -> "fusión\nmanual";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-manual.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,6 @@
+digraph undo_manual {
+	"primer cambio" -> "segundo cambio";
+	"segundo cambio" -> "tercer cambio";
+	reversar [label="reversar\nsegundo cambio", shape=box];
+	"segundo cambio" -> reversar;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-non-tip.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,9 @@
+digraph undo_non_tip {
+	"primer cambio" -> "segundo cambio";
+	"segundo cambio" -> "tercer cambio";
+	reversar [label="reversar\nsegundo cambio", shape=box];
+	"segundo cambio" -> reversar;
+	merge [label="automatizar\nfusión", shape=box];
+	"tercer cambio" -> fusión;
+	reversar -> fusión;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo-simple.dot	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,4 @@
+digraph undo_simple {
+	"primer cambio" -> "segundo cambio";
+	"segundo cambio" -> "reversar\nsegundo cambio";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/undo.tex	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,799 @@
+\chapter{Encontrar y arreglar sus equivocaciones}
+\label{chap:undo}
+
+Errar es humano, pero tratar adecuadamente las consecuencias requiere
+un sistema de control de revisiones de primera categoría.  En este
+capítulo, discutiremos algunas técnicas que puede usar cuando
+encuentra que hay un problema enraizado en su proyecto.  Mercurial
+tiene unas características poderosas que le ayudarán a isolar las
+fuentes de los problemas, y a dar cuenta de ellas apropiadamente.
+
+\section{Borrar el historial local}
+
+\subsection{La consignación accidental}
+
+Tengo el problema ocasional, pero persistente de teclear más rápido de
+lo que pienso, que aveces resulta en consignar un conjunto de cambios
+incompleto o simplemente malo. En mi caso, el conjunto de cambios
+incompleto consiste en que creé un nuevo fichero fuente, pero olvidé
+hacerle \hgcmd{add}.  Un conjunto de cambios``simplemente malo'' no es
+tan común, pero sí resulta muy molesto.
+
+\subsection{Hacer rollback una transacción}
+\label{sec:undo:rollback}
+
+En la sección~\ref{sec:concepts:txn}, mencioné que Mercurial trata
+modificación a un repositorio como una \emph{transacción}.  Cada vez
+que consigna un conjunto de cambios o lo jala de otro repositorio,
+Mercurial recuerda lo que hizo.  Puede deshacer, o hacer \emph{roll back}\ndt{El significado igual que en los
+    ambientes de sistemas manejadores de bases de datos se refiere a
+    la atomicidad e integridad al devolver un conjunto de acciones que
+  permitan dejar el repositorio en un estado consistente previo},
+exactamente una de tales acciones usando la orden \hgcmd{rollback}.
+(Ver en la sección~\ref{sec:undo:rollback-after-push} una anotación
+importante acerca del uso de esta orden.)
+
+A continuación una equivocación que me sucede frecuentemente:
+consignar un cambio en el cual he creado un nuevo fichero, pero he
+olvidado hacerle \hgcmd{add}.
+\interaction{rollback.commit}
+La salida de \hgcmd{status} después de la consignación confirma
+inmediatamente este error.
+\interaction{rollback.status}
+La consignación capturó los cambios en el fichero \filename{a}, pero
+no el nuevo fichero \filename{b}.  Si yo publicara este conjunto de
+cambios a un repositorio compartido con un colega, es bastante
+probable que algo en \filename{a} se refiriera a \filename{b}, el cual
+podría no estar presente cuando jalen mis cambios del repositorio.  Me
+convertiría el sujeto de cierta indignación.
+
+Como sea, la suerte me acompaña---Encontré mi error antes de publicar
+el conjunto de cambios.  Uso la orden \hgcmd{rollback}, y Mercurial
+hace desaparecer el último conjunto de cambios.
+\interaction{rollback.rollback}
+El conjunto de cambios ya no está en el historial del repositorio, y el
+directorio de trabajo cree que el fichero \filename{a} ha sido
+modificado.  La consignación y el roll back dejaron el directorio de
+trabajo exactamente como estaba antes de la consignación; el conjunto
+de cambios ha sido eliminado totlamente. Ahora puedo hacer \hgcmd{add}
+al fichero \filename{b}, y hacer de nuevo la consignación.
+\interaction{rollback.add}
+
+\subsection{Erroneamente jalado}
+
+Mantener ramas de desarrollo separadas de un proyecto en distintos
+repositorios es una práctica común con Mercurial.  Su equipo de
+desarrollo puede tener un repositorio compartido para la versión ``0.9''
+y otra con cambios distintos para la versión ``1.0''.
+
+Con este escenario, puede imaginar las consecuencias si tuviera un
+repositorio local ``0.9'', y jalara accidentalmente los cambios del
+repositorio compartido de la versión ``1.0'' en este.  En el peor de
+los casos, por falta de atención, es posible que publique tales
+cambios en el árbol compartido ``0.9'', confundiendo a todo su equipo
+de trabajo (pero no se preocupe, volveremos a este terrorífico
+escenario posteriormente).  En todo caso, es muy probable que usted se
+de cuenta inmediatamente, dado que Mercurial mostrará el URL de donde
+está jalando, o que vea jalando una sospechosa gran cantidad de
+cambios en el repositorio.
+
+La orden \hgcmd{rollback} excluirá eficientemente los conjuntos de
+cambios que haya acabado de jalar.  Mercurial agrupa todos los cambios
+de un \hgcmd{pull} a una única transacción y bastará con un
+\hgcmd{rollback} para deshacer esta equivocación.
+
+\subsection{Después de publicar, un roll back es futil}
+\label{sec:undo:rollback-after-push}
+
+El valor de \hgcmd{rollback} se anula cuando ha publicado sus cambios
+a otro repositorio.  Un cambio desaparece totalmente al hacer roll back,
+pero \emph{solamente} en el repositorio en el cual aplica
+\hgcmd{rollback}.  Debido a que un roll back elimina el historial,
+no hay forma de que la desaparición de un cambio se propague entre
+repositorios.
+
+Si ha publicado un cambio en otro repositorio---particularmente si es
+un repositorio público---esencialmente está ``en terreno agreste,''
+y tendrá que reparar la equivocación de un modo distinto.  Lo que
+pasará si publica un conjunto de cambios en algún sitio, hacer
+rollback y después volver a jalar del repositorio del cual había
+publicado, es que el conjunto de cambios reaparecerá en su repositorio.
+
+(Si está absolutamente segruro de que el conjunto de cambios al que
+desea hacer rollback es el cambio más reciente del repositorio en el
+cual publicó, \emph{y} sabe que nadie más pudo haber jalado de tal
+repositorio, puede hacer rollback del conjunto de cambios allí, pero
+es mejor no confiar en una solución de este estilo.  Si lo hace, tarde
+o temprano un conjunto de cambios logrará colarse en un repositorio
+que usted no controle directamente (o del cual se ha olvidado), y
+volverá a hostigarle.)
+
+\subsection{Solamente hay un roll back}
+
+Mercurial almacena exactamente una transacción en su bitácora de
+transacciones; tal transacción es la más reciente de las que haya
+ocurrido en el repositorio. Esto significa que solamente puede hacer
+roll back a una transacción. Si espera poder hacer roll back a una
+transacción después al antecesor, observará que no es el
+comportamiento que obtendrá.
+\interaction{rollback.twice}
+Una vez que haya aplicado un rollback en una transacción a un
+repositorio, no podrá volver a hacer rollback hasta que haga una
+consignación o haya jalado.
+
+\section{Revertir un cambio equivocado}
+
+Si modifica un fichero y se da cuenta que no quería realmente cambiar
+tal fichero, y todavía no ha consignado los cambios, la orden
+necesaria es \hgcmd{revert}. Observa el conjunto de cambios padre del
+directorio y restaura los contenidos del fichero al estado de tal
+conjunto de cambios. (Es una forma larga de decirlo, usualmente
+deshace sus modificaciones.)
+
+Ilustremos como actúa la orden \hgcmd{revert} con un ejemplo
+pequeño. Comenzaremos modificando un fichero al cual Mercurial ya está
+siguiendo.
+\interaction{daily.revert.modify}
+Si no queremos ese cambio, podemos aplicar \hgcmd{revert} al fichero.
+\interaction{daily.revert.unmodify}
+La orden \hgcmd{revert} nos brinda un grado adicional de seguridad
+guardando nuestro fichero modificado con la extensión \filename{.orig}.
+\interaction{daily.revert.status}
+
+Este es un resumen de casos en los cuales la orden \hgcmd{revert} es
+de utilidad. Describiremos cada uno de ellos con más detalle en la
+sección siguiente.
+\begin{itemize}
+\item Si usted modifica un fichero, lo restaurará a su estado sin
+  modificación previo.
+\item Si usted hace \hgcmd{add} a un fichero, revertirá el estado de
+  ``adicionado'' del fichero, pero no lo tocará
+\item Si borra un fichero sin decirle a Mercurial, restaurará el
+  fichero con sus contenidos sin modificación.
+\item Si usa la orden \hgcmd{remove} para eliminar un fichero, deshará
+  el estado ``removido'' del fichero, y lo restaurará con sus
+  contenidos sin modificación.
+\end{itemize}
+
+\subsection{Errores al administrar ficheros}
+\label{sec:undo:mgmt}
+
+La orden \hgcmd{revert} es útil para más que ficheros modificados. Le
+permite reversar los resultados de todas las órdenes de administración
+de ficheros que provee Mercurial---\hgcmd{add}, \hgcmd{remove}, y las
+demás.
+
+Si usted hace \hgcmd{add} a un fichero, y no deseaba que Mercurial le
+diera seguimiento, use \hgcmd{revert} para deshacer la adición.  No se
+preocupe; Mercurial no modificará de forma alguna el fichero.
+Solamente lo ``desmarcará''.
+\interaction{daily.revert.add}
+
+De forma similar, Si le solicita a Mercurial hacer \hgcmd{remove} a un
+fichero, puede usar \hgcmd{revert} para restarurarlo a los contenidos
+que tenía la revisión padre del directorio de trabajo.
+\interaction{daily.revert.remove}
+Funciona de la misma manera para un fichero que usted haya eliminado
+manualmente, sin decirle a Mercurial (recuerde que en la terminología
+de Mercurial esta clase de fichero se llama ``faltante'').
+\interaction{daily.revert.missing}
+
+Si usted revierte un \hgcmd{copy}, el fichero a donde se copió
+permanece en su directorio de trabajo, pero sin seguimiento. Dado que
+una copia no afecta el fichero fuente de copiado de ninguna maner,
+Mercurial no hace nada con este.
+\interaction{daily.revert.copy}
+
+\subsubsection{Un caso ligeramente especial:revertir un renombramiento}
+
+Si hace \hgcmd{rename} a un fichero, hay un detalle que debe tener en
+cuenta. Cuando aplica \hgcmd{revert} a un cambio de nombre, no es
+suficiente proveer el nombre del fichero destino, como puede verlo en
+el siguiente ejemplo.
+\interaction{daily.revert.rename}
+Como puede ver en la salida de \hgcmd{status}, el fichero con el nuevo
+nombre no se identifica más como agregado, pero el fichero con el
+nombre-\emph{inicial} se elimna!  Esto es contra-intuitivo (por lo
+menos para mí), pero por lo menos es fácil arreglarlo.
+\interaction{daily.revert.rename-orig}
+Por lo tanto, recuerde, para revertir un \hgcmd{rename}, debe proveer
+\emph{ambos} nombres, la fuente y el destino.
+
+% TODO: the output doesn't look like it will be removed!
+
+(A propósito, si elimina un fichero, y modifica el fichero con el
+nuevo nombre, al revertir ambos componentes del renombramiento, cuando
+Mercurial restaure el fichero que fue eliminado como parte del
+renombramiento, no será modificado.
+Si necesita que las modificaciones en el fichero destino del
+renombramiento se muestren, no olvide copiarlas encima.)
+
+Estos aspectos engorrosos al revertir un renombramiento se constituyen
+discutiblemente en un fallo de Mercurial.
+
+\section{Tratar cambios consignados}
+
+Considere un caso en el que ha consignado el cambio $a$, y otro cambio
+$b$ sobre este; se ha dado cuenta que el cambio $a$ era
+incorrecto. Mercurial le permite ``retroceder'' un conjunto de cambios
+completo automáticamente, y construir bloques que le permitan revertir
+parte de un conjunto de cambios a mano.
+
+Antes de leer esta sección, hay algo para tener en cuenta: la orden
+\hgcmd{backout} deshace cambios \emph{adicionando} al historial, sin
+modificar o borrar.  Es la herramienta correcta si está arreglando
+fallos, pero no si está tratando de deshacer algún cambio que tiene
+consecuencias catastróficas.  Para tratar con esos, vea la sección~\ref{sec:undo:aaaiiieee}.
+
+\subsection{Retroceder un conjunto de cambios}
+
+La orden \hgcmd{backout} le permite ``deshacer'' los efectos de todo
+un conjunto de cambios de forma automatizada.  Dado que el historial de
+Mercurial es inmutable, esta orden \emph{no} se deshace del conjunto
+de cambios que usted desea deshacer.  En cambio, crea un nuevo
+conjunto de cambios que \emph{reversa} el conjunto de cambios que
+usted indique.
+
+La operación de la orden \hgcmd{backout} es un poco intrincada, y lo
+ilustraremos con algunos ejemplos. Primero crearemos un repositorio
+con algunos cambios sencillos.
+\interaction{backout.init}
+
+La orden \hgcmd{backout} toma un ID de conjunto de cambios como su
+argumento; el conjunto de cambios a retroceder. Normalmente
+\hgcmd{backout} le ofrecerá un editor de texto para escribir el
+mensaje de la consignación, para dejar un registro de por qué está
+retrocediendo. En este ejemplo, colocamos un mensaje en la
+consignación usando la opción \hgopt{backout}{-m}.
+
+\subsection{Retroceder el conjunto de cambios punta}
+
+Comenzamos retrocediendo el último conjunto de cambios que consignamos.
+\interaction{backout.simple}
+Puede ver que la segunda línea de \filename{myfile} ya no está
+presente.  La salida de \hgcmd{log} nos da una idea de lo que la orden
+\hgcmd{backout} ha hecho.
+\interaction{backout.simple.log}
+Vea que el nuevo conjunto de cambios que \hgcmd{backout} ha creado es
+un hijo del conjunto de cambios que retrocedimos. Es más sencillo de
+ver en la figura~\ref{fig:undo:backout}, que presenta una vista
+gráfica del historial de cambios.  Como puede ver, el historial es
+bonito y lineal.
+
+\begin{figure}[htb]
+  \centering
+  \grafix{undo-simple}
+  \caption{Retroceso de un cambio con la orden \hgcmd{backout}}
+  \label{fig:undo:backout}
+\end{figure}
+
+\subsection{Retroceso de un cambio que no es la punta}
+
+Si desea retrocede un cambio distinto al último que ha consignado, use
+la opción \hgopt{backout}{--merge} a la orden \hgcmd{backout}.
+\interaction{backout.non-tip.clone}
+Que resulta en un retroceso de un conjunto de cambios ``en un sólo
+tiro'', una operación que resulta normalmente rápida y sencilla.
+\interaction{backout.non-tip.backout}
+
+Si ve los contenidos del fichero \filename{myfile} después de
+finalizar el retroceso, verá que el primer y el tercer cambio están
+presentes, pero no el segundo.
+\interaction{backout.non-tip.cat}
+
+Como lo muestra el historial gráfico en la
+figura~\ref{fig:undo:backout-non-tip}, Mercurial realmente consigna
+\emph{dos} cambios en estas situaciones (los nodos encerrados en una
+caja son aquellos que Mercurial consigna automaticamente).  Antes de
+que Mercurial comience el proceso de retroceso, primero recuerda cuál
+es el padre del directorio de trabajo.  Posteriormente hace un
+retroceso al conjunto de cambios objetivo y lo consigna como un
+conjunto de cambios. Finalmente, fusiona con el padre anterior del
+directorio de trabajo, y consigna el resultado de la fusión.
+
+% TODO: to me it looks like mercurial doesn't commit the second merge automatically!
+
+\begin{figure}[htb]
+  \centering
+  \grafix{undo-non-tip}
+  \caption{Retroceso automatizado de un cambio a algo que no es la punta con la orden \hgcmd{backout}}
+  \label{fig:undo:backout-non-tip}
+\end{figure}
+
+El resultado es que usted termina ``donde estaba'', solamente con un
+poco de historial adicional que deshace el efecto de un conjunto de
+cambios que usted quería evitar.
+
+\subsubsection{Use siempre la opción \hgopt{backout}{--merge}}
+
+De hecho, dado que la opción \hgopt{backout}{--merge} siempre hara lo
+``correcto'' esté o no retrocediendo el conjunto de cambios punta
+(p.e.~no tratará de fusionar si está retrocediendo la punta, dado que
+no es necesario), usted debería usar \emph{siempre} esta opción cuando
+ejecuta la orden \hgcmd{backout}.
+
+\subsection{Más control sobre el proceso de retroceso}
+
+A pesar de que recomiendo usar siempre la opción 
+\hgopt{backout}{--merge} cuando está retrocediendo un cambio, la orden
+\hgcmd{backout} le permite decidir cómo mezclar un retroceso de un
+conjunto de cambios.  Es muy extraño que usted necestite tomar control
+del proceso de retroceso de forma manual, pero puede ser útil entender
+lo que la orden \hgcmd{backout} está haciendo automáticamente para
+usted. Para ilustrarlo, clonemos nuestro primer repositorio, pero
+omitamos el retroceso que contiene.
+
+\interaction{backout.manual.clone}
+Como en el ejemplo anterior, consignaremos un tercer cambio, después
+haremos retroceso de su padre, y veremos qué pasa.
+\interaction{backout.manual.backout} 
+Nuestro nuevo conjunto de cambios es de nuevo un descendiente del
+conjunto de cambio que retrocedimos; es por lo tanto una nueva cabeza,
+\emph{no} un descendiente del conjunto de cambios que era la punta. La
+orden \hgcmd{backout} fue muy explícita diciéndolo.
+\interaction{backout.manual.log}
+
+De nuevo, es más sencillo lo que pasó viendo una gráfica del
+historial de revisiones, en la figura~\ref{fig:undo:backout-manual}.
+Esto nos aclara que cuando usamos \hgcmd{backout} para retroceder un
+cambio a algo que no sea la punta, Mercurial añade una nueva cabeza al
+repositorio (el cambio que consignó está encerrado en una caja).
+
+\begin{figure}[htb]
+  \centering
+  \grafix{undo-manual}
+  \caption{Retroceso usando la orden \hgcmd{backout}}
+  \label{fig:undo:backout-manual}
+\end{figure}
+
+Después de que la orden \hgcmd{backout} ha terminado, deja un nuevo
+conjunto de cambios de ``retroceso'' como el padre del directorio de trabajo.
+\interaction{backout.manual.parents}
+Ahora tenemos dos conjuntos de cambios aislados.
+\interaction{backout.manual.heads}
+
+Reflexionemos acerca de lo que esperamos ver como contenidos de
+\filename{myfile}.  El primer cambio debería estar presente, porque
+nunca le hicimos retroceso.  El segundo cambio debió desaparecer,
+puesto que es el que retrocedimos.  Dado que la gráfica del historial
+muestra que el tercer camlio es una cabeza separada, \emph{no}
+esperamos ver el tercer cambio presente en \filename{myfile}.
+\interaction{backout.manual.cat}
+Para que el tercer cambio esté en el fichero, hacemos una fusión usual
+de las dos cabezas.
+\interaction{backout.manual.merge}
+Después de eso, el historial gráfica de nuestro repositorio luce como
+la figura~\ref{fig:undo:backout-manual-merge}.
+
+\begin{figure}[htb]
+  \centering
+  \grafix{undo-manual-merge}
+  \caption{Fusión manual de un retroceso}
+  \label{fig:undo:backout-manual-merge}
+\end{figure}
+
+\subsection{Por qué \hgcmd{backout} hace lo que hace}
+
+Esta es una descripción corta de cómo trabaja la orden \hgcmd{backout}.
+\begin{enumerate}
+\item Se asegura de que el directorio de trabajo es ``limpio'', esto
+  es, que la salida de \hgcmd{status} debería ser vacía.
+\item Recuerda el padre actual del directorio de trabajo. A este
+  conjunto de cambio lo llamaremos \texttt{orig}
+\item Hace el equivalente de un \hgcmd{update} para sincronizar el
+  directorio de trabajo con el conjunto de cambios que usted quiere
+  retroceder. Lo llamaremos \texttt{backout}
+\item Encuentra el padre del conjunto de cambios. Lo llamaremos
+  \texttt{parent}.
+\item Para cada fichero del conjunto de cambios que el
+  \texttt{retroceso} afecte, hará el equivalente a
+  \hgcmdargs{revert}{-r parent} sobre ese fichero, para restaurarlo a
+  los contenidos que tenía antes de que el conjunto de cambios fuera
+  consignado.
+\item Se consigna el resultado como un nuevo conjunto de cambios y
+  tiene a  \texttt{backout} como su padre.
+\item Si especifica \hgopt{backout}{--merge} en la línea de comandos,
+  se fusiona con \texttt{orig}, y se consigna el resultado de la
+  fusión.
+\end{enumerate}
+
+Una vía alternativa de implementar la orden \hgcmd{backout} sería usar
+\hgcmd{export} sobre el conjunto de cambios a retroceder como un diff
+y después usar laa opción \cmdopt{patch}{--reverse} de la orden
+\command{patch} para reversar el efecto del cambio sin molestar el
+directorio de trabajo.  Suena mucho más simple, pero no funcionaría
+bien ni de cerca.
+
+La razón por la cual \hgcmd{backout} hace una actualización, una
+consignación, una fusión y otra consignación es para dar a la
+maquinaria de fusión la mayor oportunidad de hacer un buen trabajo
+cuando se trata con todos los cambios \emph{entre} el cambio que está
+retrocediendo y la punta actual.
+
+Si está retrocediendo un conjunto de cambios que está a unas ~100
+atrás en su historial del proyecto, las posibilidades de que una orden
+\command{patch} sea capaz de ser aplicada a un diff reverso,
+claramente no son altas, porque los cambios que intervienen podrían
+``no coincidir con el contexto'' que \command{patch} usa  para
+determinar si puede aplicar un parche (si esto suena como cháchara,
+vea una discusión de la orden \command{patch} en \ref{sec:mq:patch}).
+Adicionalmente, la maquinaria de fusión de Mercurial manejará ficheros
+y directorios renombrados, cambios de permisos, y modificaciones a
+ficheros binarios, nada de lo cual la orden \command{patch} puede manejar.
+
+\section{Cambios que nunca debieron ocurrir}
+\label{sec:undo:aaaiiieee}
+
+En la mayoría de los casos, la orden \hgcmd{backout} es exactamente lo
+que necesita para deshacer los efectos de un cambio.  Deja un registro
+permanente y exacto de lo que usted hizo, cuando se consignó el
+conjunto de cambios original y cuando se hizo la limpieza.
+
+En ocasiones particulares, puede haber consignado un cambio que no
+debería estar de ninguna forma en el repositorio.  Por ejemplo, sería
+muy inusual, y considerado como una equivocación, consignar los
+ficheros objeto junto con el código fuente. Los ficheros objeto no
+tienen valor intrínseco y son \emph{grandes}, por lo tanto aumentan el
+tamaño del repositorio y la cantidad de tiempo que se emplea al clonar
+o jalar cambios.
+
+Antes de discutir las opciones que tiene si consignó cambio del tipo 
+``bolsa de papel deschable'' (el tipo que es tan malo que le gustaría
+colocarse una bolsa de papel desechable en su cabeza), permítame
+discutir primero unas aproximaciones que probablemente no funcionen.
+
+Dado que Mercurial trata de forma acumulativa al historial---cada
+cambio se coloca encima de todos los cambios que le
+preceden---usualmente usted no puede hacer que unos cambios desastrosos
+desaparezcan. La única excepción es cuando usted ha acabado de
+consignar un cambio y este no ha sido publicado o jalado en otro
+repositorio. Ahí es cuando puede usar la orden \hgcmd{rollback} con
+seguridad, como detallé en la sección~\ref{sec:undo:rollback}.
+
+Después de que usted haya publicado un cambio en otro repositorio, usted
+\emph{podría} usar la orden \hgcmd{rollback} para hacer que en su copia
+local desaparezca el cambio, pero no tendrá las consecuencias que
+desea. El cambio estará presente en un repositorio remoto, y
+reaparecerá en su repositorio local la próxima vez que jale
+
+Si una situación como esta se presenta, y usted sabe en qué
+repositorios su mal cambio se ha propagado, puede \emph{intentar}
+deshacerse del conjunto de cambios de \emph{todos} los repositorios en
+los que se pueda encontrar.  Esta por supuesto, no es una solución
+satisfactoria: si usted deja de hacerlo en un solo repositorio,
+mientras esté eliminándolo, el cambio todavía estará ``allí afuera'',
+y podría propagarse más tarde.
+
+Si ha consignado uno o más cambios \emph{después} del cambio que desea
+desaparecer, sus opciones son aún más reducidas. Mercurial no provee
+una forma de ``cabar un hueco'' en el historial, dejando los conjuntos
+de cambios intactos.
+
+%Dejamos de traducir lo que viene a continuación, porque será
+%modificado por upstream...
+
+XXX This needs filling out.  The \texttt{hg-replay} script in the
+\texttt{examples} directory works, but doesn't handle merge
+changesets.  Kind of an important omission.
+
+\subsection{Cómo protegerse de cambios que han ``escapado''}
+
+Si ha consignado cambios a su repositorio local y estos han sido
+publicados o jalados en cualquier otro sitio, no es necesariamente un
+desastre. Puede protegerse de antemano de ciertas clases de conjuntos
+de cambios malos. Esto es particularmente sencillo si su equipo de
+trabajo jala cambios de un repositorio central.
+
+Al configurar algunos ganchos en el repositorio central para validar
+conjuntos de cambios (ver capítulo~\ref{chap:hook}), puede prevenir la
+publicación automáticamente de cierta clase de cambios malos.  Con tal
+configuración, cierta clase de conjuntos de cambios malos tenderán
+naturalmente a``morir'' debido a que no pueden propagarse al
+repositorio central.  Esto sucederá sin necesidad de intervención
+explícita.
+
+Por ejemplo, un gancho de cambios de entrada que verifique que un
+conjunto de cambios compila, puede prevenir que la gente ``rompa 
+la compilación'' inadvertidamente.
+
+\section{Al encuentro de la fuente de un fallo}
+\label{sec:undo:bisect}
+
+Aunque es muy bueno poder retroceder el conjunto de cambios que
+originó un fallo, se requiere que usted sepa cual conjunto de cambios
+retroceder.  Mercurial brinda una orden invaluable, llamada
+\hgcmd{bisect}, que ayuda a automatizar este proceso y a alcanzarlo
+muy eficientemente.
+
+La idea tras la orden \hgcmd{bisect} es que el conjunto de cambios que
+ha introducido un cambio de comportamiento pueda identificarse con una
+prueba binaria sencilla. No tiene que saber qué pieza de código
+introdujo el cambio, pero si requiere que sepa cómo probar la
+existencia de un fallo. La orden \hgcmd{bisect} usa su prueba para
+dirigir su búsqueda del conjunto de cambios que introdujo el código
+causante del fallo.
+
+A continuación un conjunto de escenarios que puede ayudarle a entender
+cómo puede aplicar esta orden.
+\begin{itemize}
+\item La versión más reciente de su programa tiene un fallo que usted
+  recuerda no estaba hace unas semanas, pero no sabe cuándo fue
+  introducido. En este caso, su prueba binaria busca la presencia de
+  tal fallo.
+\item Usted arregló un fallo en un apurto, y es hora de dar por
+  cerrado el caso en la base de datos de fallos de su equipo de
+  trabajo.   La base de datos de fallos requiere el ID del conjunto de
+  cambios que permita dar por cerrado el caso, pero usted no recuerda
+  qué conjunto de cambios arregló tal fallo.  De nuevo la prueba
+  binaria revisa la presencia del fallo.
+\item Su programa funciona correctamente, pero  core ~15\% más lento
+  que la última vez que lo midió. Usted desea saber qué conjunto de
+  cambios introdujo esta disminución de desempeño.  En este caso su
+  prueba binaria mide el desempeño de su programa, para ver dónde es
+  ``rápido'' y dónde es ``lento''.
+\item Los tamaños de los componentes del proyecto que usted lleva se
+  expandieron recientemente, y sospecha que algo cambio en la forma en
+  que se construye su proyecto.
+\end{itemize}
+
+Para estos ejemplos debería ser claro que la orden \hgcmd{bisect}
+es útil no solamente para encontrar la fuente de los fallos. Puede
+usarla para encontrar cualquier ``propiedad emergente'' de un
+repositorio (Cualquier cosa que usted no pueda encontrar con una
+búsqueda de texto sencilla sobre los ficheros en el árbol) para la
+cual pueda escribir una prueba binaria.
+
+A continuación introduciremos algo terminología, para aclarar qué
+partes del proceso de búsqueda son su responsabilidad y cuáles de
+Mercurial.  Una \emph{prueba} es algo que \emph{usted} ejecuta cuando
+\hgcmd{bisect} elige un conjunto de cambios.  Un \emph{sondeo} es lo que
+\hgcmd{bisect} ejecuta para decidir si una revisión es buena.  Finalmente,
+usaremos la palabra ``biseccionar', en frases como ``buscar con la
+orden \hgcmd{bisect}''.
+
+Una forma sencilla de automatizar el proceso de búsqueda sería probar
+cada conjunto de cambios.  Lo cual escala muy poco. Si le tomó diez
+minutos hacer pruebas sobre un conjunto de cambios y tiene 10.000
+conjuntos de cambios en su repositorio, esta aproximación exhaustiva
+tomaría en promedio~35 \emph{días} para encontrar el conjunto de
+cambios que introdujo el fallo. Incluso si supiera que el fallo se
+introdujo en un de los últimos 500 conjuntos de cambios y limitara la
+búsqueda a ellos, estaría tomabdi más de 40 horas para encontrar al
+conjunto de cambios culpable.
+
+La orden \hgcmd{bisect} usa su conocimiento de la ``forma'' del
+historial de revisiones de su proyecto para hacer una búsqueda
+proporcional al \emph{logaritmo} del número de conjunto de cambios a
+revisar (el tipo de búsqueda que realiza se llama búsqueda
+binaria). Con esta aproximación, el buscar entre 10.000 conjuntos de
+cambios tomará menos de 3 horas, incluso a diez minutos por prueba (La
+búsqueda requerirá cerca de 14 pruebas). Al limitar la búsqueda a la
+última centena de conjuntos de cambios, tomará a lo sumo una
+hora (Apenas unas 7 pruebas).
+
+La orden \hgcmd{bisect} tiene en cuenta la naturaleza ``ramificada''
+del historial de revisiones del proyecto con Mercurial, así que no
+hay problemas al tratar con ramas, fusiones o cabezas múltiples en un
+repositorio.  Puede evitar ramas enteras de historial con un solo
+sondeo.
+
+\subsection{Uso de la orden \hgcmd{bisect}}
+
+A continuación un ejemplo de \hgcmd{bisect} en acción.
+
+\begin{note}
+  En las versiones 0.9.5 y anteriores de Mercurial, \hgcmd{bisect} no
+  era una orden incluída en la distribución principal: se ofrecía como
+  una extensión de Mercurial. Esta sección describe la orden embebida
+  y no la extensión anterior.
+\end{note}
+
+Creamos un repostorio para probar el comando \hgcmd{bisect} de forma
+aislada
+\interaction{bisect.init}
+Simularemos de forma sencilla un proyecto con un fallo: haremos
+cambios triviales en un ciclo, e indicaremos que un cambio específico
+sea el ``fallo''.  Este ciclo crea 35 conjuntos de cambios, cada uno
+añade un único fichero al repositorio. Representaremos nuestro ``fallo''
+con un fichero que contiene el texto ``tengo un gub''.
+\interaction{bisect.commits}
+
+A continuación observaremos cómo usar la orden \hgcmd{bisect}. Podemos
+usar el mecanismo de ayuda embebida que trae Mercurial.
+\interaction{bisect.help}
+
+La orden \hgcmd{bisect} trabaja en etapas, de la siguiente forma:
+\begin{enumerate}
+\item Usted ejecuta una prueba binaria.
+  \begin{itemize}
+  \item Si la prueba es exitosa, usted se lo indicará a \hgcmd{bisect}
+    ejecutando la orden \hgcmdargs{bisect}{good}.
+  \item Si falla, ejecutará la orden \hgcmdargs{bisect}{--bad}.
+  \end{itemize}
+\item La orden usa su información para decidir qué conjuntos de
+  cambios deben probarse a continuación.
+\item Actualiza el directorio de trabajo a tal conjunto de cambios y
+  el proceso se lleva a cabo de nuevo.
+\end{enumerate}
+El proceso termina cuando \hgcmd{bisect} identifica un único conjunto
+de cambios que marca el punto donde se encontró la transición de
+``exitoso'' a ``fallido''.
+
+Para comenzar la búsqueda, es indispensable ejecutar la orden
+\hgcmdargs{bisect}{--reset}.
+\interaction{bisect.search.init}
+
+En nuestro caso, la prueba binaria es sencilla: revisamos si el
+fichero en el repositorio contiene la cadena ``tengo un gub''.  Si la
+tiene, este conjunto de cambios contiene aquel que ``causó el fallo''.
+Por convención, un conjunto de cambios que tiene la propiedad que
+estamos buscando es ``malo'', mientras que el otro que no la tiene es
+``bueno''.
+
+En la mayoría de casos, la revisión del directorio actual (usualmente
+la punta) exhibe el problema introducido por el cambio con el fallo,
+por lo tanto la marcaremos como ``mala''.
+\interaction{bisect.search.bad-init}
+
+Nuestra próxima tarea es nominar al conjunto de cambios que sabemos
+\emph{no} tiene el fallo; la orden \hgcmd{bisect} ``acotará'' su
+búsqueda entre el primer par de conjuntos de cambios buenos y malos.
+En nuestro caso, sabemos que la revisión~10 no tenía el fallo.  (Más
+adelante diré un poco más acerca de la elección del conjunto de
+cambios ``bueno''.)
+\interaction{bisect.search.good-init}
+
+Note que esta orden mostró algo.
+\begin{itemize}
+\item Nos dijo cuántos conjuntos de cambios debe considerar antes de
+  que pueda identifica aquel que introdujo el fallo, y cuántas pruebas
+  se requerirán.
+\item Actualizó el directorio de trabajo al siguiente conjunto de
+  cambios, y nos dijo qué conjunto de cambios está evaluando.
+\end{itemize}
+
+Ahora ejecutamos nuestra prueba en el directorio de trabajo. Usamos la
+orden \command{grep} para ver si nuestro fichero ``malo'' está
+presente en el directorio de trabajo.  Si lo está, esta revisión es
+mala; si no esta revisión es buena.
+\interaction{bisect.search.step1}
+
+Esta prueba luce como candidata perfecta para automatizarse, por lo
+tanto la convertimos en una función de interfaz de comandos.
+\interaction{bisect.search.mytest}
+Ahora podemos ejecutar un paso entero de pruebas con un solo comando,
+\texttt{mytest}.
+\interaction{bisect.search.step2}
+Unas invocaciones más de nuestra prueba, y hemos terminado.
+\interaction{bisect.search.rest}
+
+Aunque teníamos unos~40 conjuntos de cambios en los cuales buscar, la
+orden \hgcmd{bisect} nos permitió encontrar el conjunto de cambios que
+introdujo el ``fallo'' con sólo cinco pruebas.  Porque el número de
+pruebas que la orden \hgcmd{bisect} ejecuta crece logarítmicamente con
+la cantidad de conjuntos de cambios a buscar, la ventaja que esto
+tiene frente a la  búsqueda por``fuerza bruta'' crece con cada
+conjunto de cambios que usted adicione.
+
+\subsection{Limpieza después de la búsqueda}
+
+Cuando haya terminado de usar la orden \hgcmd{bisect} en un
+repositorio, puede usar la orden \hgcmdargs{bisect}{reset} para
+deshacerse de la información que se estaba usando para lograr la
+búsqueda. Lar orden no usa mucho espacio, así que no hay problema si
+olvida ejecutar la orden.  En todo caso, \hgcmd{bisect} no le
+permitirá comenzar una nueva búsqueda sobre el repositorio hasta que
+no aplique \hgcmdargs{bisect}{reset}.
+\interaction{bisect.search.reset}
+
+\section{Consejos para encontrar fallos efectivamente}
+
+\subsection{Dar una entrada consistente}
+
+La orden \hgcmd{bisect} requiere que usted ofrezca un reporte correcto
+del resultado de cada prueba que aplique.  Si usted le dice que una
+prueba falla cuando en realidad era acertada, \emph{podría} detectar
+la inconsistencia. Si puede identificar una inconsistencia en sus
+reportes, le dirá que un conjunto de cambios particular es a la vez
+bueno y malo.  Aunque puede no hacerlo; estaría tratando de reportar
+un conjunto de cambios como el responsable de un fallo aunque no lo
+sea.
+
+\subsection{Automatizar tanto como se pueda}
+
+Cuando comencé a usar la orden \hgcmd{bisect}, intenté ejecutar
+algunas veces las pruebas a mano desde la línea de comandos. Es una
+aproximación a la cual no esta acostumbrado. Después de algunos
+intentos, me di cuenta que estaba cometiendo tantas equivocaciones que
+tenía que comenzar de nuevo con mis búsquedas varias veces antes de
+llegar a los resultados deseados.
+
+Mi problema inicial al dirigir a la orden \hgcmd{bisect} manualmente
+ocurrieron incluso con búsquedas en repositorios pequeños; si el
+problema que está buscando es más sutil, o el número de pruebas que
+\hgcmd{bisect} debe aplicar, la posibilidad de errar es mucho más
+alta. Una vez que comencé a automatizar mis pruebas, obtuve mejores
+resultados.
+
+La clave para las pruebas automatizadas se puede resumir en:
+\begin{itemize}
+\item pruebe siempre buscando el mismo síntoma y
+\item ofrezca siempre datos consistentes a la orden \hgcmd{bisect}.
+\end{itemize}
+En mi tutorial de ejemplo anterior, la orden \command{grep} busca el
+síntoma, y la construcción \texttt{if} toma el resultado de esta
+prueba y verifica que siempre alimentamos con los mismos datos a la
+orden \hgcmd{bisect}. La función \texttt{mytest} los une de una forma
+reproducible, logrando que cada prueba sea uniforme y consistente.
+
+\subsection{Verificar los resultados}
+
+Dado que la salida de la búsqueda de \hgcmd{bisect} es tan buena como
+los datos ofrecidos por usted, no confíe en esto como si fuera la
+verdad absoluta. Una forma sencilla de asegurarse es ejecutar
+manualmente su prueba a cada uno de los siguientes conjuntos de
+cambios:
+\begin{itemize}
+\item El conjunto de cambios que se reportó como la primera versión
+  erronea. Su prueba debería dar un reporte de fallo.
+\item El conjunto de cambios padre (cada padre, si es una fusión).
+  Su prueba debería reportar este(os) conjunto(s) de cambios como
+  bueno(s).
+\item Un hijo del conjunto de cambios. Su prueba debería reportar al
+  conjunto de cambios hijo como malo.
+\end{itemize}
+
+\subsection{Tener en cuenta la interferencia entre fallos}
+
+Es posible que su búsqueda de un fallo pueda viciarse por la presencia
+de otro. Por ejemplo, digamos que su programa se revienta en la
+revisión 100, y que funcionó correctamente en la revisión 50.  Sin su
+conocimiento, alguien introdujo un fallo con consecuencias grandes en
+la revisión 60, y lo arregló en la revisión 80. Sus resultados
+estarían distorcionados de una o muchas formas.
+
+Es posible que este fallo ``enmascare'' completamente al suyo, y que
+podría haberse revelado antes de que su propio fallo haya tenido
+oportunidad de manifestarse. Si no puede saltar el otro fallo (por
+ejemplo, este evita que su proyecto se arme o compile), y de esta
+forma no se pueda revisar si su fallo esté presente en un conjunto
+particular de cambios, la orden \hgcmd{bisect} no podrá ayudarle
+directamente. En cambio, puede marcar este conjunto de cambios como
+al ejecutar \hgcmdargs{bisect}{--skip}.
+
+Un problema distinto podría surgir si su prueba de la presencia de un
+fallo no es suficientemente específica. Si usted busca ``mi programa
+se revienta'', entonces tanto su fallo como el otro fallo sin relación
+que terminan presentando síntomas distintos, podría terminar
+confundiendo a \hgcmd{bisect}.
+
+Otra situación en la cual sería de mucha utilidad emplear a
+\hgcmdargs{bisect}{--skip} surge cuando usted no puede probar una
+revisión porque su proyecto estaba en una situación de rompimiento y
+por lo tanto en un estado en el cual era imposible hacer la prueba en
+esa revisión, tal vez porque alguien consignó un cambio que hacía
+imposible la construcción del proyecto.
+
+\subsection{Acotar la búsqueda perezosamente}
+
+Elegir los primeros ``buenos'' y ``malos'' conjuntos de cambios que
+marcarán los límites de su búsqueda en general es sencillo, pero vale
+la pena discutirlo.  Desde la perspectiva de \hgcmd{bisect}, el
+conjunto de cambios ``más nuevo'' por convención es el ``malo'', y el
+otro conjunto de cambios es el ``bueno''.
+
+Si no recuerda cuál podría ser el cambio ``bueno'', para informar a
+\hgcmd{bisect}, podría hacer pruebas aleatorias en el peor de los
+casos. Pero recuerde eliminar aquellos conjuntos de cambios que
+podrían no exhibir el fallo (tal vez porque la característica donde se
+presenta el fallo todavía no está presente) y aquellos en los cuales
+otro fallo puede enmascararlo (como se discutió anteriormente).
+
+Incluso si termina ``muy atrás'' por miles de conjuntos de cambios o
+meses de historial, solamente estaŕa adicionando unas pruebas contadas
+para \hgcmd{bisect}, gracias al comportamiento logarítmico.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/wdir-after-commit.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-after-commit.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs5973">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3128" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-6.0462,-0.664361)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6772"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,222.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="390.0539"
+     inkscape:cy="602.10507"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="11"
+     inkscape:window-y="8"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="245.98355"
+       x="328.23956"
+       height="258.57144"
+       width="174.28572"
+       id="rect6047"
+       style="fill:url(#linearGradient6216);fill-opacity:1;stroke:#686868;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6261"
+       transform="translate(234,0)">
+      <rect
+         y="258.7149"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect5983"
+         style="fill:#b1b1b1;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5985"
+         y="284.47562"
+         x="138.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="284.47562"
+           x="138.7962"
+           id="tspan5987"
+           sodipodi:role="line">dfbbb33f3fa3</tspan></text>
+    </g>
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect5996"
+       width="134.53746"
+       height="44.537449"
+       x="348.11371"
+       y="320.38159" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="372.7962"
+       y="346.1423"
+       id="text5998"><tspan
+         sodipodi:role="line"
+         id="tspan6000"
+         x="372.7962"
+         y="346.1423"
+         style="font-family:Courier">e7639888bb2f</tspan></text>
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6004"
+       width="134.53746"
+       height="44.537449"
+       x="348.11371"
+       y="382.04825" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="370.65421"
+       y="407.80896"
+       id="text6006"><tspan
+         sodipodi:role="line"
+         id="tspan6008"
+         x="370.65421"
+         y="407.80896"
+         style="font-family:Courier">7b064d8bac5e</tspan></text>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6018"
+       d="M 415.38242,303.62646 L 415.38242,320.00744"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <path
+       inkscape:connection-end="#rect6004"
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 415.38242,365.29315 L 415.38243,381.67412"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="348.11359"
+       y="443.71487" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="372.79706"
+       y="469.47556"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="372.79706"
+         y="469.47556"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 415.38238,426.95981 L 415.38235,443.34087"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="327.66046"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="327.66046"
+         y="231.36218">Historia en el repositorio</tspan></text>
+    <rect
+       y="245.94225"
+       x="557.28418"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(262.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">dfbbb33f3fa3</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(263.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="576.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="576.63208"
+         y="270.479">Primer padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="576.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="576.07544"
+         y="364.49615">Segundo padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="556.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="556.61743"
+         y="231.36218">Padres del directorio de trabajo</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 576.82542,297.63008 L 483.02528,287.95831"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#g6261" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="316.86407"
+       y="275.6496"
+       id="text6573"><tspan
+         sodipodi:role="line"
+         id="tspan6575"
+         x="316.86407"
+         y="275.6496"
+         style="text-align:end;text-anchor:end">Nuevo</tspan><tspan
+         sodipodi:role="line"
+         x="316.86407"
+         y="290.6496"
+         id="tspan6577"
+         style="text-align:end;text-anchor:end">conjunto</tspan><tspan
+         sodipodi:role="line"
+         x="316.86407"
+         y="305.6496"
+         style="text-align:end;text-anchor:end"
+         id="tspan3470">de</tspan><tspan
+         sodipodi:role="line"
+         x="316.86407"
+         y="320.6496"
+         style="text-align:end;text-anchor:end"
+         id="tspan3472">cambios</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/wdir-branch.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-branch.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs5973">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3193" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.90509668"
+     inkscape:cx="345.85973"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="75"
+     inkscape:window-y="69"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="246.06918"
+       x="64.325172"
+       height="204.26233"
+       width="333.2135"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g1935">
+      <rect
+         y="266.24374"
+         x="84.113708"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.00446"
+         x="108.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="108.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+    </g>
+    <g
+       id="g6976"
+       transform="translate(70,0)">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 160.92915,311.15532 L 167.83571,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g1935" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="110.11359"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="134.79706"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="134.79706"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 177.38238,372.82195 L 177.38235,389.20303"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       y="245.94225"
+       x="447.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(152.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">ffb20e1701ea</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(153.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="466.63208"
+         y="270.479">Primer padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="466.07544"
+         y="364.49615">Segundo padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="446.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="446.61743"
+         y="231.36218">Padres del directorio de trabajo</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82542,300.21999 L 377.00207,294.39744"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect1925" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <g
+       id="g2845">
+      <rect
+         y="266.24374"
+         x="242.09048"
+         height="44.537449"
+         width="134.53746"
+         id="rect1925"
+         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text1927"
+         y="292.00446"
+         x="266.77298"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="266.77298"
+           id="tspan1929"
+           sodipodi:role="line">ffb20e1701ea</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path1933"
+       d="M 260.89978,311.15532 L 225.84185,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="109.45568"
+       y="231.4554"
+       id="text2837"><tspan
+         sodipodi:role="line"
+         id="tspan2839"
+         x="109.45568"
+         y="231.4554">Cabeza Pre-existente</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="237.54184"
+       y="231.4554"
+       id="text2841"><tspan
+         sodipodi:role="line"
+         id="tspan2843"
+         x="237.54184"
+         y="231.4554">Cabeza recién creada (y tip)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 148.05048,235.87482 L 149.94915,265.86962"
+       id="path2850"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g1935" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 303.83495,238.08453 L 306.87874,265.86962"
+       id="path2852"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g2845" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/wdir-merge.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-merge.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs5973">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3259" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.911882,0,0,0.789965,-574.7896,51.22599)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,112.8399,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.28"
+     inkscape:cx="345.85973"
+     inkscape:cy="690.49342"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="338"
+     inkscape:window-y="50"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="246.06918"
+       x="64.325172"
+       height="204.26233"
+       width="333.2135"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.91925466;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6976"
+       transform="translate(70,0)">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 160.92915,311.15532 L 167.83571,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g1935" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="110.11359"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="134.79706"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="134.79706"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 177.38238,372.82195 L 177.38235,389.20303"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       y="245.94225"
+       x="447.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(152.3254,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">ffb20e1701ea</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(153.0396,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:black;fill-opacity:1;font-family:Courier">e7639888bb2f</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="466.63208"
+         y="270.479">Primer padre (sin cambio)</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="466.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="466.07544"
+         y="364.49615">Segundo padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="446.61743"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="446.61743"
+         y="231.36218">Padres del directorio de trabajo</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82542,300.21999 L 377.00207,294.39744"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect1925" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+    <g
+       id="g2845">
+      <rect
+         y="266.24374"
+         x="242.09048"
+         height="44.537449"
+         width="134.53746"
+         id="rect1925"
+         style="fill:#9f9f9f;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text1927"
+         y="292.00446"
+         x="266.77298"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="266.77298"
+           id="tspan1929"
+           sodipodi:role="line">ffb20e1701ea</tspan></text>
+    </g>
+    <path
+       inkscape:connector-type="polyline"
+       id="path1933"
+       d="M 260.89978,311.15532 L 225.84185,327.53627"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1;display:inline"
+       inkscape:connection-end="#g6976" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="109.45568"
+       y="231.4554"
+       id="text2837"><tspan
+         sodipodi:role="line"
+         id="tspan2839"
+         x="109.45568"
+         y="231.4554">Cabeza pre-existente</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="237.54184"
+       y="231.4554"
+       id="text2841"><tspan
+         sodipodi:role="line"
+         id="tspan2843"
+         x="237.54184"
+         y="231.4554">Cabeza recién creada(y tip)</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 148.05048,235.87482 L 149.94915,265.86962"
+       id="path2850"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g1935" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
+       d="M 303.83495,238.08453 L 306.87874,265.86962"
+       id="path2852"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g2845" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 466.82545,379.17944 L 219.0253,307.95488"
+       id="path3016"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6135"
+       inkscape:connection-end="#g1935" />
+    <g
+       id="g1935">
+      <rect
+         y="266.24374"
+         x="84.113708"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.00446"
+         x="108.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.00446"
+           x="108.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/wdir-pre-branch.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,373 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir-pre-branch.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs5973">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3314" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6974"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-314.246,50.85694)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6996"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-85.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.64"
+     inkscape:cx="235.37429"
+     inkscape:cy="726.21069"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="2"
+     inkscape:window-y="43"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       y="245.94225"
+       x="20.198257"
+       height="204.51619"
+       width="174.36833"
+       id="rect6047"
+       style="fill:url(#linearGradient6974);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <rect
+       style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect5996"
+       width="134.53746"
+       height="44.537449"
+       x="40.113693"
+       y="266.24374" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="64.796204"
+       y="292.00446"
+       id="text5998"><tspan
+         sodipodi:role="line"
+         id="tspan6000"
+         x="64.796204"
+         y="292.00446"
+         style="font-family:Courier">e7639888bb2f</tspan></text>
+    <g
+       id="g6976">
+      <rect
+         y="327.9104"
+         x="40.113693"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.67111"
+         x="62.654205"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.67111"
+           x="62.654205"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+    </g>
+    <path
+       inkscape:connection-end="#rect6004"
+       inkscape:connector-type="polyline"
+       id="path6020"
+       d="M 107.38242,311.15529 L 107.38242,327.53626"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <rect
+       style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect6039"
+       width="134.53746"
+       height="44.537449"
+       x="40.113571"
+       y="389.57703" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="64.797073"
+       y="415.33771"
+       id="text6041"><tspan
+         sodipodi:role="line"
+         id="tspan6043"
+         x="64.797073"
+         y="415.33771"
+         style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    <path
+       inkscape:connection-end="#rect6039"
+       inkscape:connector-type="polyline"
+       id="path6045"
+       d="M 107.38238,372.82195 L 107.38235,389.20301"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1" />
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="19.660461"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="19.660461"
+         y="231.36218">Historia en el repositorio</tspan></text>
+    <rect
+       y="245.94225"
+       x="249.28412"
+       height="204.51619"
+       width="174.36833"
+       id="rect6140"
+       style="fill:url(#linearGradient6996);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    <g
+       id="g6130"
+       transform="translate(-45.67459,24.38544)">
+      <rect
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6106"
+         width="134.53746"
+         height="44.537449"
+         x="314.87415"
+         y="257.95059" />
+      <text
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="339.55664"
+         y="283.7113"
+         id="text6108"><tspan
+           sodipodi:role="line"
+           id="tspan6110"
+           x="339.55664"
+           y="283.7113"
+           style="font-family:Courier">7b064d8bac5e</tspan></text>
+    </g>
+    <g
+       id="g6135"
+       transform="translate(-44.96042,49.83106)">
+      <rect
+         inkscape:transform-center-y="102.85714"
+         inkscape:transform-center-x="129.28571"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6112"
+         width="134.53746"
+         height="44.537449"
+         x="314.15985"
+         y="326.52203" />
+      <text
+         inkscape:transform-center-y="102.7311"
+         inkscape:transform-center-x="128.69672"
+         xml:space="preserve"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         x="338.84335"
+         y="352.28271"
+         id="text6114"><tspan
+           sodipodi:role="line"
+           id="tspan6116"
+           x="338.84335"
+           y="352.28271"
+           style="fill:#979797;fill-opacity:1;font-family:Courier">000000000000</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="268.63208"
+       y="270.479"
+       id="text6118"><tspan
+         sodipodi:role="line"
+         id="tspan6120"
+         x="268.63208"
+         y="270.479">Primer padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="268.07544"
+       y="364.49615"
+       id="text6122"><tspan
+         sodipodi:role="line"
+         id="tspan6124"
+         x="268.07544"
+         y="364.49615">Segundo padre</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="248.61746"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="248.61746"
+         y="231.36218">Padres del directorio de trabajo</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 268.82543,318.06163 L 175.02528,336.72225"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-end="#g6976"
+       inkscape:connection-start="#g6130" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/es/wdir.svg	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg5971"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docbase="/home/bos/hg/hgbook/en"
+   sodipodi:docname="wdir.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs5973">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective3368" />
+    <marker
+       inkscape:stockid="Arrow1Mstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mstart"
+       style="overflow:visible">
+      <path
+         id="path4855"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.4) translate(10,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient6049">
+      <stop
+         style="stop-color:#686868;stop-opacity:1;"
+         offset="0"
+         id="stop6051" />
+      <stop
+         style="stop-color:#f0f0f0;stop-opacity:1;"
+         offset="1"
+         id="stop6053" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow1Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Mend"
+       style="overflow:visible;">
+      <path
+         id="path4852"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.4) rotate(180) translate(10,0)" />
+    </marker>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6083"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6142"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-42.00893,-30.49544)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6193"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-240.0462,-8.633237e-6)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6216"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6232"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000473,0,0,0.790947,-11.16012,50.85693)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6049"
+       id="linearGradient6445"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000474,0,0,0.790947,-240.246,50.9948)"
+       x1="333.91171"
+       y1="488.79077"
+       x2="508.94543"
+       y2="263.79077" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.8101934"
+     inkscape:cx="301.66555"
+     inkscape:cy="721.33993"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="906"
+     inkscape:window-height="659"
+     inkscape:window-x="355"
+     inkscape:window-y="55"
+     showgrid="false">
+    <sodipodi:guide
+       orientation="vertical"
+       position="-1.4285714"
+       id="guide6022" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5976">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g6431"
+       transform="translate(0,-0.137863)">
+      <rect
+         style="fill:url(#linearGradient6445);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6047"
+         width="174.36833"
+         height="204.51619"
+         x="94.198257"
+         y="246.08011" />
+      <rect
+         y="266.38159"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect5996"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text5998"
+         y="292.1423"
+         x="138.7962"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="292.1423"
+           x="138.7962"
+           id="tspan6000"
+           sodipodi:role="line">e7639888bb2f</tspan></text>
+      <rect
+         y="328.04825"
+         x="114.11369"
+         height="44.537449"
+         width="134.53746"
+         id="rect6004"
+         style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6006"
+         y="353.80896"
+         x="136.65421"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="font-family:Courier"
+           y="353.80896"
+           x="136.65421"
+           id="tspan6008"
+           sodipodi:role="line">7b064d8bac5e</tspan></text>
+      <path
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         d="M 181.38242,311.29315 L 181.38242,327.67412"
+         id="path6020"
+         inkscape:connector-type="polyline"
+         inkscape:connection-end="#rect6004" />
+      <rect
+         y="389.71487"
+         x="114.11357"
+         height="44.537449"
+         width="134.53746"
+         id="rect6039"
+         style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <text
+         id="text6041"
+         y="415.47556"
+         x="138.79707"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           style="fill:#979797;fill-opacity:1;font-family:Courier"
+           y="415.47556"
+           x="138.79707"
+           id="tspan6043"
+           sodipodi:role="line">000000000000</tspan></text>
+      <path
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#686868;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-opacity:1"
+         d="M 181.38238,372.95981 L 181.38235,389.34087"
+         id="path6045"
+         inkscape:connector-type="polyline"
+         inkscape:connection-end="#rect6039" />
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="93.660484"
+       y="231.36218"
+       id="text6102"><tspan
+         sodipodi:role="line"
+         id="tspan6104"
+         x="93.660484"
+         y="231.36218">Historia en el repositorio</tspan></text>
+    <g
+       id="g6416">
+      <rect
+         style="fill:url(#linearGradient6232);fill-opacity:1;stroke:#686868;stroke-width:0.66539276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="rect6140"
+         width="174.36833"
+         height="204.51619"
+         x="323.28412"
+         y="245.94225" />
+      <g
+         transform="translate(28.32541,24.38544)"
+         id="g6130">
+        <rect
+           y="257.95059"
+           x="314.87415"
+           height="44.537449"
+           width="134.53746"
+           id="rect6106"
+           style="fill:#d4d4d4;fill-opacity:1;stroke:black;stroke-width:0.7482574;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.49651474, 0.74825737;stroke-dashoffset:0;stroke-opacity:1" />
+        <text
+           id="text6108"
+           y="283.7113"
+           x="339.55664"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           xml:space="preserve"><tspan
+             style="font-family:Courier"
+             y="283.7113"
+             x="339.55664"
+             id="tspan6110"
+             sodipodi:role="line">e7639888bb2f</tspan></text>
+      </g>
+      <g
+         transform="translate(29.03958,49.83106)"
+         id="g6135">
+        <rect
+           y="326.52203"
+           x="314.15985"
+           height="44.537449"
+           width="134.53746"
+           id="rect6112"
+           style="fill:#ededed;fill-opacity:1;stroke:#797979;stroke-width:0.74800003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           inkscape:transform-center-x="129.28571"
+           inkscape:transform-center-y="102.85714" />
+        <text
+           id="text6114"
+           y="352.28271"
+           x="338.84335"
+           style="font-size:12px;font-style:normal;font-weight:normal;fill:#979797;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+           xml:space="preserve"
+           inkscape:transform-center-x="128.69672"
+           inkscape:transform-center-y="102.7311"><tspan
+             style="fill:#979797;fill-opacity:1;font-family:Courier"
+             y="352.28271"
+             x="338.84335"
+             id="tspan6116"
+             sodipodi:role="line">000000000000</tspan></text>
+      </g>
+      <text
+         id="text6118"
+         y="270.479"
+         x="342.63208"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="270.479"
+           x="342.63208"
+           id="tspan6120"
+           sodipodi:role="line">Primer padre</tspan></text>
+      <text
+         id="text6122"
+         y="364.49615"
+         x="342.07544"
+         style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+         xml:space="preserve"><tspan
+           y="364.49615"
+           x="342.07544"
+           id="tspan6124"
+           sodipodi:role="line">Segundo padre</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman"
+       x="322.61746"
+       y="231.36218"
+       id="text6195"><tspan
+         sodipodi:role="line"
+         id="tspan6197"
+         x="322.61746"
+         y="231.36218">Padres del directorio de trabajo</tspan></text>
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+       d="M 342.82543,299.89384 L 249.02528,293.36123"
+       id="path6266"
+       inkscape:connector-type="polyline"
+       inkscape:connection-start="#g6130"
+       inkscape:connection-end="#rect5996" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="M 665.12232,418.17579 L 665.12232,418.17579"
+       id="path6270"
+       inkscape:connector-type="polyline" />
+  </g>
+</svg>
--- a/examples/hg-interdiff	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-#
-# Adapter for using interdiff with mercurial's extdiff extension.
-#
-# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
-#
-# This software may be used and distributed according to the terms of
-# the GNU General Public License, incorporated herein by reference.
-
-import os, sys
-
-def walk(base):
-    # yield all non-directories below the base path.
-    for root, dirs, files in os.walk(base):
-        for f in files:
-            path = os.path.join(root, f)
-            yield path[len(base)+1:], path
-    else:
-        if os.path.isfile(base):
-            yield '', base
-
-# create list of unique file names under both directories.
-files = dict(walk(sys.argv[1]))
-files.update(walk(sys.argv[2]))
-files = files.keys()
-files.sort()
-
-def name(base, f):
-    if f:
-        path = os.path.join(base, f)
-    else:
-        path = base
-    # interdiff requires two files; use /dev/null if one is missing.
-    if os.path.exists(path):
-        return path
-    return '/dev/null'
-
-ret = 0
-
-for f in files:
-    if os.system('interdiff "%s" "%s"' % (name(sys.argv[1], f),
-                                          name(sys.argv[2], f))):
-        ret = 1
-
-sys.exit(ret)
--- a/examples/hg-replay	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-#
-# Adapter for using interdiff with mercurial's extdiff extension.
-#
-# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com>
-#
-# This software may be used and distributed according to the terms of
-# the GNU General Public License, incorporated herein by reference.
-
-import os
-import shutil
-import sys
-import tempfile
-
-if len(sys.argv) < 4:
-    print >> sys.stderr, ('usage: %s srcrepo destrepo cset-to-omit [...]' %
-                          os.path.basename(sys.argv[0]))
-    sys.exit(1)
-
-srcrepo, destrepo = sys.argv[1], sys.argv[2]
-omit = sys.argv[3:]
-    
-changemap = {}
-revs = []
-
-parent = None
-
-sys.stdout.write('gathering history...')
-sys.stdout.flush()
-
-for line in os.popen("hg --cwd %r log -r0:tip --template '{rev}:{node} {parents}\n'" % srcrepo):
-    changes = line.split()
-    cset = changes[0].split(':')[1]
-    rev = len(revs)
-    changemap[cset] = rev
-    if len(changes) >= 2:
-        p1 = int(changes[1].split(':', 1)[0])
-    if len(changes) == 3:
-        p2 = int(changes[2].split(':', 1)[0])
-    else:
-        p2 = None
-    if len(changes) == 1:
-        p1 = parent
-    revs.append((cset, p1, p2))
-    parent = rev
-
-sys.stdout.write(' %d revs\n' % len(revs))
-
-def findrev(r):
-    try:
-        i = int(r)
-        if str(i) == r:
-            rev = i
-        if rev < 0:
-            rev += len(revs)
-        if rev < 0 or rev > len(revs):
-            print >> sys.stderr, 'bad changeset: %r' % r
-            sys.exit(1)
-        cset = revs[rev][0]
-    except ValueError:
-        cset = r
-        matches = [changemap[c] for c in changemap if c.startswith(cset)]
-        if len(matches) != 1:
-            print >> sys.stderr, 'bad changeset: %r' % r
-            sys.exit(1)
-        rev = matches[0]
-    return rev
-
-def run(cmd):
-    print cmd
-    ret = os.system(cmd)
-    if ret:
-        print >> sys.stderr, 'failure:', cmd
-        sys.exit(1)
-
-omit = map(findrev, omit)
-omit.sort()
-newrevs = revs[:omit[0]]
-tip = len(newrevs) - 1
-run('hg clone -q -r%s %r %r' % (tip, srcrepo, destrepo))
-    
-os.environ['HGMERGE'] = 'true'
-
-patchdir = tempfile.mkdtemp(prefix='replay.')
-try:
-    run('hg --cwd %r export --git -o %r%s%%R %d:tip' %
-        (srcrepo, patchdir, os.sep, omit[0]+1))
-    for rev in xrange(omit[0], len(revs)):
-        if rev in omit:
-            print 'omit', rev
-            newrevs.append((None, revs[rev][1], None))
-            continue
-        _, p1, p2 = revs[rev]
-        np1 = newrevs[p1][1]
-        if tip != np1:
-            run('hg --cwd %r update -q -C %s' % (destrepo, np1))
-        np2 = None
-        if p2:
-            np2 = newrevs[p2][1]
-            run('hg --cwd %r merge -q %s' % (destrepo, np2))
-            print >> sys.stderr, 'XXX - cannot handle merges properly yet'
-        run('hg --cwd %r import -q -f %r%s%d' % (destrepo, patchdir, os.sep, rev))
-        tip = len(newrevs) - 1
-        newrevs.append((None, tip, np2))
-finally:
-    print 'cleaning up ...'
-    #shutil.rmtree(patchdir)
Binary file htdocs/hgicon.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/index.en.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <link rel="icon" href="/hgicon.png" type="image/png">
+    <meta name="robots" content="index,follow">
+    <title>Distributed revision control with Mercurial</title>
+  </head>
+
+  <body>
+    <h1>Distributed revision control with Mercurial</h1>
+
+    <p>Welcome to the home of the book &ldquo;Distributed revision
+      control with Mercurial&rdquo;, by <a
+      href="http://www.serpentine.com/blog/">Bryan O'Sullivan</a>.
+      This is a <a href="hgbookap4.html">freely licensed</a> book
+      about the <a
+      href="http://www.selenic.com/mercurial">Mercurial</a> revision
+      control system.</p>
+
+    <ul>
+      <li>The <a href="hgbook.html">HTML version</a> is split into one
+	web page per chapter.</li>
+      <li>The <a href="hgbook.pdf">PDF version</a> is a single 1.3
+	megabyte file.</li>
+      <li>The <a href="http://hg.serpentine.com/mercurial/book">source
+	  code</a> is available to the adventurous.</li>
+    </ul>
+
+    <h2>How you can help Mercurial, and help free software</h2>
+
+    <p>Mercurial is a member of the <a
+	href="http://conservancy.softwarefreedom.org/">Software
+	Freedom Conservancy</a>, a wonderful non-profit
+      organisation that offers its member projects legal and
+      administrative advice.  The SFC can accept <a
+      href="http://conservancy.softwarefreedom.org/?donate">accept
+      donations</a> (tax-free under IRS 501(c)(3), within the United
+      States) on behalf of its member projects.  If you would like to
+      support Mercurial directly, please consider making a donation to
+      the SFC on its behalf.</p>
+
+    <p>If you would like to help free software developers to provide
+      their important public services without being impeded by legal
+      issues, please consider donating to the SFC's sister
+      organisation, the <a
+	href="http://www.softwarefreedom.org/">Software Freedom Law
+	Center</a>.</p>
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/index.es.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="es">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <link rel="icon" href="/hgicon.png" type="image/png">
+    <meta name="robots" content="index,follow">
+    <title>Control Distribuido de Revisiones con Mercurial</title>
+  </head>
+
+  <body>
+    <h1>Control Distribuido de Revisiones con Mercurial</h1>
+
+    <p>Bienvenido al sito del libro &ldquo;Control Distribuido de Revisiones con Mercurial&rdquo;, en español, 
+      por <a href="http://www.serpentine.com/blog/">Bryan O'Sullivan</a>.
+      Este libro está cobijado por una <a href="hgbookap4.html">licencia abierta</a>
+      y trata del sistema de control de revisiones
+      <a href="http://www.selenic.com/mercurial">Mercurial</a>.
+
+    <p>Los traductores son <a href="http://devnull.li/~jerojasro/blog/">Javier Rojas</a> e
+    <a href="http://igor.tamarapatino.org/">Igor Támara</a>. En este sitio usted puede encontrar:
+    <ul>
+      <li>La <a href="onepage.html">versi&oacute;n HTML</a> una sola página.</li>
+      <li>La <a href="hgbook.pdf">versi&oacute;n PDF</a> (1.9 megabytes.)</li>
+      <li>El <a href="http://mercurial.intuxication.org/hg/mercurial_book_es/">c&oacute;digo
+	fuente</a> de la traducci&oacute;n, si desea revisarla o colaborar con el proyecto. En 
+      <a href="http://hg.serpentine.com/mercurial/book">este sitio</a> puede
+      encontrar la versi&oacute;n original en ingl&eacute;s.</li>
+    </ul>
+    Para más detalles acerca del proceso de traducción, por favor vea <a
+        href="http://mercurial.intuxication.org/hg/mercurial_book_es/file/tip/es/Leame.1st">este
+        fichero</a>.
+
+    <h2>¿Cómo puede usted ayudar a Mercurial, y el software libre?</h2>
+
+    <p>Mercurial es miembro del <a
+	href="http://conservancy.softwarefreedom.org/">Conservatorio
+	de Software Libre</a>, una maravillosa organización sin ánimo
+      de lucro que ofrece a sus proyectos miembros consejo legal y
+      administrativo.  La SFC acepta <a href="http://conservancy.softwarefreedom.org/?donate">donaciones</a>
+      (deducibles de impuestos bajo IRS 501(c)(3), dentro de los Estados Unidos) 
+      en representación de sus proyectos miembros.  Si desea dar un apoyo
+      directo a Mercurial, por favor considere hacer una donación a SFC 
+      en su representación.</p>
+
+    <p>Si desea apoyar a los desarrolladores de software libre en su
+      importante servicio público sin estar impedido por cuestiones
+      legales, por favor considere donar a la organización hermana de
+      SFC, el <a
+	href="http://www.softwarefreedom.org/">Centro de Leyes de Software
+	Libre</a>.</p>
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/index.html.var	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,7 @@
+URI: index.en.html
+Content-Language: en
+Content-Type: text/html; charset=UTF-8
+
+URI: index.es.html
+Content-Language: es
+Content-Type: text/html; charset=UTF-8
Binary file html/hgicon.png has changed
--- a/html/index.en.html	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-    <link rel="icon" href="/hgicon.png" type="image/png">
-    <meta name="robots" content="index,follow">
-    <title>Distributed revision control with Mercurial</title>
-  </head>
-
-  <body>
-    <h1>Distributed revision control with Mercurial</h1>
-
-    <p>Welcome to the home of the book &ldquo;Distributed revision
-      control with Mercurial&rdquo;, by <a
-      href="http://www.serpentine.com/blog/">Bryan O'Sullivan</a>.
-      This is a <a href="hgbookap4.html">freely licensed</a> book
-      about the <a
-      href="http://www.selenic.com/mercurial">Mercurial</a> revision
-      control system.</p>
-
-    <ul>
-      <li>The <a href="hgbook.html">HTML version</a> is split into one
-	web page per chapter.</li>
-      <li>The <a href="hgbook.pdf">PDF version</a> is a single 1.3
-	megabyte file.</li>
-      <li>The <a href="http://hg.serpentine.com/mercurial/book">source
-	  code</a> is available to the adventurous.</li>
-    </ul>
-
-    <h2>How you can help Mercurial, and help free software</h2>
-
-    <p>Mercurial is a member of the <a
-	href="http://conservancy.softwarefreedom.org/">Software
-	Freedom Conservancy</a>, a wonderful non-profit
-      organisation that offers its member projects legal and
-      administrative advice.  The SFC can accept <a
-      href="http://conservancy.softwarefreedom.org/?donate">accept
-      donations</a> (tax-free under IRS 501(c)(3), within the United
-      States) on behalf of its member projects.  If you would like to
-      support Mercurial directly, please consider making a donation to
-      the SFC on its behalf.</p>
-
-    <p>If you would like to help free software developers to provide
-      their important public services without being impeded by legal
-      issues, please consider donating to the SFC's sister
-      organisation, the <a
-	href="http://www.softwarefreedom.org/">Software Freedom Law
-	Center</a>.</p>
-  </body>
-</html>
--- a/html/index.html.var	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-URI: index.en.html
-Content-Language: en
-Content-Type: text/html; charset=UTF-8
--- a/ja/Makefile	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/Makefile	Tue Apr 21 00:36:40 2009 +0900
@@ -1,64 +1,26 @@
 # 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 := $(wildcard figs/*.dot figs/*.gif figs/*.png figs/*.svg)
 
-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
+xml-src-files := \
+	00book.xml \
+	app*.xml \
+	ch*.xml
 
 image-dot := $(filter %.dot,$(image-sources))
 image-svg := $(filter %.svg,$(image-sources))
-image-png := $(filter %.png,$(image-sources))
+image-oth := $(filter %.gif %.png,$(image-sources))
+
+obj-web := html
+obj-websup := $(obj-web)/support
+obj-web-read := $(obj-web)/read
 
-image-pdf := $(image-dot:%.dot=%.pdf) $(image-svg:%.svg=%.pdf) $(image-png)
-image-html := $(image-dot:%.dot=%.png) $(image-svg:%.svg=%.png) $(image-png)
-#image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png)
-image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png:%.png=%.eps)
+image-web := \
+	$(image-dot:%.dot=$(obj-web-read)/%.png) \
+	$(image-svg:%.svg=$(obj-web-read)/%.png) \
+	$(image-oth:%=$(obj-web-read)/%)
 
-example-sources := \
+example-sources-by-name := \
 	backout \
 	bisect \
 	branching \
@@ -90,6 +52,49 @@
 	tour \
 	tour-merge-conflict
 
+example-sources := \
+	$(example-sources-by-name:%=examples/%) \
+	$(wildcard examples/ch*/*)
+
+extras-web-base := \
+	$(obj-web)/index.html \
+	$(obj-web)/robots.txt \
+	$(obj-websup)/form-min.js \
+	$(obj-websup)/form.js \
+	$(obj-websup)/hsbook.js \
+	$(obj-websup)/jquery-min.js \
+	$(obj-websup)/jquery.js \
+	$(obj-websup)/styles.css
+
+extras-web := $(extras-web-base) $(extras-web-base:%=%.gz)
+
+xsltproc := xsltproc
+xsltproc-opts := --nonet --xinclude --path '$(xml-path)'
+
+xmllint := xmllint
+xmllint-opts := --noout --nonet --valid
+
+system-xsl-dir := $(firstword $(wildcard \
+	/usr/share/sgml/docbook/xsl-stylesheets \
+	/usr/share/xml/docbook/stylesheet/nwalsh \
+	))
+
+# Bletcherousness.
+
+ifneq ($(wildcard /usr/share/sgml/docbook/xml-dtd-4.4-*),)
+dtd-dir := $(wildcard /usr/share/sgml/docbook/xml-dtd-4.4-*)
+else
+ifneq ($(wildcard /usr/share/xml/docbook/schema/dtd/4.4),)
+dtd-dir := $(wildcard /usr/share/xml/docbook/schema/dtd/4.4)
+else
+$(error Do not know where to look for DocBook XML 4.4 DTD)
+endif
+endif
+
+ifeq ($(system-xsl-dir),)
+$(error add a suitable directory to system-xsl-dir)
+endif
+
 example-prereqs := \
 	/usr/bin/merge
 
@@ -98,11 +103,6 @@
 	../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')
@@ -110,132 +110,111 @@
 hg-version = $(shell hg version -q | \
 		     sed 's,.*(version \(unknown\|[a-f0-9+]*\)),\1,')
 
-all: dvi
-
-#dvi: $(sources) $(image-eps) examples
-dvi: $(sources) $(image-eps)
-	platex 00book.tex
+all: web complete.xml
 
-	cp 00book.aux hgbook.aux
-	bibtex hgbook
+../stylesheets/system-xsl: $(system-xsl-dir)
+	ln -s $< $@
 
-	platex 00book.tex
-	platex 00book.tex
-	platex 00book.tex
+web: ../stylesheets/system-xsl websup html
 
-
-
-
+html: $(obj-web-read)/index.html
 
-
-pdf: pdf/hgbook.pdf
-
-define pdf
-	mkdir -p $(dir $@)
-	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+../web/index-read.html.in: ../web/genindex.py $(xml-src-files)
+	cd ../web && ./genindex.py
 
-	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
+$(obj-web-read)/index.html: ../stylesheets/system-xsl .validated-00book.xml ../web/index-read.html.in
+	xsltproc $(xsltproc-opts) -o $(obj-web-read)/x ../stylesheets/chunk-stylesheet.xsl 00book.xml
+	python ../web/texpand.py ../web/index-read.html.in html/read/index.html
+	for i in $(obj-web-read)/*.html; do \
+	  gzip -9 -c $$i > $$i.gz; \
+	done
 
-#pdf/hgbook.pdf: $(sources) $(image-pdf) examples
-pdf/hgbook.pdf: $(sources) $(image-pdf)
-	$(call pdf)
-
-html: onepage split
-
-onepage: $(htlatex) html/onepage/hgbook.html html/onepage/hgbook.css $(image-html:%=html/onepage/%)
+websup: $(extras-web) $(image-web)
+	mkdir -p $(obj-websup)/figs $(obj-web-read)/figs
+	cp ../stylesheets/system-xsl/images/*.png $(obj-websup)/figs
+	cp -f ../web/icons/*.png $(obj-websup)/figs
 
-html/onepage/%: %
-	cp $< $@
-
-split: $(htlatex) html/split/hgbook.html html/split/hgbook.css $(image-html:%=html/split/%)
-
-html/split/%: %
-	cp $< $@
+complete.xml: .validated-00book.xml
+	$(xsltproc) $(xsltproc-opts) -o $@ ../stylesheets/dtd-profile.xsl 00book.xml
 
-# 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.
+all-ids.dat: ../stylesheets/all-ids.xsl $(xml-src-files)
+	$(xsltproc) $(xsltproc-opts) -o $@ ../stylesheets/all-ids.xsl 00book.xml
+
+web: websup
 
-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
+valid: .validated-00book.xml
 
-#html/onepage/hgbook.html: $(sources) $(image-html) examples bookhtml.cfg
-html/onepage/hgbook.html: $(sources) $(image-html) bookhtml.cfg
-	$(call htlatex,$@,$<)
-
-#html/split/hgbook.html: $(sources) examples bookhtml.cfg
-html/split/hgbook.html: $(sources) bookhtml.cfg
-	$(call htlatex,$@,$<,2)
+.validated-00book.xml: $(xml-src-files) examples/.run
+	$(xmllint) --path '$(dtd-dir):$(xml-path)' $(xmllint-opts) $<
+	touch $@
 
 # Produce 90dpi PNGs for the web.
 
-%.png: %.svg
-	inkscape -D -e $@ $<
-
-%.svg: %.dot
-	dot -Tsvg -o $@ $<
-
-# Produce eps & pdf for the pdf
+$(obj-web-read)/figs/%.png: $(obj-web-read)/figs/%.svg fixsvg
+	mkdir -p $(dir $@)
+	./fixsvg $<
+	inkscape -D -e $@ $<-tmp.svg
+	rm $<-tmp.svg
 
-%.pdf: %.eps
-	epstopdf $<
-
-%.eps: %.svg
-	inkscape -E $@ $<
+$(obj-web-read)/figs/%.png: figs/%.svg fixsvg
+	mkdir -p $(dir $@)
+	./fixsvg $<
+	inkscape -D -e $@ $<-tmp.svg
+	rm $<-tmp.svg
 
-%.eps: %.dot
-	dot -Tps -o $@ $<
+$(obj-web-read)/figs/%.gif: figs/%.gif
+	cp $< $@
 
-%.eps: %.png
-	convert $< ps:$@
+$(obj-web-read)/figs/%.png: figs/%.png
+	cp $< $@
+
+$(obj-web-read)/figs/%.svg: figs/%.dot
+	mkdir -p $(dir $@)
+	dot -Tsvg -o $@ $<
 
 examples: $(example-prereqs) examples/.run
 
-examples/.run: $(example-sources:%=examples/%.run)
-	touch examples/.run
+examples/.run: $(example-sources)
+	cd examples && ./run-example -a
 
 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
+	-rm -rf dist html $(image-dot:%.dot=%.pdf) $(image-dot:%.dot=%.png) \
+	  $(image-svg:%.svg=%.png) examples/*.{lxo,run} examples/.run
 
-install: pdf split $(dist-sources)
+install: html $(dist-sources)
 	rm -rf dist
 	mkdir -p dist
-	cp pdf/hgbook.pdf dist
-	cp html/split/*.{css,html,png} dist
+	cp html/*.{css,html,png} dist
 	cp $(dist-sources) dist
 
+rsync: install
+	rsync -avz --delete dist sp.red-bean.com:public_html/hgbook
+
+vpath %.css ../web
+vpath %.html.in ../web
+vpath %.js ../web/javascript
+
+$(obj-websup)/%.css: %.css
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-websup)/%.jpg: %.jpg
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-websup)/%.js: %.js
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-web)/%: ../web/%
+	@mkdir -p $(dir $@)
+	cp $< $@
+
+$(obj-web)/%.html: %.html.in
+	@mkdir -p $(dir $@)
+	python ../web/texpand.py $< $@
+
+%.gz: %
+	gzip -9 -c $< > $@
--- a/ja/Makefile.orig	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/Makefile.orig	Tue Apr 21 00:36:40 2009 +0900
@@ -55,6 +55,8 @@
 
 image-pdf := $(image-dot:%.dot=%.pdf) $(image-svg:%.svg=%.pdf) $(image-png)
 image-html := $(image-dot:%.dot=%.png) $(image-svg:%.svg=%.png) $(image-png)
+#image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png)
+image-eps := $(image-dot:%.dot=%.eps) $(image-svg:%.svg=%.eps) $(image-png:%.png=%.eps)
 
 example-sources := \
 	backout \
@@ -108,22 +110,42 @@
 hg-version = $(shell hg version -q | \
 		     sed 's,.*(version \(unknown\|[a-f0-9+]*\)),\1,')
 
-all: pdf html
+all: dvi
+
+#dvi: $(sources) $(image-eps) examples
+dvi: $(sources) $(image-eps)
+	platex 00book.tex
+
+	cp 00book.aux hgbook.aux
+	bibtex hgbook
+
+	platex 00book.tex
+	platex 00book.tex
+	platex 00book.tex
+
+
+
+
+
 
 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) $(image-pdf) examples
+#pdf/hgbook.pdf: $(sources) $(image-pdf) examples
+pdf/hgbook.pdf: $(sources) $(image-pdf)
 	$(call pdf)
 
 html: onepage split
@@ -153,10 +175,12 @@
 	rm $(dir $(1))/hgbook.css
 endef
 
-html/onepage/hgbook.html: $(sources) $(image-html) examples bookhtml.cfg
+#html/onepage/hgbook.html: $(sources) $(image-html) examples bookhtml.cfg
+html/onepage/hgbook.html: $(sources) $(image-html) bookhtml.cfg
 	$(call htlatex,$@,$<)
 
-html/split/hgbook.html: $(sources) examples bookhtml.cfg
+#html/split/hgbook.html: $(sources) examples bookhtml.cfg
+html/split/hgbook.html: $(sources) bookhtml.cfg
 	$(call htlatex,$@,$<,2)
 
 # Produce 90dpi PNGs for the web.
@@ -178,6 +202,9 @@
 %.eps: %.dot
 	dot -Tps -o $@ $<
 
+%.eps: %.png
+	convert $< ps:$@
+
 examples: $(example-prereqs) examples/.run
 
 examples/.run: $(example-sources:%=examples/%.run)
@@ -212,5 +239,3 @@
 	cp html/split/*.{css,html,png} dist
 	cp $(dist-sources) dist
 
-rsync: install
-	rsync -avz --delete dist sp.red-bean.com:public_html/hgbook
--- a/ja/examples/bisect	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/bisect	Tue Apr 21 00:36:40 2009 +0900
@@ -1,7 +1,11 @@
 #!/bin/bash
 
-#echo '[extensions]' >> $HGRC
-#echo 'hbisect =' >> $HGRC
+if  hg -v | head -1 | grep -e "version 0.*"
+then
+#On mercurial 1.0 and later bisect is a builtin
+echo '[extensions]' >> $HGRC
+echo 'hbisect =' >> $HGRC
+fi
 
 # XXX There's some kind of horrible nondeterminism in the execution of
 # bisect at the moment.  Ugh.
@@ -33,15 +37,15 @@
 
 #$ name: search.init
 
-hg bisect --reset
+hg bisect init
 
 #$ name: search.bad-init
 
-hg bisect --bad
+hg bisect bad
 
 #$ name: search.good-init
 
-hg bisect --good 10
+hg bisect good 10
 
 #$ name: search.step1
 
@@ -66,7 +70,7 @@
   fi
 
   echo this revision is $result
-  hg bisect --$result
+  hg bisect $result
 }
 
 #$ name: search.step2
@@ -81,7 +85,7 @@
 
 #$ name: search.reset
 
-hg bisect --reset
+hg bisect reset
 
 #$ name:
 
--- a/ja/examples/branch-named	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/branch-named	Tue Apr 21 00:36:40 2009 +0900
@@ -64,11 +64,10 @@
 #$ name: update-bar
 
 hg update bar
-hg update -C bar
 
 #$ name: merge
 
 hg branch
-hg merge
+hg merge foo
 hg commit -m 'Merge'
 hg tip
--- a/ja/examples/daily.files	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/daily.files	Tue Apr 21 00:36:40 2009 +0900
@@ -4,9 +4,9 @@
 
 hg init add-example
 cd add-example
-echo a > a
+echo a > myfile.txt
 hg status
-hg add a
+hg add myfile.txt
 hg status
 hg commit -m 'Added one file'
 hg status
@@ -14,10 +14,10 @@
 #$ name: add-dir
 
 mkdir b
-echo b > b/b
-echo c > b/c
+echo b > b/somefile.txt
+echo c > b/source.cpp
 mkdir b/d
-echo d > b/d/d
+echo d > b/d/test.h
 hg add b
 hg commit -m 'Added all files in subdirectory'
 
--- a/ja/examples/rename.divergent	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/rename.divergent	Tue Apr 21 00:36:40 2009 +0900
@@ -14,7 +14,7 @@
 #$ name: rename.anne
 
 cd anne
-hg mv foo bar
+hg rename foo bar
 hg ci -m 'Rename foo to bar'
 
 #$ name: rename.bob
--- a/ja/examples/run-example	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/run-example	Tue Apr 21 00:36:40 2009 +0900
@@ -7,6 +7,7 @@
 import cStringIO
 import errno
 import getopt
+import glob
 import os
 import pty
 import re
@@ -18,23 +19,23 @@
 import tempfile
 import time
 
-tex_subs = {
-    '\\': '\\textbackslash{}',
-    '{': '\\{',
-    '}': '\\}',
+xml_subs = {
+    '<': '&lt;',
+    '>': '&gt;',
+    '&': '&amp;',
     }
 
 def gensubs(s):
     start = 0
     for i, c in enumerate(s):
-        sub = tex_subs.get(c)
+        sub = xml_subs.get(c)
         if sub:
             yield s[start:i]
             start = i + 1
             yield sub
     yield s[start:]
 
-def tex_escape(s):
+def xml_escape(s):
     return ''.join(gensubs(s))
         
 def maybe_unlink(name):
@@ -53,7 +54,92 @@
             return p
     return None
         
+def result_name(name):
+    return os.path.normpath(os.path.join('results', name.replace(os.sep, '-')))
+
+def wopen(name):
+    path = os.path.dirname(name)
+    if path:
+        try:
+            os.makedirs(path)
+        except OSError, err:
+            if err.errno != errno.EEXIST:
+                raise
+    return open(name, 'w')
+
 class example:
+    entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml'))
+
+    def __init__(self, name, verbose, keep_change):
+        self.name = os.path.normpath(name)
+        self.verbose = verbose
+        self.keep_change = keep_change
+        
+    def status(self, s):
+        sys.stdout.write(s)
+        if not s.endswith('\n'):
+            sys.stdout.flush()
+
+    def rename_output(self, base, ignore=[]):
+        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
+        def mangle(s):
+            return mangle_re.sub('', s)
+        def matchfp(fp1, fp2):
+            while True:
+                s1 = mangle(fp1.readline())
+                s2 = mangle(fp2.readline())
+                if cmp(s1, s2):
+                    break
+                if not s1:
+                    return True
+            return False
+
+        oldname = result_name(base + '.out')
+        tmpname = result_name(base + '.tmp')
+        errname = result_name(base + '.err')
+        errfp = open(errname, 'w+')
+        for line in open(tmpname):
+            errfp.write(mangle_re.sub('', line))
+        os.rename(tmpname, result_name(base + '.lxo'))
+        errfp.seek(0)
+        try:
+            oldfp = open(oldname)
+        except IOError, err:
+            if err.errno != errno.ENOENT:
+                raise
+            os.rename(errname, oldname)
+            return False
+        if matchfp(oldfp, errfp):
+            os.unlink(errname)
+            return False
+        else:
+            print >> sys.stderr, '\nOutput of %s has changed!' % base
+            if self.keep_change:
+                os.rename(errname, oldname)
+                return False
+            else:
+                os.system('diff -u %s %s 1>&2' % (oldname, errname))
+            return True
+
+class static_example(example):
+    def run(self):
+        self.status('running %s\n' % self.name)
+        s = open(self.name).read().rstrip()
+        s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
+        ofp = wopen(result_name(self.name + '.tmp'))
+        ofp.write('<!-- BEGIN %s -->\n' % self.name)
+        ofp.write('<programlisting>')
+        ofp.write(s)
+        ofp.write('</programlisting>\n')
+        ofp.write('<!-- END %s -->\n' % self.name)
+        ofp.close()
+        self.rename_output(self.name)
+        norm = self.name.replace(os.sep, '-')
+        example.entities[
+            '<!ENTITY %s SYSTEM "results/%s.lxo">' % (norm, norm)] = 1
+
+
+class shell_example(example):
     shell = '/usr/bin/env bash'
     ps1 = '__run_example_ps1__ '
     ps2 = '__run_example_ps2__ '
@@ -61,9 +147,8 @@
     
     timeout = 10
 
-    def __init__(self, name, verbose):
-        self.name = name
-        self.verbose = verbose
+    def __init__(self, name, verbose, keep_change):
+        example.__init__(self, name, verbose, keep_change)
         self.poll = select.poll()
 
     def parse(self):
@@ -76,11 +161,6 @@
                 yield cfp.getvalue()
                 cfp.seek(0)
                 cfp.truncate()
-        
-    def status(self, s):
-        sys.stdout.write(s)
-        if not s.endswith('\n'):
-            sys.stdout.flush()
 
     def send(self, s):
         if self.verbose:
@@ -146,12 +226,12 @@
         maybe_unlink(self.name + '.run')
 
         rcfile = os.path.join(tmpdir, '.hgrc')
-        rcfp = open(rcfile, 'w')
+        rcfp = wopen(rcfile)
         print >> rcfp, '[ui]'
         print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>"
         
         rcfile = os.path.join(tmpdir, '.bashrc')
-        rcfp = open(rcfile, 'w')
+        rcfp = wopen(rcfile)
         print >> rcfp, 'PS1="%s"' % self.ps1
         print >> rcfp, 'PS2="%s"' % self.ps2
         print >> rcfp, 'unset HISTFILE'
@@ -230,12 +310,22 @@
                                 return 1
                             assert os.sep not in out
                             if ofp is not None:
+                                ofp.write('</screen>\n')
+                                ofp.write('<!-- END %s -->\n' % ofp_basename)
                                 ofp.close()
                                 err |= self.rename_output(ofp_basename, ignore)
                             if out:
                                 ofp_basename = '%s.%s' % (self.name, out)
+                                norm = os.path.normpath(ofp_basename)
+                                norm = norm.replace(os.sep, '-')
+                                example.entities[
+                                    '<!ENTITY interaction.%s '
+                                    'SYSTEM "results/%s.lxo">'
+                                    % (norm, norm)] = 1
                                 read_hint = ofp_basename + ' '
-                                ofp = open(ofp_basename + '.tmp', 'w')
+                                ofp = wopen(result_name(ofp_basename + '.tmp'))
+                                ofp.write('<!-- BEGIN %s -->\n' % ofp_basename)
+                                ofp.write('<screen>')
                             else:
                                 ofp = None
                         elif pi == 'ignore':
@@ -248,14 +338,15 @@
                         # first, print the command we ran
                         if not hunk.startswith('#'):
                             nl = hunk.endswith('\n')
-                            hunk = ('%s \\textbf{%s}' %
+                            hunk = ('<prompt>%s</prompt> '
+                                    '<userinput>%s</userinput>' %
                                     (prompts[ps],
-                                     tex_escape(hunk.rstrip('\n'))))
+                                     xml_escape(hunk.rstrip('\n'))))
                             if nl: hunk += '\n'
                         ofp.write(hunk)
                         # then its output
-                        ofp.write(tex_escape(output))
-                    ps = newps
+                        ofp.write(xml_escape(output))
+                        ps = newps
                 self.status('\n')
             except:
                 print >> sys.stderr, '(killed)'
@@ -267,6 +358,8 @@
                     ps, output = self.sendreceive('exit\n', read_hint)
                     if ofp is not None:
                         ofp.write(output)
+                        ofp.write('</screen>\n')
+                        ofp.write('<!-- END %s -->\n' % ofp_basename)
                         ofp.close()
                         err |= self.rename_output(ofp_basename, ignore)
                     os.close(self.cfd)
@@ -281,69 +374,40 @@
                     elif os.WIFSIGNALED(rc):
                         print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
                 else:
-                    open(self.name + '.run', 'w')
-#                return err
-                return 0
+                    wopen(result_name(self.name + '.run'))
+                return err
         finally:
             shutil.rmtree(tmpdir)
 
-    def rename_output(self, base, ignore):
-        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
-        def mangle(s):
-            return mangle_re.sub('', s)
-        def matchfp(fp1, fp2):
-            while True:
-                s1 = mangle(fp1.readline())
-                s2 = mangle(fp2.readline())
-                if cmp(s1, s2):
-                    break
-                if not s1:
-                    return True
-            return False
-
-        oldname = base + '.out'
-        tmpname = base + '.tmp'
-        errname = base + '.err'
-        errfp = open(errname, 'w+')
-        for line in open(tmpname):
-            errfp.write(mangle_re.sub('', line))
-        os.rename(tmpname, base + '.lxo')
-        errfp.seek(0)
-        try:
-            oldfp = open(oldname)
-        except IOError, err:
-            if err.errno != errno.ENOENT:
-                raise
-            os.rename(errname, oldname)
-            return False
-        if matchfp(oldfp, errfp):
-            os.unlink(errname)
-            return False
-        else:
-            print >> sys.stderr, '\nOutput of %s has changed!' % base
-            os.system('diff -u %s %s 1>&2' % (oldname, errname))
-            return True
-
 def print_help(exit, msg=None):
     if msg:
         print >> sys.stderr, 'Error:', msg
     print >> sys.stderr, 'Usage: run-example [options] [test...]'
     print >> sys.stderr, 'Options:'
-    print >> sys.stderr, '  -a --all       run all tests in this directory'
+    print >> sys.stderr, '  -a --all       run all examples in this directory'
     print >> sys.stderr, '  -h --help      print this help message'
+    print >> sys.stderr, '     --keep      keep new output as desired output'
     print >> sys.stderr, '  -v --verbose   display extra debug output'
     sys.exit(exit)
 
 def main(path='.'):
+    if os.path.realpath(path).split(os.sep)[-1] != 'examples':
+        print >> sys.stderr, 'Not being run from the examples directory!'
+        sys.exit(1)
+
     opts, args = getopt.getopt(sys.argv[1:], '?ahv',
-                               ['all', 'help', 'verbose'])
+                               ['all', 'help', 'keep', 'verbose'])
     verbose = False
     run_all = False
+    keep_change = False
+
     for o, a in opts:
         if o in ('-h', '-?', '--help'):
             print_help(0)
         if o in ('-a', '--all'):
             run_all = True
+        if o in ('--keep',):
+            keep_change = True
         if o in ('-v', '--verbose'):
             verbose = True
     errs = 0
@@ -355,19 +419,20 @@
                 print >> sys.stderr, '%s: %s' % (a, err.strerror)
                 errs += 1
                 continue
-            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
-                if example(a, verbose).run():
-                    errs += 1
+            if stat.S_ISREG(st.st_mode):
+                if st.st_mode & 0111:
+                    if shell_example(a, verbose, keep_change).run():
+                        errs += 1
+                elif a.endswith('.lst'):
+                    static_example(a, verbose, keep_change).run()
             else:
                 print >> sys.stderr, '%s: not a file, or not executable' % a
                 errs += 1
     elif run_all:
-        names = os.listdir(path)
+        names = glob.glob("*") + glob.glob("app*/*") + glob.glob("ch*/*")
         names.sort()
         for name in names:
-            if name == 'run-example' or name.startswith('.'): continue
-            if name.endswith('.out') or name.endswith('~'): continue
-            if name.endswith('.run'): continue
+            if name == 'run-example' or name.endswith('~'): continue
             pathname = os.path.join(path, name)
             try:
                 st = os.lstat(pathname)
@@ -376,12 +441,20 @@
                 if err.errno != errno.ENOENT:
                     raise
                 continue
-            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
-                if example(pathname, verbose).run():
-                    errs += 1
-        print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
+            if stat.S_ISREG(st.st_mode):
+                if st.st_mode & 0111:
+                    if shell_example(pathname, verbose, keep_change).run():
+                        errs += 1
+                elif pathname.endswith('.lst'):
+                    static_example(pathname, verbose, keep_change).run()
+        print >> wopen(os.path.join(path, '.run')), time.asctime()
     else:
         print_help(1, msg='no test names given, and --all not provided')
+
+    fp = wopen('auto-snippets.xml')
+    for key in sorted(example.entities.iterkeys()):
+        print >> fp, key
+    fp.close()
     return errs
 
 if __name__ == '__main__':
--- a/ja/examples/template.svnstyle	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/template.svnstyle	Tue Apr 21 00:36:40 2009 +0900
@@ -34,6 +34,7 @@
 hg log -r0 --template '{node}'
 
 #$ name: simplest
+#$ ignore: \d+-\d+-\d+ \d+:\d+ \+.*
 
 cat svn.style
 hg log -r1 --style svn.style
--- a/ja/examples/tour	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/tour	Tue Apr 21 00:36:40 2009 +0900
@@ -31,7 +31,7 @@
 #$ name: log-r
 
 hg log -r 3
-hg log -r ff5d7b70a2a9
+hg log -r 0272e0d5a517
 hg log -r 1 -r 4
 
 #$ name: log.range
@@ -52,10 +52,17 @@
 hg clone hello my-hello
 cd my-hello
 
-#$ name: sed
+#$ name: cat1
+cat hello.c
+
+#$ name:
 
 sed -i '/printf/a\\tprintf("hello again!\\n");' hello.c
 
+#$ name: cat2
+# ... edit edit edit ...
+cat hello.c
+
 #$ name: status
 
 ls
@@ -73,6 +80,10 @@
 
 hg commit
 
+#$ name: merge.dummy1
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-hello
+
 #$ name: tip
 
 hg tip -vp
@@ -135,14 +146,23 @@
 
 hg push http://hg.serpentine.com/tutorial/hello
 
+#$ name:
+cp hello.c ../new-hello.c
+sed -i '/printf/i\\tprintf("once more, hello.\\n");' ../new-hello.c
+
 #$ name: merge.clone
 
 cd ..
 hg clone hello my-new-hello
 cd my-new-hello
-sed -i '/printf/i\\tprintf("once more, hello.\\n");' hello.c
+# The file new-hello.c is lightly edited.
+cp ../new-hello.c hello.c
 hg commit -m 'A new hello for a new day.'
 
+#$ name: merge.dummy2
+
+hg log -r 5 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV5.my-new-hello
+
 #$ name: merge.cat
 
 cat hello.c
@@ -152,6 +172,10 @@
 
 hg pull ../my-hello
 
+#$ name: merge.dummy3
+
+hg log -r 6 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV6.my-new-hello
+
 #$ name: merge.heads
 
 hg heads
@@ -173,6 +197,10 @@
 
 hg commit -m 'Merged changes'
 
+#$ name: merge.dummy4
+
+hg log -r 7 | grep changeset | cut -c 16-19 2>/dev/null > /tmp/REV7.my-new-hello
+
 #$ name: merge.tip
 
 hg tip
--- a/ja/examples/tour-merge-conflict	Mon Apr 20 23:50:34 2009 +0900
+++ b/ja/examples/tour-merge-conflict	Tue Apr 21 00:36:40 2009 +0900
@@ -68,5 +68,6 @@
 Nigerian dictator Sani Abacha.
 EOF
 
+hg resolve -m letter.txt
 hg commit -m 'Send me your money'
 hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/po/zh.po	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,16376 @@
+#
+# Simplified Chinese translation for hgbook
+# This file is distributed under the same license as the hgbook.
+#
+# Authors:
+# Dongsheng Song <dongsheng.song@gmail.com>, 2009
+#
+# Check translation:
+#    msgfmt --statistics -c -o zh.mo zh.po
+#
+# Please format your translation before commit:
+#    msgcat --sort-by-file --width=80 -o zh_new.po zh.po
+#    mv -f zh_new.po zh.po
+#
+# Dictionary:
+# blame             追溯
+# branch            分支
+# changes           修改
+# changeset         修改集
+# checkout          检出
+# remove            移除(从版本库删除)
+# delete            删除(只从文件系统删除)
+# filelog           文件日志
+# patchset          补丁集
+# pushing to        推到
+# pulling from      拉自,抓取
+# rename            改名
+# repository        版本库
+# revert            恢复
+# revision          版本
+# revlog            版本日志
+# tag               标签
+# tip               顶点
+# undo              撤销
+# unversioned       未版本控制
+# updated           更新到,同步到(适用于旧版本)
+# versioned         受版本控制
+# working copy      工作副本
+# ...
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: hgbook 1.2\n"
+"POT-Creation-Date: 2009-04-05 11:48+0800\n"
+"PO-Revision-Date: 2009-04-05 12:10+0800\n"
+"Last-Translator: 宋冬生 <songdonogsheng@live.cn>\n"
+"Language-Team: Simplified Chinese <i18n-zh@googlegroups.com >\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-Country: CHINA\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#. type: Content of: <book><title>
+#: ../en/00book.xml:41
+msgid "Mercurial: The Definitive Guide"
+msgstr "Mercurial 权威指南"
+
+#. type: Content of: <book><subtitle>
+#: ../en/00book.xml:46
+msgid "Compiled from $rev_id$"
+msgstr "编译自 $rev_id$"
+
+#. type: Content of: <book><bookinfo>
+#: ../en/00book.xml:48
+msgid "<edition>1</edition> <isbn>9780596800673</isbn>"
+msgstr "<edition>1</edition> <isbn>9780596800673</isbn>"
+
+#. type: Content of: <book><bookinfo><authorgroup><author><firstname>
+#: ../en/00book.xml:52
+msgid "Bryan"
+msgstr "Bryan"
+
+#. type: Content of: <book><bookinfo><authorgroup><author><surname>
+#: ../en/00book.xml:53
+msgid "O'Sullivan"
+msgstr "O'Sullivan"
+
+#. type: Content of: <book><bookinfo>
+#: ../en/00book.xml:57
+msgid ""
+"<editor> <firstname>Mike</firstname> <surname>Loukides</surname> </editor> "
+"<copyright> <year>2006</year> <year>2007</year> <year>2008</year> <year>2009</"
+"year> <holder>Bryan O'Sullivan</holder> </copyright>"
+msgstr ""
+"<editor> <firstname>Mike</firstname> <surname>Loukides</surname> </editor> "
+"<copyright> <year>2006</year> <year>2007</year> <year>2008</year> <year>2009</"
+"year> <holder>Bryan O'Sullivan</holder> </copyright>"
+
+#. type: Content of: <book><appendix><title>
+#: ../en/appB-mq-ref.xml:5
+msgid "Mercurial Queues reference"
+msgstr "Mercurial 队列参考"
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appB-mq-ref.xml:8
+msgid "MQ command reference"
+msgstr "MQ 命令参考"
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appB-mq-ref.xml:10
+msgid ""
+"For an overview of the commands provided by MQ, use the command <command role="
+"\"hg-cmd\">hg help mq</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:14
+msgid ""
+"<command role=\"hg-ext-mq\">qapplied</command>&emdash;print applied patches"
+msgstr "<command role=\"hg-ext-mq\">qapplied</command>—显示已应用的补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:17
+msgid ""
+"The <command role=\"hg-ext-mq\">qapplied</command> command prints the current "
+"stack of applied patches.  Patches are printed in oldest-to-newest order, so "
+"the last patch in the list is the <quote>top</quote> patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:24
+msgid ""
+"<command role=\"hg-ext-mq\">qcommit</command>&emdash;commit changes in the "
+"queue repository"
+msgstr "<command role=\"hg-ext-mq\">qcommit</command>—提交队列中的修改"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:27
+msgid ""
+"The <command role=\"hg-ext-mq\">qcommit</command> command commits any "
+"outstanding changes in the <filename role=\"special\" class=\"directory\">.hg/"
+"patches</filename> repository.  This command only works if the <filename role="
+"\"special\" class=\"directory\">.hg/patches</filename> directory is a "
+"repository, i.e. you created the directory using <command role=\"hg-cmd\">hg "
+"qinit <option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option></command> or ran "
+"<command role=\"hg-cmd\">hg init</command> in the directory after running "
+"<command role=\"hg-ext-mq\">qinit</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:39
+msgid ""
+"This command is shorthand for <command role=\"hg-cmd\">hg commit --cwd .hg/"
+"patches</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:43
+msgid ""
+"<command role=\"hg-ext-mq\">qdelete</command>&emdash;delete a patch from the "
+"<filename role=\"special\">series</filename> file"
+msgstr ""
+"<command role=\"hg-ext-mq\">qdelete</command>—从文件 <filename role=\"special"
+"\">series</filename> 中删除补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:48
+msgid ""
+"The <command role=\"hg-ext-mq\">qdelete</command> command removes the entry "
+"for a patch from the <filename role=\"special\">series</filename> file in the "
+"<filename role=\"special\" class=\"directory\">.hg/patches</filename> "
+"directory.  It does not pop the patch if the patch is already applied.  By "
+"default, it does not delete the patch file; use the <option role=\"hg-ext-mq-"
+"cmd-qdel-opt\">-f</option> option to do that."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:57 ../en/appB-mq-ref.xml:99 ../en/appB-mq-ref.xml:157
+#: ../en/appB-mq-ref.xml:197 ../en/appB-mq-ref.xml:264
+#: ../en/appB-mq-ref.xml:335 ../en/appB-mq-ref.xml:404
+#: ../en/appB-mq-ref.xml:497
+msgid "Options:"
+msgstr "选项:"
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:59
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qdel-opt\">-f</option>: Delete the patch file."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:66
+msgid ""
+"<command role=\"hg-ext-mq\">qdiff</command>&emdash;print a diff of the "
+"topmost applied patch"
+msgstr "<command role=\"hg-ext-mq\">qdiff</command>—显示最新应用补丁的差异"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:69
+msgid ""
+"The <command role=\"hg-ext-mq\">qdiff</command> command prints a diff of the "
+"topmost applied patch. It is equivalent to <command role=\"hg-cmd\">hg diff -"
+"r-2:-1</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:75
+msgid ""
+"<command role=\"hg-ext-mq\">qfold</command>&emdash;merge (<quote>fold</"
+"quote>) several patches into one"
+msgstr ""
+"<command role=\"hg-ext-mq\">qfold</command>—将多个补丁合并(<quote>折叠</"
+"quote>)成一个"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:78
+msgid ""
+"The <command role=\"hg-ext-mq\">qfold</command> command merges multiple "
+"patches into the topmost applied patch, so that the topmost applied patch "
+"makes the union of all of the changes in the patches in question."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:83
+msgid ""
+"The patches to fold must not be applied; <command role=\"hg-ext-mq\">qfold</"
+"command> will exit with an error if any is.  The order in which patches are "
+"folded is significant; <command role=\"hg-cmd\">hg qfold a b</command> means "
+"<quote>apply the current topmost patch, followed by <literal>a</literal>, "
+"followed by <literal>b</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:91
+msgid ""
+"The comments from the folded patches are appended to the comments of the "
+"destination patch, with each block of comments separated by three asterisk "
+"(<quote><literal>*</literal></quote>) characters.  Use the <option role=\"hg-"
+"ext-mq-cmd-qfold-opt\">-e</option> option to edit the commit message for the "
+"combined patch/changeset after the folding has completed."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:101
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qfold-opt\">-e</option>: Edit the commit message "
+"and patch description for the newly folded patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:106
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qfold-opt\">-l</option>: Use the contents of the "
+"given file as the new commit message and patch description for the folded "
+"patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:111
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qfold-opt\">-m</option>: Use the given text as "
+"the new commit message and patch description for the folded patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:119
+msgid ""
+"<command role=\"hg-ext-mq\">qheader</command>&emdash;display the header/"
+"description of a patch"
+msgstr "<command role=\"hg-ext-mq\">qheader</command>—显示补丁头部描述"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:123
+msgid ""
+"The <command role=\"hg-ext-mq\">qheader</command> command prints the header, "
+"or description, of a patch.  By default, it prints the header of the topmost "
+"applied patch. Given an argument, it prints the header of the named patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:130
+msgid ""
+"<command role=\"hg-ext-mq\">qimport</command>&emdash;import a third-party "
+"patch into the queue"
+msgstr "<command role=\"hg-ext-mq\">qimport</command>—将第三方补丁导入队列"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:133
+msgid ""
+"The <command role=\"hg-ext-mq\">qimport</command> command adds an entry for "
+"an external patch to the <filename role=\"special\">series</filename> file, "
+"and copies the patch into the <filename role=\"special\" class=\"directory\">."
+"hg/patches</filename> directory.  It adds the entry immediately after the "
+"topmost applied patch, but does not push the patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:141
+msgid ""
+"If the <filename role=\"special\" class=\"directory\">.hg/patches</filename> "
+"directory is a repository, <command role=\"hg-ext-mq\">qimport</command> "
+"automatically does an <command role=\"hg-cmd\">hg add</command> of the "
+"imported patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:149
+msgid ""
+"<command role=\"hg-ext-mq\">qinit</command>&emdash;prepare a repository to "
+"work with MQ"
+msgstr "<command role=\"hg-ext-mq\">qinit</command>—为使用 MQ 配置版本库"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:152
+msgid ""
+"The <command role=\"hg-ext-mq\">qinit</command> command prepares a repository "
+"to work with MQ.  It creates a directory called <filename role=\"special\" "
+"class=\"directory\">.hg/patches</filename>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:159
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option>: Create <filename role="
+"\"special\" class=\"directory\">.hg/patches</filename> as a repository in its "
+"own right.  Also creates a <filename role=\"special\">.hgignore</filename> "
+"file that will ignore the <filename role=\"special\">status</filename> file."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:169
+msgid ""
+"When the <filename role=\"special\" class=\"directory\">.hg/patches</"
+"filename> directory is a repository, the <command role=\"hg-ext-mq\">qimport</"
+"command> and <command role=\"hg-ext-mq\">qnew</command> commands "
+"automatically <command role=\"hg-cmd\">hg add</command> new patches."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:178
+msgid "<command role=\"hg-ext-mq\">qnew</command>&emdash;create a new patch"
+msgstr "<command role=\"hg-ext-mq\">qnew</command>—创建新补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:181
+msgid ""
+"The <command role=\"hg-ext-mq\">qnew</command> command creates a new patch.  "
+"It takes one mandatory argument, the name to use for the patch file.  The "
+"newly created patch is created empty by default.  It is added to the "
+"<filename role=\"special\">series</filename> file after the current topmost "
+"applied patch, and is immediately pushed on top of that patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:189
+msgid ""
+"If <command role=\"hg-ext-mq\">qnew</command> finds modified files in the "
+"working directory, it will refuse to create a new patch unless the <option "
+"role=\"hg-ext-mq-cmd-qnew-opt\">-f</option> option is used (see below).  This "
+"behaviour allows you to <command role=\"hg-ext-mq\">qrefresh</command> your "
+"topmost applied patch before you apply a new patch on top of it."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:199
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qnew-opt\">-f</option>: Create a new patch if "
+"the contents of the working directory are modified.  Any outstanding "
+"modifications are added to the newly created patch, so after this command "
+"completes, the working directory will no longer be modified."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:206
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qnew-opt\">-m</option>: Use the given text as "
+"the commit message. This text will be stored at the beginning of the patch "
+"file, before the patch data."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:215
+msgid ""
+"<command role=\"hg-ext-mq\">qnext</command>&emdash;print the name of the next "
+"patch"
+msgstr "<command role=\"hg-ext-mq\">qnext</command>—显示下个补丁的名称"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:218
+msgid ""
+"The <command role=\"hg-ext-mq\">qnext</command> command prints the name name "
+"of the next patch in the <filename role=\"special\">series</filename> file "
+"after the topmost applied patch.  This patch will become the topmost applied "
+"patch if you run <command role=\"hg-ext-mq\">qpush</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:227
+msgid ""
+"<command role=\"hg-ext-mq\">qpop</command>&emdash;pop patches off the stack"
+msgstr "<command role=\"hg-ext-mq\">qpop</command>—删除堆栈顶部的补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:230
+msgid ""
+"The <command role=\"hg-ext-mq\">qpop</command> command removes applied "
+"patches from the top of the stack of applied patches.  By default, it removes "
+"only one patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:234
+msgid ""
+"This command removes the changesets that represent the popped patches from "
+"the repository, and updates the working directory to undo the effects of the "
+"patches."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:238
+msgid ""
+"This command takes an optional argument, which it uses as the name or index "
+"of the patch to pop to.  If given a name, it will pop patches until the named "
+"patch is the topmost applied patch.  If given a number, <command role=\"hg-"
+"ext-mq\">qpop</command> treats the number as an index into the entries in the "
+"series file, counting from zero (empty lines and lines containing only "
+"comments do not count).  It pops patches until the patch identified by the "
+"given index is the topmost applied patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:248
+msgid ""
+"The <command role=\"hg-ext-mq\">qpop</command> command does not read or write "
+"patches or the <filename role=\"special\">series</filename> file.  It is thus "
+"safe to <command role=\"hg-ext-mq\">qpop</command> a patch that you have "
+"removed from the <filename role=\"special\">series</filename> file, or a "
+"patch that you have renamed or deleted entirely.  In the latter two cases, "
+"use the name of the patch as it was when you applied it."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:257
+msgid ""
+"By default, the <command role=\"hg-ext-mq\">qpop</command> command will not "
+"pop any patches if the working directory has been modified.  You can override "
+"this behaviour using the <option role=\"hg-ext-mq-cmd-qpop-opt\">-f</option> "
+"option, which reverts all modifications in the working directory."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:266
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpop-opt\">-a</option>: Pop all applied "
+"patches.  This returns the repository to its state before you applied any "
+"patches."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:271
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpop-opt\">-f</option>: Forcibly revert any "
+"modifications to the working directory when popping."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:276
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpop-opt\">-n</option>: Pop a patch from the "
+"named queue."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:281
+msgid ""
+"The <command role=\"hg-ext-mq\">qpop</command> command removes one line from "
+"the end of the <filename role=\"special\">status</filename> file for each "
+"patch that it pops."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:288
+msgid ""
+"<command role=\"hg-ext-mq\">qprev</command>&emdash;print the name of the "
+"previous patch"
+msgstr "<command role=\"hg-ext-mq\">qprev</command>—显示上个补丁的名称"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:291
+msgid ""
+"The <command role=\"hg-ext-mq\">qprev</command> command prints the name of "
+"the patch in the <filename role=\"special\">series</filename> file that comes "
+"before the topmost applied patch. This will become the topmost applied patch "
+"if you run <command role=\"hg-ext-mq\">qpop</command>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:300
+msgid ""
+"<command role=\"hg-ext-mq\">qpush</command>&emdash;push patches onto the stack"
+msgstr "<command role=\"hg-ext-mq\">qpush</command>—增加补丁到堆栈"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:303
+msgid ""
+"The <command role=\"hg-ext-mq\">qpush</command> command adds patches onto the "
+"applied stack.  By default, it adds only one patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:307
+msgid ""
+"This command creates a new changeset to represent each applied patch, and "
+"updates the working directory to apply the effects of the patches."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:311
+msgid "The default data used when creating a changeset are as follows:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:314
+msgid ""
+"The commit date and time zone are the current date and time zone.  Because "
+"these data are used to compute the identity of a changeset, this means that "
+"if you <command role=\"hg-ext-mq\">qpop</command> a patch and <command role="
+"\"hg-ext-mq\">qpush</command> it again, the changeset that you push will have "
+"a different identity than the changeset you popped."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:322
+msgid ""
+"The author is the same as the default used by the <command role=\"hg-cmd\">hg "
+"commit</command> command."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:326
+msgid ""
+"The commit message is any text from the patch file that comes before the "
+"first diff header.  If there is no such text, a default commit message is "
+"used that identifies the name of the patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:331
+msgid ""
+"If a patch contains a Mercurial patch header (XXX add link), the information "
+"in the patch header overrides these defaults."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:337
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">-a</option>: Push all unapplied "
+"patches from the <filename role=\"special\">series</filename> file until "
+"there are none left to push."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:343
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">-l</option>: Add the name of the "
+"patch to the end of the commit message."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:347
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">-m</option>: If a patch fails to "
+"apply cleanly, use the entry for the patch in another saved queue to compute "
+"the parameters for a three-way merge, and perform a three-way merge using the "
+"normal Mercurial merge machinery.  Use the resolution of the merge as the new "
+"patch content."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:355
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">-n</option>: Use the named queue if "
+"merging while pushing."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:360
+msgid ""
+"The <command role=\"hg-ext-mq\">qpush</command> command reads, but does not "
+"modify, the <filename role=\"special\">series</filename> file.  It appends "
+"one line to the <command role=\"hg-cmd\">hg status</command> file for each "
+"patch that it pushes."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:368
+msgid ""
+"<command role=\"hg-ext-mq\">qrefresh</command>&emdash;update the topmost "
+"applied patch"
+msgstr "<command role=\"hg-ext-mq\">qrefresh</command>—更新最新的补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:372
+msgid ""
+"The <command role=\"hg-ext-mq\">qrefresh</command> command updates the "
+"topmost applied patch.  It modifies the patch, removes the old changeset that "
+"represented the patch, and creates a new changeset to represent the modified "
+"patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:378
+msgid ""
+"The <command role=\"hg-ext-mq\">qrefresh</command> command looks for the "
+"following modifications:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:381
+msgid ""
+"Changes to the commit message, i.e. the text before the first diff header in "
+"the patch file, are reflected in the new changeset that represents the patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:386
+msgid ""
+"Modifications to tracked files in the working directory are added to the "
+"patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:389
+msgid ""
+"Changes to the files tracked using <command role=\"hg-cmd\">hg add</command>, "
+"<command role=\"hg-cmd\">hg copy</command>, <command role=\"hg-cmd\">hg "
+"remove</command>, or <command role=\"hg-cmd\">hg rename</command>.  Added "
+"files and copy and rename destinations are added to the patch, while removed "
+"files and rename sources are removed."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:398
+msgid ""
+"Even if <command role=\"hg-ext-mq\">qrefresh</command> detects no changes, it "
+"still recreates the changeset that represents the patch.  This causes the "
+"identity of the changeset to differ from the previous changeset that "
+"identified the patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:406
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-e</option>: Modify the commit "
+"and patch description, using the preferred text editor."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:411
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-m</option>: Modify the commit "
+"message and patch description, using the given text."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:416
+msgid ""
+"<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-l</option>: Modify the commit "
+"message and patch description, using text from the given file."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:424
+msgid "<command role=\"hg-ext-mq\">qrename</command>&emdash;rename a patch"
+msgstr "<command role=\"hg-ext-mq\">qrename</command>—改名补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:427
+msgid ""
+"The <command role=\"hg-ext-mq\">qrename</command> command renames a patch, "
+"and changes the entry for the patch in the <filename role=\"special\">series</"
+"filename> file."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:431
+msgid ""
+"With a single argument, <command role=\"hg-ext-mq\">qrename</command> renames "
+"the topmost applied patch.  With two arguments, it renames its first argument "
+"to its second."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:438
+msgid ""
+"<command role=\"hg-ext-mq\">qrestore</command>&emdash;restore saved queue "
+"state"
+msgstr "<command role=\"hg-ext-mq\">qrestore</command>—恢复保存的队列"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:442
+msgid "XXX No idea what this does."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:446
+msgid ""
+"<command role=\"hg-ext-mq\">qsave</command>&emdash;save current queue state"
+msgstr "<command role=\"hg-ext-mq\">qsave</command>—保存当前的队列状态"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:449
+msgid "XXX Likewise."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:453
+msgid ""
+"<command role=\"hg-ext-mq\">qseries</command>&emdash;print the entire patch "
+"series"
+msgstr "<command role=\"hg-ext-mq\">qseries</command>—显示补丁序列"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:456
+msgid ""
+"The <command role=\"hg-ext-mq\">qseries</command> command prints the entire "
+"patch series from the <filename role=\"special\">series</filename> file.  It "
+"prints only patch names, not empty lines or comments.  It prints in order "
+"from first to be applied to last."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:464
+msgid ""
+"<command role=\"hg-ext-mq\">qtop</command>&emdash;print the name of the "
+"current patch"
+msgstr "<command role=\"hg-ext-mq\">qtop</command>—显示当前补丁的名称"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:467
+msgid ""
+"The <command role=\"hg-ext-mq\">qtop</command> prints the name of the topmost "
+"currently applied patch."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:472
+msgid ""
+"<command role=\"hg-ext-mq\">qunapplied</command>&emdash;print patches not yet "
+"applied"
+msgstr "<command role=\"hg-ext-mq\">qunapplied</command>—显示尚未应用的补丁"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:476
+msgid ""
+"The <command role=\"hg-ext-mq\">qunapplied</command> command prints the names "
+"of patches from the <filename role=\"special\">series</filename> file that "
+"are not yet applied.  It prints them in order from the next patch that will "
+"be pushed to the last."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:484
+msgid ""
+"<command role=\"hg-cmd\">hg strip</command>&emdash;remove a revision and "
+"descendants"
+msgstr "<command role=\"hg-cmd\">hg strip</command>—删除一个版本及其后继"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:487
+msgid ""
+"The <command role=\"hg-cmd\">hg strip</command> command removes a revision, "
+"and all of its descendants, from the repository.  It undoes the effects of "
+"the removed revisions from the repository, and updates the working directory "
+"to the first parent of the removed revision."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:493
+msgid ""
+"The <command role=\"hg-cmd\">hg strip</command> command saves a backup of the "
+"removed changesets in a bundle, so that they can be reapplied if removed in "
+"error."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:499
+msgid ""
+"<option role=\"hg-opt-strip\">-b</option>: Save unrelated changesets that are "
+"intermixed with the stripped changesets in the backup bundle."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:503
+msgid ""
+"<option role=\"hg-opt-strip\">-f</option>: If a branch has multiple heads, "
+"remove all heads. XXX This should be renamed, and use <literal>-f</literal> "
+"to strip revs when there are pending changes."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/appB-mq-ref.xml:508
+msgid "<option role=\"hg-opt-strip\">-n</option>: Do not save a backup bundle."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appB-mq-ref.xml:515
+msgid "MQ file reference"
+msgstr "MQ 文件参考"
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:518
+msgid "The <filename role=\"special\">series</filename> file"
+msgstr "<filename role=\"special\">序列</filename>文件"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:521
+msgid ""
+"The <filename role=\"special\">series</filename> file contains a list of the "
+"names of all patches that MQ can apply.  It is represented as a list of "
+"names, with one name saved per line.  Leading and trailing white space in "
+"each line are ignored."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:527
+msgid ""
+"Lines may contain comments.  A comment begins with the <quote><literal>#</"
+"literal></quote> character, and extends to the end of the line.  Empty lines, "
+"and lines that contain only comments, are ignored."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:532
+msgid ""
+"You will often need to edit the <filename role=\"special\">series</filename> "
+"file by hand, hence the support for comments and empty lines noted above.  "
+"For example, you can comment out a patch temporarily, and <command role=\"hg-"
+"ext-mq\">qpush</command> will skip over that patch when applying patches.  "
+"You can also change the order in which patches are applied by reordering "
+"their entries in the <filename role=\"special\">series</filename> file."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:541
+msgid ""
+"Placing the <filename role=\"special\">series</filename> file under revision "
+"control is also supported; it is a good idea to place all of the patches that "
+"it refers to under revision control, as well.  If you create a patch "
+"directory using the <option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option> "
+"option to <command role=\"hg-ext-mq\">qinit</command>, this will be done for "
+"you automatically."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><sect2><title>
+#: ../en/appB-mq-ref.xml:551
+msgid "The <filename role=\"special\">status</filename> file"
+msgstr "<filename role=\"special\">状态</filename>文件"
+
+#. type: Content of: <book><appendix><sect1><sect2><para>
+#: ../en/appB-mq-ref.xml:554
+msgid ""
+"The <filename role=\"special\">status</filename> file contains the names and "
+"changeset hashes of all patches that MQ currently has applied.  Unlike the "
+"<filename role=\"special\">series</filename> file, this file is not intended "
+"for editing.  You should not place this file under revision control, or "
+"modify it in any way.  It is used by MQ strictly for internal book-keeping."
+msgstr ""
+
+#. type: Content of: <book><appendix><title>
+#: ../en/appC-srcinstall.xml:5
+msgid "Installing Mercurial from source"
+msgstr "从源代码安装 Mercurial"
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appC-srcinstall.xml:8
+msgid "On a Unix-like system"
+msgstr "类 Unix 系统"
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appC-srcinstall.xml:10
+msgid ""
+"If you are using a Unix-like system that has a sufficiently recent version of "
+"Python (2.3 or newer) available, it is easy to install Mercurial from source."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appC-srcinstall.xml:14
+msgid ""
+"Download a recent source tarball from <ulink url=\"http://www.selenic.com/"
+"mercurial/download\">http://www.selenic.com/mercurial/download</ulink>."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appC-srcinstall.xml:17
+msgid "Unpack the tarball:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appC-srcinstall.xml:20
+msgid ""
+"Go into the source directory and run the installer script.  This will build "
+"Mercurial and install it in your home directory."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appC-srcinstall.xml:27
+msgid ""
+"Once the install finishes, Mercurial will be in the <literal>bin</literal> "
+"subdirectory of your home directory.  Don't forget to make sure that this "
+"directory is present in your shell's search path."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appC-srcinstall.xml:32
+msgid ""
+"You will probably need to set the <envar>PYTHONPATH</envar> environment "
+"variable so that the Mercurial executable can find the rest of the Mercurial "
+"packages.  For example, on my laptop, I have set it to <literal>/home/bos/lib/"
+"python</literal>.  The exact path that you will need to use depends on how "
+"Python was built for your system, but should be easy to figure out.  If "
+"you're uncertain, look through the output of the installer script above, and "
+"see where the contents of the <literal>mercurial</literal> directory were "
+"installed to."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appC-srcinstall.xml:44
+msgid "On Windows"
+msgstr "Windows 系统"
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appC-srcinstall.xml:46
+msgid ""
+"Building and installing Mercurial on Windows requires a variety of tools, a "
+"fair amount of technical knowledge, and considerable patience.  I very much "
+"<emphasis>do not recommend</emphasis> this route if you are a <quote>casual "
+"user</quote>.  Unless you intend to hack on Mercurial, I strongly suggest "
+"that you use a binary package instead."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appC-srcinstall.xml:53
+msgid ""
+"If you are intent on building Mercurial from source on Windows, follow the "
+"<quote>hard way</quote> directions on the Mercurial wiki at <ulink url="
+"\"http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall\">http://www."
+"selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, and expect the "
+"process to involve a lot of fiddly work."
+msgstr ""
+
+#. type: Content of: <book><appendix><title>
+#: ../en/appD-license.xml:5
+msgid "Open Publication License"
+msgstr ""
+
+#. type: Content of: <book><appendix><para>
+#: ../en/appD-license.xml:7
+msgid "Version 1.0, 8 June 1999"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:10
+msgid "Requirements on both unmodified and modified versions"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:13
+msgid ""
+"The Open Publication works may be reproduced and distributed in whole or in "
+"part, in any medium physical or electronic, provided that the terms of this "
+"license are adhered to, and that this license or an incorporation of it by "
+"reference (with any options elected by the author(s) and/or publisher) is "
+"displayed in the reproduction."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:20
+msgid "Proper form for an incorporation by reference is as follows:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><blockquote><para>
+#: ../en/appD-license.xml:24
+msgid ""
+"Copyright (c) <emphasis>year</emphasis> by <emphasis>author's name or "
+"designee</emphasis>. This material may be distributed only subject to the "
+"terms and conditions set forth in the Open Publication License, v<emphasis>x."
+"y</emphasis> or later (the latest version is presently available at <ulink "
+"url=\"http://www.opencontent.org/openpub/\">http://www.opencontent.org/"
+"openpub/</ulink>)."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:33
+msgid ""
+"The reference must be immediately followed with any options elected by the "
+"author(s) and/or publisher of the document (see <xref linkend=\"sec:opl:"
+"options\"/>)."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:37
+msgid ""
+"Commercial redistribution of Open Publication-licensed material is permitted."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:40
+msgid ""
+"Any publication in standard (paper) book form shall require the citation of "
+"the original publisher and author. The publisher and author's names shall "
+"appear on all outer surfaces of the book. On all outer surfaces of the book "
+"the original publisher's name shall be as large as the title of the work and "
+"cited as possessive with respect to the title."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:49
+msgid "Copyright"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:51
+msgid ""
+"The copyright to each Open Publication is owned by its author(s) or designee."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:56
+msgid "Scope of license"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:58
+msgid ""
+"The following license terms apply to all Open Publication works, unless "
+"otherwise explicitly stated in the document."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:62
+msgid ""
+"Mere aggregation of Open Publication works or a portion of an Open "
+"Publication work with other works or programs on the same media shall not "
+"cause this license to apply to those other works. The aggregate work shall "
+"contain a notice specifying the inclusion of the Open Publication material "
+"and appropriate copyright notice."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:69
+msgid ""
+"<emphasis role=\"bold\">Severability</emphasis>. If any part of this license "
+"is found to be unenforceable in any jurisdiction, the remaining portions of "
+"the license remain in force."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:74
+msgid ""
+"<emphasis role=\"bold\">No warranty</emphasis>. Open Publication works are "
+"licensed and provided <quote>as is</quote> without warranty of any kind, "
+"express or implied, including, but not limited to, the implied warranties of "
+"merchantability and fitness for a particular purpose or a warranty of non-"
+"infringement."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:83
+msgid "Requirements on modified works"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:85
+msgid ""
+"All modified versions of documents covered by this license, including "
+"translations, anthologies, compilations and partial documents, must meet the "
+"following requirements:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:90
+msgid "The modified version must be labeled as such."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:93
+msgid ""
+"The person making the modifications must be identified and the modifications "
+"dated."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:96
+msgid ""
+"Acknowledgement of the original author and publisher if applicable must be "
+"retained according to normal academic citation practices."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:100
+msgid "The location of the original unmodified document must be identified."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:103
+msgid ""
+"The original author's (or authors') name(s) may not be used to assert or "
+"imply endorsement of the resulting document without the original author's (or "
+"authors')  permission."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:111
+msgid "Good-practice recommendations"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:113
+msgid ""
+"In addition to the requirements of this license, it is requested from and "
+"strongly recommended of redistributors that:"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:118
+msgid ""
+"If you are distributing Open Publication works on hardcopy or CD-ROM, you "
+"provide email notification to the authors of your intent to redistribute at "
+"least thirty days before your manuscript or media freeze, to give the authors "
+"time to provide updated documents. This notification should describe "
+"modifications, if any, made to the document."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:125
+msgid ""
+"All substantive modifications (including deletions) be either clearly marked "
+"up in the document or else described in an attachment to the document."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:129
+msgid ""
+"Finally, while it is not mandatory under this license, it is considered good "
+"form to offer a free copy of any hardcopy and CD-ROM expression of an Open "
+"Publication-licensed work to its author(s)."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><title>
+#: ../en/appD-license.xml:137
+msgid "License options"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><para>
+#: ../en/appD-license.xml:139
+msgid ""
+"The author(s) and/or publisher of an Open Publication-licensed document may "
+"elect certain options by appending language to the reference to or copy of "
+"the license.  These options are considered part of the license instance and "
+"must be included with the license (or its incorporation by reference) in "
+"derived works."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:147
+msgid ""
+"To prohibit distribution of substantively modified versions without the "
+"explicit permission of the author(s). <quote>Substantive modification</quote> "
+"is defined as a change to the semantic content of the document, and excludes "
+"mere changes in format or typographical corrections."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:154
+msgid ""
+"To accomplish this, add the phrase <quote>Distribution of substantively "
+"modified versions of this document is prohibited without the explicit "
+"permission of the copyright holder.</quote> to the license reference or copy."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:160
+msgid ""
+"To prohibit any publication of this work or derivative works in whole or in "
+"part in standard (paper)  book form for commercial purposes is prohibited "
+"unless prior permission is obtained from the copyright holder."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect1><orderedlist><listitem><para>
+#: ../en/appD-license.xml:165
+msgid ""
+"To accomplish this, add the phrase <quote>Distribution of the work or "
+"derivative of the work in any standard (paper) book form is prohibited unless "
+"prior permission is obtained from the copyright holder.</quote> to the "
+"license reference or copy."
+msgstr ""
+
+#. type: Content of: <book><preface><title>
+#: ../en/ch00-preface.xml:5
+msgid "Preface"
+msgstr "序言"
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:8
+msgid "Why revision control? Why Mercurial?"
+msgstr "为什么使用版本控制? 为什么使用 Mercurial?"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:10
+msgid ""
+"Revision control is the process of managing multiple versions of a piece of "
+"information.  In its simplest form, this is something that many people do by "
+"hand: every time you modify a file, save it under a new name that contains a "
+"number, each one higher than the number of the preceding version."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:16
+msgid ""
+"Manually managing multiple versions of even a single file is an error-prone "
+"task, though, so software tools to help automate this process have long been "
+"available.  The earliest automated revision control tools were intended to "
+"help a single user to manage revisions of a single file.  Over the past few "
+"decades, the scope of revision control tools has expanded greatly; they now "
+"manage multiple files, and help multiple people to work together.  The best "
+"modern revision control tools have no problem coping with thousands of people "
+"working together on projects that consist of hundreds of thousands of files."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:27
+msgid ""
+"The arrival of distributed revision control is relatively recent, and so far "
+"this new field has grown due to people's willingness to explore ill-charted "
+"territory."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:31
+msgid ""
+"I am writing a book about distributed revision control because I believe that "
+"it is an important subject that deserves a field guide. I chose to write "
+"about Mercurial because it is the easiest tool to learn the terrain with, and "
+"yet it scales to the demands of real, challenging environments where many "
+"other revision control tools buckle."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:39
+msgid "Why use revision control?"
+msgstr "为什么使用版本控制?"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:41
+msgid ""
+"There are a number of reasons why you or your team might want to use an "
+"automated revision control tool for a project."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:46
+msgid ""
+"It will track the history and evolution of your project, so you don't have "
+"to.  For every change, you'll have a log of <emphasis>who</emphasis> made it; "
+"<emphasis>why</emphasis> they made it; <emphasis>when</emphasis> they made "
+"it; and <emphasis>what</emphasis> the change was."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:53
+msgid ""
+"When you're working with other people, revision control software makes it "
+"easier for you to collaborate.  For example, when people more or less "
+"simultaneously make potentially incompatible changes, the software will help "
+"you to identify and resolve those conflicts."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:59
+msgid ""
+"It can help you to recover from mistakes.  If you make a change that later "
+"turns out to be in error, you can revert to an earlier version of one or more "
+"files.  In fact, a <emphasis>really</emphasis> good revision control tool "
+"will even help you to efficiently figure out exactly when a problem was "
+"introduced (see <xref linkend=\"sec:undo:bisect\"/> for details)."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:66
+msgid ""
+"It will help you to work simultaneously on, and manage the drift between, "
+"multiple versions of your project."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:71
+msgid ""
+"Most of these reasons are equally valid&emdash;at least in theory&emdash;"
+"whether you're working on a project by yourself, or with a hundred other "
+"people."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:76
+msgid ""
+"A key question about the practicality of revision control at these two "
+"different scales (<quote>lone hacker</quote> and <quote>huge team</quote>) is "
+"how its <emphasis>benefits</emphasis> compare to its <emphasis>costs</"
+"emphasis>.  A revision control tool that's difficult to understand or use is "
+"going to impose a high cost."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:84
+msgid ""
+"A five-hundred-person project is likely to collapse under its own weight "
+"almost immediately without a revision control tool and process. In this case, "
+"the cost of using revision control might hardly seem worth considering, since "
+"<emphasis>without</emphasis> it, failure is almost guaranteed."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:91
+msgid ""
+"On the other hand, a one-person <quote>quick hack</quote> might seem like a "
+"poor place to use a revision control tool, because surely the cost of using "
+"one must be close to the overall cost of the project.  Right?"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:96
+msgid ""
+"Mercurial uniquely supports <emphasis>both</emphasis> of these scales of "
+"development.  You can learn the basics in just a few minutes, and due to its "
+"low overhead, you can apply revision control to the smallest of projects with "
+"ease.  Its simplicity means you won't have a lot of abstruse concepts or "
+"command sequences competing for mental space with whatever you're "
+"<emphasis>really</emphasis> trying to do.  At the same time, Mercurial's high "
+"performance and peer-to-peer nature let you scale painlessly to handle large "
+"projects."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:106
+msgid ""
+"No revision control tool can rescue a poorly run project, but a good choice "
+"of tools can make a huge difference to the fluidity with which you can work "
+"on a project."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:113
+msgid "The many names of revision control"
+msgstr "版本控制的别名"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:115
+msgid ""
+"Revision control is a diverse field, so much so that it is referred to by "
+"many names and acronyms.  Here are a few of the more common variations you'll "
+"encounter:"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:119
+msgid "Revision control (RCS)"
+msgstr "版本控制(RCS)"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:120
+msgid "Software configuration management (SCM), or configuration management"
+msgstr "软件配置管理(SCM),或配置管理"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:122
+msgid "Source code management"
+msgstr "源代码管理"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:123
+msgid "Source code control, or source control"
+msgstr "源代码控制,或源控制"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:125
+msgid "Version control (VCS)"
+msgstr "版本控制(VCS)"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:127
+msgid ""
+"Some people claim that these terms actually have different meanings, but in "
+"practice they overlap so much that there's no agreed or even useful way to "
+"tease them apart."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:135
+msgid "This book is a work in progress"
+msgstr "本书正在编写中"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:137
+msgid ""
+"I am releasing this book while I am still writing it, in the hope that it "
+"will prove useful to others.  I am writing under an open license in the hope "
+"that you, my readers, will contribute feedback and perhaps content of your "
+"own."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:144
+msgid "About the examples in this book"
+msgstr "本书的例子"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:146
+msgid ""
+"This book takes an unusual approach to code samples.  Every example is "
+"<quote>live</quote>&emdash;each one is actually the result of a shell script "
+"that executes the Mercurial commands you see.  Every time an image of the "
+"book is built from its sources, all the example scripts are automatically "
+"run, and their current results compared against their expected results."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:153
+msgid ""
+"The advantage of this approach is that the examples are always accurate; they "
+"describe <emphasis>exactly</emphasis> the behaviour of the version of "
+"Mercurial that's mentioned at the front of the book.  If I update the version "
+"of Mercurial that I'm documenting, and the output of some command changes, "
+"the build fails."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:160
+msgid ""
+"There is a small disadvantage to this approach, which is that the dates and "
+"times you'll see in examples tend to be <quote>squashed</quote> together in a "
+"way that they wouldn't be if the same commands were being typed by a human.  "
+"Where a human can issue no more than one command every few seconds, with any "
+"resulting timestamps correspondingly spread out, my automated example scripts "
+"run many commands in one second."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:168
+msgid ""
+"As an instance of this, several consecutive commits in an example can show up "
+"as having occurred during the same second.  You can see this occur in the "
+"<literal role=\"hg-ext\">bisect</literal> example in <xref linkend=\"sec:undo:"
+"bisect\"/>, for instance."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:174
+msgid ""
+"So when you're reading examples, don't place too much weight on the dates or "
+"times you see in the output of commands.  But <emphasis>do</emphasis> be "
+"confident that the behaviour you're seeing is consistent and reproducible."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:182
+msgid "Trends in the field"
+msgstr "版本控制的发展趋势"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:184
+msgid ""
+"There has been an unmistakable trend in the development and use of revision "
+"control tools over the past four decades, as people have become familiar with "
+"the capabilities of their tools and constrained by their limitations."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:189
+msgid ""
+"The first generation began by managing single files on individual computers.  "
+"Although these tools represented a huge advance over ad-hoc manual revision "
+"control, their locking model and reliance on a single computer limited them "
+"to small, tightly-knit teams."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:195
+msgid ""
+"The second generation loosened these constraints by moving to network-"
+"centered architectures, and managing entire projects at a time.  As projects "
+"grew larger, they ran into new problems.  With clients needing to talk to "
+"servers very frequently, server scaling became an issue for large projects.  "
+"An unreliable network connection could prevent remote users from being able "
+"to talk to the server at all.  As open source projects started making read-"
+"only access available anonymously to anyone, people without commit privileges "
+"found that they could not use the tools to interact with a project in a "
+"natural way, as they could not record their changes."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:207
+msgid ""
+"The current generation of revision control tools is peer-to-peer in nature.  "
+"All of these systems have dropped the dependency on a single central server, "
+"and allow people to distribute their revision control data to where it's "
+"actually needed.  Collaboration over the Internet has moved from constrained "
+"by technology to a matter of choice and consensus.  Modern tools can operate "
+"offline indefinitely and autonomously, with a network connection only needed "
+"when syncing changes with another repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:219
+msgid "A few of the advantages of distributed revision control"
+msgstr "分布版本控制的优点"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:222
+msgid ""
+"Even though distributed revision control tools have for several years been as "
+"robust and usable as their previous-generation counterparts, people using "
+"older tools have not yet necessarily woken up to their advantages.  There are "
+"a number of ways in which distributed tools shine relative to centralised "
+"ones."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:229
+msgid ""
+"For an individual developer, distributed tools are almost always much faster "
+"than centralised tools.  This is for a simple reason: a centralised tool "
+"needs to talk over the network for many common operations, because most "
+"metadata is stored in a single copy on the central server.  A distributed "
+"tool stores all of its metadata locally.  All else being equal, talking over "
+"the network adds overhead to a centralised tool.  Don't underestimate the "
+"value of a snappy, responsive tool: you're going to spend a lot of time "
+"interacting with your revision control software."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:240
+msgid ""
+"Distributed tools are indifferent to the vagaries of your server "
+"infrastructure, again because they replicate metadata to so many locations.  "
+"If you use a centralised system and your server catches fire, you'd better "
+"hope that your backup media are reliable, and that your last backup was "
+"recent and actually worked.  With a distributed tool, you have many backups "
+"available on every contributor's computer."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:248
+msgid ""
+"The reliability of your network will affect distributed tools far less than "
+"it will centralised tools.  You can't even use a centralised tool without a "
+"network connection, except for a few highly constrained commands.  With a "
+"distributed tool, if your network connection goes down while you're working, "
+"you may not even notice.  The only thing you won't be able to do is talk to "
+"repositories on other computers, something that is relatively rare compared "
+"with local operations.  If you have a far-flung team of collaborators, this "
+"may be significant."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:259
+msgid "Advantages for open source projects"
+msgstr "开源项目的优点"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:261
+msgid ""
+"If you take a shine to an open source project and decide that you would like "
+"to start hacking on it, and that project uses a distributed revision control "
+"tool, you are at once a peer with the people who consider themselves the "
+"<quote>core</quote> of that project.  If they publish their repositories, you "
+"can immediately copy their project history, start making changes, and record "
+"your work, using the same tools in the same ways as insiders.  By contrast, "
+"with a centralised tool, you must use the software in a <quote>read only</"
+"quote> mode unless someone grants you permission to commit changes to their "
+"central server.  Until then, you won't be able to record changes, and your "
+"local modifications will be at risk of corruption any time you try to update "
+"your client's view of the repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><title>
+#: ../en/ch00-preface.xml:277
+msgid "The forking non-problem"
+msgstr "分叉不是问题"
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:279
+msgid ""
+"It has been suggested that distributed revision control tools pose some sort "
+"of risk to open source projects because they make it easy to <quote>fork</"
+"quote> the development of a project.  A fork happens when there are "
+"differences in opinion or attitude between groups of developers that cause "
+"them to decide that they can't work together any longer.  Each side takes a "
+"more or less complete copy of the project's source code, and goes off in its "
+"own direction."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:289
+msgid ""
+"Sometimes the camps in a fork decide to reconcile their differences. With a "
+"centralised revision control system, the <emphasis>technical</emphasis> "
+"process of reconciliation is painful, and has to be performed largely by "
+"hand.  You have to decide whose revision history is going to <quote>win</"
+"quote>, and graft the other team's changes into the tree somehow. This "
+"usually loses some or all of one side's revision history."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:298
+msgid ""
+"What distributed tools do with respect to forking is they make forking the "
+"<emphasis>only</emphasis> way to develop a project.  Every single change that "
+"you make is potentially a fork point.  The great strength of this approach is "
+"that a distributed revision control tool has to be really good at "
+"<emphasis>merging</emphasis> forks, because forks are absolutely fundamental: "
+"they happen all the time."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:307
+msgid ""
+"If every piece of work that everybody does, all the time, is framed in terms "
+"of forking and merging, then what the open source world refers to as a "
+"<quote>fork</quote> becomes <emphasis>purely</emphasis> a social issue.  If "
+"anything, distributed tools <emphasis>lower</emphasis> the likelihood of a "
+"fork:"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:314
+msgid ""
+"They eliminate the social distinction that centralised tools impose: that "
+"between insiders (people with commit access) and outsiders (people without)."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:318
+msgid ""
+"They make it easier to reconcile after a social fork, because all that's "
+"involved from the perspective of the revision control software is just "
+"another merge."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:323
+msgid ""
+"Some people resist distributed tools because they want to retain tight "
+"control over their projects, and they believe that centralised tools give "
+"them this control.  However, if you're of this belief, and you publish your "
+"CVS or Subversion repositories publicly, there are plenty of tools available "
+"that can pull out your entire project's history (albeit slowly) and recreate "
+"it somewhere that you don't control.  So while your control in this case is "
+"illusory, you are forgoing the ability to fluidly collaborate with whatever "
+"people feel compelled to mirror and fork your history."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:338
+msgid "Advantages for commercial projects"
+msgstr "商业项目的优点"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:340
+msgid ""
+"Many commercial projects are undertaken by teams that are scattered across "
+"the globe.  Contributors who are far from a central server will see slower "
+"command execution and perhaps less reliability.  Commercial revision control "
+"systems attempt to ameliorate these problems with remote-site replication add-"
+"ons that are typically expensive to buy and cantankerous to administer.  A "
+"distributed system doesn't suffer from these problems in the first place.  "
+"Better yet, you can easily set up multiple authoritative servers, say one per "
+"site, so that there's no redundant communication between repositories over "
+"expensive long-haul network links."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:352
+msgid ""
+"Centralised revision control systems tend to have relatively low "
+"scalability.  It's not unusual for an expensive centralised system to fall "
+"over under the combined load of just a few dozen concurrent users.  Once "
+"again, the typical response tends to be an expensive and clunky replication "
+"facility.  Since the load on a central server&emdash;if you have one at "
+"all&emdash;is many times lower with a distributed tool (because all of the "
+"data is replicated everywhere), a single cheap server can handle the needs of "
+"a much larger team, and replication to balance load becomes a simple matter "
+"of scripting."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:364
+msgid ""
+"If you have an employee in the field, troubleshooting a problem at a "
+"customer's site, they'll benefit from distributed revision control. The tool "
+"will let them generate custom builds, try different fixes in isolation from "
+"each other, and search efficiently through history for the sources of bugs "
+"and regressions in the customer's environment, all without needing to connect "
+"to your company's network."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:375
+msgid "Why choose Mercurial?"
+msgstr "为什么选择 Mercurial?"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:377
+msgid ""
+"Mercurial has a unique set of properties that make it a particularly good "
+"choice as a revision control system."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:380
+msgid "It is easy to learn and use."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:381
+msgid "It is lightweight."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:382
+msgid "It scales excellently."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:383
+msgid "It is easy to customise."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:386
+msgid ""
+"If you are at all familiar with revision control systems, you should be able "
+"to get up and running with Mercurial in less than five minutes.  Even if not, "
+"it will take no more than a few minutes longer.  Mercurial's command and "
+"feature sets are generally uniform and consistent, so you can keep track of a "
+"few general rules instead of a host of exceptions."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:393
+msgid ""
+"On a small project, you can start working with Mercurial in moments. Creating "
+"new changes and branches; transferring changes around (whether locally or "
+"over a network); and history and status operations are all fast.  Mercurial "
+"attempts to stay nimble and largely out of your way by combining low "
+"cognitive overhead with blazingly fast operations."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:400
+msgid ""
+"The usefulness of Mercurial is not limited to small projects: it is used by "
+"projects with hundreds to thousands of contributors, each containing tens of "
+"thousands of files and hundreds of megabytes of source code."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:405
+msgid ""
+"If the core functionality of Mercurial is not enough for you, it's easy to "
+"build on.  Mercurial is well suited to scripting tasks, and its clean "
+"internals and implementation in Python make it easy to add features in the "
+"form of extensions.  There are a number of popular and useful extensions "
+"already available, ranging from helping to identify bugs to improving "
+"performance."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:415
+msgid "Mercurial compared with other tools"
+msgstr "Mercurial 与其它工具的比较"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:417
+msgid ""
+"Before you read on, please understand that this section necessarily reflects "
+"my own experiences, interests, and (dare I say it) biases.  I have used every "
+"one of the revision control tools listed below, in most cases for several "
+"years at a time."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:425 ../en/ch00-preface.xml:636
+msgid "Subversion"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:427
+msgid ""
+"Subversion is a popular revision control tool, developed to replace CVS.  It "
+"has a centralised client/server architecture."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:431
+msgid ""
+"Subversion and Mercurial have similarly named commands for performing the "
+"same operations, so if you're familiar with one, it is easy to learn to use "
+"the other.  Both tools are portable to all popular operating systems."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:436
+msgid ""
+"Prior to version 1.5, Subversion had no useful support for merges. At the "
+"time of writing, its merge tracking capability is new, and known to be <ulink "
+"url=\"http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced."
+"html#svn.branchmerge.advanced.finalword\">complicated and buggy</ulink>."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:442
+msgid ""
+"Mercurial has a substantial performance advantage over Subversion on every "
+"revision control operation I have benchmarked.  I have measured its advantage "
+"as ranging from a factor of two to a factor of six when compared with "
+"Subversion 1.4.3's <emphasis>ra_local</emphasis> file store, which is the "
+"fastest access method available.  In more realistic deployments involving a "
+"network-based store, Subversion will be at a substantially larger "
+"disadvantage.  Because many Subversion commands must talk to the server and "
+"Subversion does not have useful replication facilities, server capacity and "
+"network bandwidth become bottlenecks for modestly large projects."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:455
+msgid ""
+"Additionally, Subversion incurs substantial storage overhead to avoid network "
+"transactions for a few common operations, such as finding modified files "
+"(<literal>status</literal>) and displaying modifications against the current "
+"revision (<literal>diff</literal>).  As a result, a Subversion working copy "
+"is often the same size as, or larger than, a Mercurial repository and working "
+"directory, even though the Mercurial repository contains a complete history "
+"of the project."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:465
+msgid ""
+"Subversion is widely supported by third party tools.  Mercurial currently "
+"lags considerably in this area.  This gap is closing, however, and indeed "
+"some of Mercurial's GUI tools now outshine their Subversion equivalents.  "
+"Like Mercurial, Subversion has an excellent user manual."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:471
+msgid ""
+"Because Subversion doesn't store revision history on the client, it is well "
+"suited to managing projects that deal with lots of large, opaque binary "
+"files.  If you check in fifty revisions to an incompressible 10MB file, "
+"Subversion's client-side space usage stays constant The space used by any "
+"distributed SCM will grow rapidly in proportion to the number of revisions, "
+"because the differences between each revision are large."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:480
+msgid ""
+"In addition, it's often difficult or, more usually, impossible to merge "
+"different versions of a binary file.  Subversion's ability to let a user lock "
+"a file, so that they temporarily have the exclusive right to commit changes "
+"to it, can be a significant advantage to a project where binary files are "
+"widely used."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:487
+msgid ""
+"Mercurial can import revision history from a Subversion repository. It can "
+"also export revision history to a Subversion repository.  This makes it easy "
+"to <quote>test the waters</quote> and use Mercurial and Subversion in "
+"parallel before deciding to switch.  History conversion is incremental, so "
+"you can perform an initial conversion, then small additional conversions "
+"afterwards to bring in new changes."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:499 ../en/ch00-preface.xml:638
+msgid "Git"
+msgstr "Git"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:501
+msgid ""
+"Git is a distributed revision control tool that was developed for managing "
+"the Linux kernel source tree.  Like Mercurial, its early design was somewhat "
+"influenced by Monotone."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:506
+msgid ""
+"Git has a very large command set, with version 1.5.0 providing 139 individual "
+"commands.  It has something of a reputation for being difficult to learn.  "
+"Compared to Git, Mercurial has a strong focus on simplicity."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:511
+msgid ""
+"In terms of performance, Git is extremely fast.  In several cases, it is "
+"faster than Mercurial, at least on Linux, while Mercurial performs better on "
+"other operations.  However, on Windows, the performance and general level of "
+"support that Git provides is, at the time of writing, far behind that of "
+"Mercurial."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:518
+msgid ""
+"While a Mercurial repository needs no maintenance, a Git repository requires "
+"frequent manual <quote>repacks</quote> of its metadata.  Without these, "
+"performance degrades, while space usage grows rapidly.  A server that "
+"contains many Git repositories that are not rigorously and frequently "
+"repacked will become heavily disk-bound during backups, and there have been "
+"instances of daily backups taking far longer than 24 hours as a result.  A "
+"freshly packed Git repository is slightly smaller than a Mercurial "
+"repository, but an unpacked repository is several orders of magnitude larger."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:529
+msgid ""
+"The core of Git is written in C.  Many Git commands are implemented as shell "
+"or Perl scripts, and the quality of these scripts varies widely. I have "
+"encountered several instances where scripts charged along blindly in the "
+"presence of errors that should have been fatal."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:535
+msgid "Mercurial can import revision history from a Git repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:541 ../en/ch00-preface.xml:637
+msgid "CVS"
+msgstr "CVS"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:543
+msgid ""
+"CVS is probably the most widely used revision control tool in the world.  Due "
+"to its age and internal untidiness, it has been only lightly maintained for "
+"many years."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:547
+msgid ""
+"It has a centralised client/server architecture.  It does not group related "
+"file changes into atomic commits, making it easy for people to <quote>break "
+"the build</quote>: one person can successfully commit part of a change and "
+"then be blocked by the need for a merge, causing other people to see only a "
+"portion of the work they intended to do.  This also affects how you work with "
+"project history.  If you want to see all of the modifications someone made as "
+"part of a task, you will need to manually inspect the descriptions and "
+"timestamps of the changes made to each file involved (if you even know what "
+"those files were)."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:559
+msgid ""
+"CVS has a muddled notion of tags and branches that I will not attempt to even "
+"describe.  It does not support renaming of files or directories well, making "
+"it easy to corrupt a repository.  It has almost no internal consistency "
+"checking capabilities, so it is usually not even possible to tell whether or "
+"how a repository is corrupt.  I would not recommend CVS for any project, "
+"existing or new."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:567
+msgid ""
+"Mercurial can import CVS revision history.  However, there are a few caveats "
+"that apply; these are true of every other revision control tool's CVS "
+"importer, too.  Due to CVS's lack of atomic changes and unversioned "
+"filesystem hierarchy, it is not possible to reconstruct CVS history "
+"completely accurately; some guesswork is involved, and renames will usually "
+"not show up.  Because a lot of advanced CVS administration has to be done by "
+"hand and is hence error-prone, it's common for CVS importers to run into "
+"multiple problems with corrupted repositories (completely bogus revision "
+"timestamps and files that have remained locked for over a decade are just two "
+"of the less interesting problems I can recall from personal experience)."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:581
+msgid "Mercurial can import revision history from a CVS repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:587
+msgid "Commercial tools"
+msgstr "商业工具"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:589
+msgid ""
+"Perforce has a centralised client/server architecture, with no client-side "
+"caching of any data.  Unlike modern revision control tools, Perforce requires "
+"that a user run a command to inform the server about every file they intend "
+"to edit."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:595
+msgid ""
+"The performance of Perforce is quite good for small teams, but it falls off "
+"rapidly as the number of users grows beyond a few dozen. Modestly large "
+"Perforce installations require the deployment of proxies to cope with the "
+"load their users generate."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:604
+msgid "Choosing a revision control tool"
+msgstr "选择版本控制工具"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:606
+msgid ""
+"With the exception of CVS, all of the tools listed above have unique "
+"strengths that suit them to particular styles of work.  There is no single "
+"revision control tool that is best in all situations."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:611
+msgid ""
+"As an example, Subversion is a good choice for working with frequently edited "
+"binary files, due to its centralised nature and support for file locking."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:615
+msgid ""
+"I personally find Mercurial's properties of simplicity, performance, and good "
+"merge support to be a compelling combination that has served me well for "
+"several years."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:623
+msgid "Switching from another tool to Mercurial"
+msgstr "从其它工具切换到 Mercurial"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:625
+msgid ""
+"Mercurial is bundled with an extension named <literal role=\"hg-ext"
+"\">convert</literal>, which can incrementally import revision history from "
+"several other revision control tools.  By <quote>incremental</quote>, I mean "
+"that you can convert all of a project's history to date in one go, then rerun "
+"the conversion later to obtain new changes that happened after the initial "
+"conversion."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:633
+msgid ""
+"The revision control tools supported by <literal role=\"hg-ext\">convert</"
+"literal> are as follows:"
+msgstr "<literal role=\"hg-ext\">convert</literal> 支持的版本控制工具有:"
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:639
+msgid "Darcs"
+msgstr "Darcs"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:641
+msgid ""
+"In addition, <literal role=\"hg-ext\">convert</literal> can export changes "
+"from Mercurial to Subversion.  This makes it possible to try Subversion and "
+"Mercurial in parallel before committing to a switchover, without risking the "
+"loss of any work."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:647
+msgid ""
+"The <command role=\"hg-ext-convert\">convert</command> command is easy to "
+"use.  Simply point it at the path or URL of the source repository, optionally "
+"give it the name of the destination repository, and it will start working.  "
+"After the initial conversion, just run the same command again to import new "
+"changes."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:656
+msgid "A short history of revision control"
+msgstr "版本控制简史"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:658
+msgid ""
+"The best known of the old-time revision control tools is SCCS (Source Code "
+"Control System), which Marc Rochkind wrote at Bell Labs, in the early 1970s.  "
+"SCCS operated on individual files, and required every person working on a "
+"project to have access to a shared workspace on a single system.  Only one "
+"person could modify a file at any time; arbitration for access to files was "
+"via locks.  It was common for people to lock files, and later forget to "
+"unlock them, preventing anyone else from modifying those files without the "
+"help of an administrator."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:669
+msgid ""
+"Walter Tichy developed a free alternative to SCCS in the early 1980s; he "
+"called his program RCS (Revision Control System).  Like SCCS, RCS required "
+"developers to work in a single shared workspace, and to lock files to prevent "
+"multiple people from modifying them simultaneously."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:675
+msgid ""
+"Later in the 1980s, Dick Grune used RCS as a building block for a set of "
+"shell scripts he initially called cmt, but then renamed to CVS (Concurrent "
+"Versions System).  The big innovation of CVS was that it let developers work "
+"simultaneously and somewhat independently in their own personal workspaces.  "
+"The personal workspaces prevented developers from stepping on each other's "
+"toes all the time, as was common with SCCS and RCS. Each developer had a copy "
+"of every project file, and could modify their copies independently.  They had "
+"to merge their edits prior to committing changes to the central repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:686
+msgid ""
+"Brian Berliner took Grune's original scripts and rewrote them in C, releasing "
+"in 1989 the code that has since developed into the modern version of CVS.  "
+"CVS subsequently acquired the ability to operate over a network connection, "
+"giving it a client/server architecture.  CVS's architecture is centralised; "
+"only the server has a copy of the history of the project. Client workspaces "
+"just contain copies of recent versions of the project's files, and a little "
+"metadata to tell them where the server is.  CVS has been enormously "
+"successful; it is probably the world's most widely used revision control "
+"system."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:697
+msgid ""
+"In the early 1990s, Sun Microsystems developed an early distributed revision "
+"control system, called TeamWare.  A TeamWare workspace contains a complete "
+"copy of the project's history.  TeamWare has no notion of a central "
+"repository.  (CVS relied upon RCS for its history storage; TeamWare used "
+"SCCS.)"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:704
+msgid ""
+"As the 1990s progressed, awareness grew of a number of problems with CVS.  It "
+"records simultaneous changes to multiple files individually, instead of "
+"grouping them together as a single logically atomic operation.  It does not "
+"manage its file hierarchy well; it is easy to make a mess of a repository by "
+"renaming files and directories.  Worse, its source code is difficult to read "
+"and maintain, which made the <quote>pain level</quote> of fixing these "
+"architectural problems prohibitive."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:714
+msgid ""
+"In 2001, Jim Blandy and Karl Fogel, two developers who had worked on CVS, "
+"started a project to replace it with a tool that would have a better "
+"architecture and cleaner code.  The result, Subversion, does not stray from "
+"CVS's centralised client/server model, but it adds multi-file atomic commits, "
+"better namespace management, and a number of other features that make it a "
+"generally better tool than CVS. Since its initial release, it has rapidly "
+"grown in popularity."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:723
+msgid ""
+"More or less simultaneously, Graydon Hoare began working on an ambitious "
+"distributed revision control system that he named Monotone. While Monotone "
+"addresses many of CVS's design flaws and has a peer-to-peer architecture, it "
+"goes beyond earlier (and subsequent) revision control tools in a number of "
+"innovative ways.  It uses cryptographic hashes as identifiers, and has an "
+"integral notion of <quote>trust</quote> for code from different sources."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:732
+msgid ""
+"Mercurial began life in 2005.  While a few aspects of its design are "
+"influenced by Monotone, Mercurial focuses on ease of use, high performance, "
+"and scalability to very large projects."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><title>
+#: ../en/ch00-preface.xml:740
+msgid "Colophon&emdash;this book is Free"
+msgstr "后记—本书是自由的!"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:742
+msgid ""
+"This book is licensed under the Open Publication License, and is produced "
+"entirely using Free Software tools.  It is typeset with DocBook XML.  "
+"Illustrations are drawn and rendered with <ulink url=\"http://www.inkscape."
+"org/\">Inkscape</ulink>."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:747
+msgid ""
+"The complete source code for this book is published as a Mercurial "
+"repository, at <ulink url=\"http://hg.serpentine.com/mercurial/book\">http://"
+"hg.serpentine.com/mercurial/book</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch01-tour-basic.xml:5
+msgid "A tour of Mercurial: the basics"
+msgstr "Mercurial 教程: 基础知识"
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:8
+msgid "Installing Mercurial on your system"
+msgstr "安装 Mercurial"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:10
+msgid ""
+"Prebuilt binary packages of Mercurial are available for every popular "
+"operating system.  These make it easy to start using Mercurial on your "
+"computer immediately."
+msgstr ""
+"对于每种流行的操作系统,都有已经构建的二进制软件包。这让在你的计算机上开始使"
+"用 Mercurial 变得很容易。"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:15
+msgid "Windows"
+msgstr "Windows"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:17
+msgid ""
+"The best version of Mercurial for Windows is TortoiseHg, which can be found "
+"at <ulink url=\"http://bitbucket.org/tortoisehg/stable/wiki/Home\">http://"
+"bitbucket.org/tortoisehg/stable/wiki/Home</ulink>.  This package has no "
+"external dependencies; it <quote>just works</quote>.  It provides both "
+"command line and graphical user interfaces."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:27
+msgid "Mac OS X"
+msgstr "Mac OS X"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:29
+msgid ""
+"Lee Cantey publishes an installer of Mercurial for Mac OS X at <ulink url="
+"\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:35
+msgid "Linux"
+msgstr "Linux"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:37
+msgid ""
+"Because each Linux distribution has its own packaging tools, policies, and "
+"rate of development, it's difficult to give a comprehensive set of "
+"instructions on how to install Mercurial binaries.  The version of Mercurial "
+"that you will end up with can vary depending on how active the person is who "
+"maintains the package for your distribution."
+msgstr ""
+"由于每种 Linux 发行版都有自己的包管理工具,开发策略和进度,从而很难给出安装 "
+"Mercurial 二进制包的全面说明。你安装的 Mercurial 版本,在很大程度上依赖于你所"
+"使用的发行版的 Mercurial 维护者的活跃程度。"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:44
+msgid ""
+"To keep things simple, I will focus on installing Mercurial from the command "
+"line under the most popular Linux distributions.  Most of these distributions "
+"provide graphical package managers that will let you install Mercurial with a "
+"single click; the package name to look for is <literal>mercurial</literal>."
+msgstr ""
+"为了让事情简单,我会致力于说明在最流行的 Linux 发行版中,从命令行安装 "
+"Mercurial 的方法。这些发行版都提供了图形界面的包管理器,让你通过点击鼠标安装 "
+"Mercurial;寻找的包名称是 <literal>mercurial</literal>。"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:52
+msgid "Ubuntu and Debian:"
+msgstr "Ubuntu 与 Debian:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:54
+msgid "Fedora and OpenSUSE:"
+msgstr "Fedora and OpenSUSE:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:56
+msgid "Gentoo:"
+msgstr "Gentoo:"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:62
+msgid "Solaris"
+msgstr "Solaris"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:64
+msgid ""
+"SunFreeWare, at <ulink url=\"http://www.sunfreeware.com\">http://www."
+"sunfreeware.com</ulink>, provides prebuilt packages of Mercurial."
+msgstr ""
+"位于 <ulink url=\"http://www.sunfreeware.com\">http://www.sunfreeware.com</"
+"ulink> 的 SunFreeWare 提供了 Mercurial 的二进制安装包。"
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:73
+msgid "Getting started"
+msgstr "开始"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:75
+msgid ""
+"To begin, we'll use the <command role=\"hg-cmd\">hg version</command> command "
+"to find out whether Mercurial is actually installed properly.  The actual "
+"version information that it prints isn't so important; it's whether it prints "
+"anything at all that we care about."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:84
+msgid "Built-in help"
+msgstr "内置帮助"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:86
+msgid ""
+"Mercurial provides a built-in help system.  This is invaluable for those "
+"times when you find yourself stuck trying to remember how to run a command.  "
+"If you are completely stuck, simply run <command role=\"hg-cmd\">hg help</"
+"command>; it will print a brief list of commands, along with a description of "
+"what each does.  If you ask for help on a specific command (as below), it "
+"prints more detailed information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:97
+msgid ""
+"For a more impressive level of detail (which you won't usually need) run "
+"<command role=\"hg-cmd\">hg help <option role=\"hg-opt-global\">-v</option></"
+"command>.  The <option role=\"hg-opt-global\">-v</option> option is short for "
+"<option role=\"hg-opt-global\">--verbose</option>, and tells Mercurial to "
+"print more information than it usually would."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:108
+msgid "Working with a repository"
+msgstr "使用版本库"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:110
+msgid ""
+"In Mercurial, everything happens inside a <emphasis>repository</emphasis>.  "
+"The repository for a project contains all of the files that <quote>belong to</"
+"quote> that project, along with a historical record of the project's files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:116
+msgid ""
+"There's nothing particularly magical about a repository; it is simply a "
+"directory tree in your filesystem that Mercurial treats as special. You can "
+"rename or delete a repository any time you like, using either the command "
+"line or your file browser."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:123
+msgid "Making a local copy of a repository"
+msgstr "创建版本库的工作副本"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:125
+msgid ""
+"<emphasis>Copying</emphasis> a repository is just a little bit special.  "
+"While you could use a normal file copying command to make a copy of a "
+"repository, it's best to use a built-in command that Mercurial provides.  "
+"This command is called <command role=\"hg-cmd\">hg clone</command>, because "
+"it makes an identical copy of an existing repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:134
+msgid ""
+"One advantage of using <command role=\"hg-cmd\">hg clone</command> is that, "
+"as we can see above, it lets us clone repositories over the network.  Another "
+"is that it remembers where we cloned from, which we'll find useful soon when "
+"we want to fetch new changes from another repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:140
+msgid ""
+"If our clone succeeded, we should now have a local directory called <filename "
+"class=\"directory\">hello</filename>.  This directory will contain some files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:146
+msgid ""
+"These files have the same contents and history in our repository as they do "
+"in the repository we cloned."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:149
+msgid ""
+"Every Mercurial repository is complete, self-contained, and independent.  It "
+"contains its own private copy of a project's files and history.  As we just "
+"mentioned, a cloned repository remembers the location of the repository it "
+"was cloned from, but Mercurial will not communicate with that repository, or "
+"any other, unless you tell it to."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:156
+msgid ""
+"What this means for now is that we're free to experiment with our repository, "
+"safe in the knowledge that it's a private <quote>sandbox</quote> that won't "
+"affect anyone else."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:162
+msgid "What's in a repository?"
+msgstr "什么是版本库?"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:164
+msgid ""
+"When we take a more detailed look inside a repository, we can see that it "
+"contains a directory named <filename class=\"directory\">.hg</filename>.  "
+"This is where Mercurial keeps all of its metadata for the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:171
+msgid ""
+"The contents of the <filename class=\"directory\">.hg</filename> directory "
+"and its subdirectories are private to Mercurial.  Every other file and "
+"directory in the repository is yours to do with as you please."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:177
+msgid ""
+"To introduce a little terminology, the <filename class=\"directory\">.hg</"
+"filename> directory is the <quote>real</quote> repository, and all of the "
+"files and directories that coexist with it are said to live in the "
+"<emphasis>working directory</emphasis>.  An easy way to remember the "
+"distinction is that the <emphasis>repository</emphasis> contains the "
+"<emphasis>history</emphasis> of your project, while the <emphasis>working "
+"directory</emphasis> contains a <emphasis>snapshot</emphasis> of your project "
+"at a particular point in history."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:192
+msgid "A tour through history"
+msgstr "回溯历史"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:194
+msgid ""
+"One of the first things we might want to do with a new, unfamiliar repository "
+"is understand its history.  The <command role=\"hg-cmd\">hg log</command> "
+"command gives us a view of the history of changes in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:201
+msgid ""
+"By default, this command prints a brief paragraph of output for each change "
+"to the project that was recorded.  In Mercurial terminology, we call each of "
+"these recorded events a <emphasis>changeset</emphasis>, because it can "
+"contain a record of changes to several files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:207
+msgid ""
+"The fields in a record of output from <command role=\"hg-cmd\">hg log</"
+"command> are as follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:211
+msgid ""
+"<literal>changeset</literal>: This field has the format of a number, followed "
+"by a colon, followed by a hexadecimal (or <emphasis>hex</emphasis>)  string.  "
+"These are <emphasis>identifiers</emphasis> for the changeset.  The hex string "
+"is a unique identifier: the same hex string will always refer to the same "
+"changeset. The number is shorter and easier to type than the hex string, but "
+"it isn't unique: the same number in two different clones of a repository may "
+"identify different changesets.  Why provide the number at all, then? For "
+"local convenience."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:223
+msgid ""
+"<literal>user</literal>: The identity of the person who created the "
+"changeset.  This is a free-form field, but it most often contains a person's "
+"name and email address."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:227
+msgid ""
+"<literal>date</literal>: The date and time on which the changeset was "
+"created, and the timezone in which it was created.  (The date and time are "
+"local to that timezone; they display what time and date it was for the person "
+"who created the changeset.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:232
+msgid ""
+"<literal>summary</literal>: The first line of the text message that the "
+"creator of the changeset entered to describe the changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:236
+msgid ""
+"Some changesets, such as the first in the list above, have a <literal>tag</"
+"literal> field.  A tag is another way to identify a changeset, by giving it "
+"an easy-to-remember name. (The tag named <literal>tip</literal> is special: "
+"it always refers to the newest change in a repository.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:244
+msgid ""
+"The default output printed by <command role=\"hg-cmd\">hg log</command> is "
+"purely a summary; it is missing a lot of detail."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:248
+msgid ""
+"<xref linkend=\"fig:tour-basic:history\"/> provides a graphical "
+"representation of the history of the <filename class=\"directory\">hello</"
+"filename> repository, to make it a little easier to see which direction "
+"history is <quote>flowing</quote> in.  We'll be returning to this figure "
+"several times in this chapter and the chapter that follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><figure><title>
+#: ../en/ch01-tour-basic.xml:257
+msgid ""
+"Graphical history of the <filename class=\"directory\">hello</filename> "
+"repository"
+msgstr "版本库 <filename class=\"directory\">hello</filename> 的历史图"
+
+#. type: Content of: <book><chapter><sect1><figure>
+#: ../en/ch01-tour-basic.xml:259 ../en/ch02-tour-merge.xml:50
+#: ../en/ch02-tour-merge.xml:181 ../en/ch03-concepts.xml:293
+msgid "<placeholder type=\"mediaobject\" id=\"0\"/>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><figure><mediaobject>
+#: ../en/ch01-tour-basic.xml:260
+msgid ""
+"<imageobject><imagedata fileref=\"figs/tour-history.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject><textobject><phrase>
+#: ../en/ch01-tour-basic.xml:261 ../en/ch02-tour-merge.xml:52
+#: ../en/ch02-tour-merge.xml:82 ../en/ch02-tour-merge.xml:129
+#: ../en/ch02-tour-merge.xml:183 ../en/ch02-tour-merge.xml:254
+#: ../en/ch03-concepts.xml:57 ../en/ch03-concepts.xml:106
+#: ../en/ch03-concepts.xml:191 ../en/ch03-concepts.xml:295
+#: ../en/ch03-concepts.xml:346 ../en/ch03-concepts.xml:361
+#: ../en/ch03-concepts.xml:402 ../en/ch03-concepts.xml:422
+#: ../en/ch03-concepts.xml:465 ../en/ch05-collab.xml:276
+#: ../en/ch08-undo.xml:365 ../en/ch08-undo.xml:412 ../en/ch08-undo.xml:477
+#: ../en/ch08-undo.xml:515 ../en/ch11-mq.xml:412
+msgid "XXX add text"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:266
+msgid "Changesets, revisions, and talking to other people"
+msgstr "修改集,版本,与其它用户交互"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:269
+msgid ""
+"As English is a notoriously sloppy language, and computer science has a "
+"hallowed history of terminological confusion (why use one term when four will "
+"do?), revision control has a variety of words and phrases that mean the same "
+"thing.  If you are talking about Mercurial history with other people, you "
+"will find that the word <quote>changeset</quote> is often compressed to "
+"<quote>change</quote> or (when written)  <quote>cset</quote>, and sometimes a "
+"changeset is referred to as a <quote>revision</quote> or a <quote>rev</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:279
+msgid ""
+"While it doesn't matter what <emphasis>word</emphasis> you use to refer to "
+"the concept of <quote>a changeset</quote>, the <emphasis>identifier</"
+"emphasis> that you use to refer to <quote>a <emphasis>specific</emphasis> "
+"changeset</quote> is of great importance. Recall that the <literal>changeset</"
+"literal> field in the output from <command role=\"hg-cmd\">hg log</command> "
+"identifies a changeset using both a number and a hexadecimal string."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:288
+msgid ""
+"The revision number is a handy notation that is <emphasis>only valid in that "
+"repository</emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:291
+msgid ""
+"The hexadecimal string is the <emphasis>permanent, unchanging identifier</"
+"emphasis> that will always identify that exact changeset in <emphasis>every</"
+"emphasis> copy of the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:297
+msgid ""
+"This distinction is important.  If you send someone an email talking about "
+"<quote>revision 33</quote>, there's a high likelihood that their revision 33 "
+"will <emphasis>not be the same</emphasis> as yours.  The reason for this is "
+"that a revision number depends on the order in which changes arrived in a "
+"repository, and there is no guarantee that the same changes will happen in "
+"the same order in different repositories. Three changes <literal>a,b,c</"
+"literal> can easily appear in one repository as <literal>0,1,2</literal>, "
+"while in another as <literal>0,2,1</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:309
+msgid ""
+"Mercurial uses revision numbers purely as a convenient shorthand.  If you "
+"need to discuss a changeset with someone, or make a record of a changeset for "
+"some other reason (for example, in a bug report), use the hexadecimal "
+"identifier."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:317
+msgid "Viewing specific revisions"
+msgstr "察看指定版本"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:319
+msgid ""
+"To narrow the output of <command role=\"hg-cmd\">hg log</command> down to a "
+"single revision, use the <option role=\"hg-opt-log\">-r</option> (or <option "
+"role=\"hg-opt-log\">--rev</option>) option.  You can use either a revision "
+"number or a hexadecimal identifier, and you can provide as many revisions as "
+"you want."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:328
+msgid ""
+"If you want to see the history of several revisions without having to list "
+"each one, you can use <emphasis>range notation</emphasis>; this lets you "
+"express the idea <quote>I want all revisions between <literal>abc</literal> "
+"and <literal>def</literal>, inclusive</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:336
+msgid ""
+"Mercurial also honours the order in which you specify revisions, so <command "
+"role=\"hg-cmd\">hg log -r 2:4</command> prints 2, 3, and 4. while <command "
+"role=\"hg-cmd\">hg log -r 4:2</command> prints 4, 3, and 2."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:343
+msgid "More detailed information"
+msgstr "更详细的信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:345
+msgid ""
+"While the summary information printed by <command role=\"hg-cmd\">hg log</"
+"command> is useful if you already know what you're looking for, you may need "
+"to see a complete description of the change, or a list of the files changed, "
+"if you're trying to decide whether a changeset is the one you're looking for. "
+"The <command role=\"hg-cmd\">hg log</command> command's <option role=\"hg-opt-"
+"global\">-v</option> (or <option role=\"hg-opt-global\">--verbose</option>) "
+"option gives you this extra detail."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:357
+msgid ""
+"If you want to see both the description and content of a change, add the "
+"<option role=\"hg-opt-log\">-p</option> (or <option role=\"hg-opt-log\">--"
+"patch</option>) option.  This displays the content of a change as a "
+"<emphasis>unified diff</emphasis> (if you've never seen a unified diff "
+"before, see <xref linkend=\"sec:mq:patch\"/> for an overview)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:367
+msgid ""
+"The <option role=\"hg-opt-log\">-p</option> option is tremendously useful, so "
+"it's well worth remembering."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:374
+msgid "All about command options"
+msgstr "命令选项"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:376
+msgid ""
+"Let's take a brief break from exploring Mercurial commands to discuss a "
+"pattern in the way that they work; you may find this useful to keep in mind "
+"as we continue our tour."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:380
+msgid ""
+"Mercurial has a consistent and straightforward approach to dealing with the "
+"options that you can pass to commands.  It follows the conventions for "
+"options that are common to modern Linux and Unix systems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:387
+msgid ""
+"Every option has a long name.  For example, as we've already seen, the "
+"<command role=\"hg-cmd\">hg log</command> command accepts a <option role=\"hg-"
+"opt-log\">--rev</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:393
+msgid ""
+"Most options have short names, too.  Instead of <option role=\"hg-opt-log\">--"
+"rev</option>, we can use <option role=\"hg-opt-log\">-r</option>.  (The "
+"reason that some options don't have short names is that the options in "
+"question are rarely used.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:400
+msgid ""
+"Long options start with two dashes (e.g.  <option role=\"hg-opt-log\">--rev</"
+"option>), while short options start with one (e.g. <option role=\"hg-opt-log"
+"\">-r</option>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:406
+msgid ""
+"Option naming and usage is consistent across commands.  For example, every "
+"command that lets you specify a changeset ID or revision number accepts both "
+"<option role=\"hg-opt-log\">-r</option> and <option role=\"hg-opt-log\">--"
+"rev</option> arguments."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:413
+msgid ""
+"If you are using short options, you can save typing by running them together. "
+"For example, the command <command role=\"hg-cmd\">hg log -v -p -r 2</command> "
+"can be written as <command role=\"hg-cmd\">hg log -vpr2</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:420
+msgid ""
+"In the examples throughout this book, I use short options instead of long.  "
+"This just reflects my own preference, so don't read anything significant into "
+"it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:424
+msgid ""
+"Most commands that print output of some kind will print more output when "
+"passed a <option role=\"hg-opt-global\">-v</option> (or <option role=\"hg-opt-"
+"global\">--verbose</option>) option, and less when passed <option role=\"hg-"
+"opt-global\">-q</option> (or <option role=\"hg-opt-global\">--quiet</option>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><title>
+#: ../en/ch01-tour-basic.xml:431
+msgid "Option naming consistency"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch01-tour-basic.xml:433
+msgid ""
+"Almost always, Mercurial commands use consistent option names to refer to the "
+"same concepts.  For instance, if a command deals with changesets, you'll "
+"always identify them with <option role=\"hg-opt-log\">--rev</option> or "
+"<option role=\"hg-opt-log\">-r</option>.  This consistent use of option names "
+"makes it easier to remember what options a particular command takes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:444
+msgid "Making and reviewing changes"
+msgstr "创建和复审修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:446
+msgid ""
+"Now that we have a grasp of viewing history in Mercurial, let's take a look "
+"at making some changes and examining them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:450
+msgid ""
+"The first thing we'll do is isolate our experiment in a repository of its "
+"own.  We use the <command role=\"hg-cmd\">hg clone</command> command, but we "
+"don't need to clone a copy of the remote repository.  Since we already have a "
+"copy of it locally, we can just clone that instead.  This is much faster than "
+"cloning over the network, and cloning a local repository uses less disk space "
+"in most cases, too<placeholder type=\"footnote\" id=\"0\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para><footnote><para>
+#: ../en/ch01-tour-basic.xml:457
+msgid ""
+"The saving of space arises when source and destination repositories are on "
+"the same filesystem, in which case Mercurial will use hardlinks to do copy-on-"
+"write sharing of its internal metadata.  If that explanation meant nothing to "
+"you, don't worry: everything happens transparently and automatically, and you "
+"don't need to understand it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:467
+msgid ""
+"As an aside, it's often good practice to keep a <quote>pristine</quote> copy "
+"of a remote repository around, which you can then make temporary clones of to "
+"create sandboxes for each task you want to work on.  This lets you work on "
+"multiple tasks in parallel, each isolated from the others until it's complete "
+"and you're ready to integrate it back.  Because local clones are so cheap, "
+"there's almost no overhead to cloning and destroying repositories whenever "
+"you want."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:476
+msgid ""
+"In our <filename class=\"directory\">my-hello</filename> repository, we have "
+"a file <filename>hello.c</filename> that contains the classic <quote>hello, "
+"world</quote> program."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:482
+msgid "Let's edit this file so that it prints a second line of output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:487
+msgid ""
+"Mercurial's <command role=\"hg-cmd\">hg status</command> command will tell us "
+"what Mercurial knows about the files in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:493
+msgid ""
+"The <command role=\"hg-cmd\">hg status</command> command prints no output for "
+"some files, but a line starting with <quote><literal>M</literal></quote> for "
+"<filename>hello.c</filename>.  Unless you tell it to, <command role=\"hg-cmd"
+"\">hg status</command> will not print any output for files that have not been "
+"modified."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:500
+msgid ""
+"The <quote><literal>M</literal></quote> indicates that Mercurial has noticed "
+"that we modified <filename>hello.c</filename>.  We didn't need to "
+"<emphasis>inform</emphasis> Mercurial that we were going to modify the file "
+"before we started, or that we had modified the file after we were done; it "
+"was able to figure this out itself."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:508
+msgid ""
+"It's somewhat helpful to know that we've modified <filename>hello.c</"
+"filename>, but we might prefer to know exactly <emphasis>what</emphasis> "
+"changes we've made to it.  To do this, we use the <command role=\"hg-cmd\">hg "
+"diff</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:517 ../en/ch11-mq.xml:187
+msgid "Understanding patches"
+msgstr "理解补丁"
+
+#. type: Content of: <book><chapter><sect1><tip><para>
+#: ../en/ch01-tour-basic.xml:519
+msgid ""
+"Remember to take a look at <xref linkend=\"sec:mq:patch\"/> if you don't know "
+"how to read output above."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:525
+msgid "Recording changes in a new changeset"
+msgstr "在新修改集中记录修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:527
+msgid ""
+"We can modify files, build and test our changes, and use <command role=\"hg-"
+"cmd\">hg status</command> and <command role=\"hg-cmd\">hg diff</command> to "
+"review our changes, until we're satisfied with what we've done and arrive at "
+"a natural stopping point where we want to record our work in a new changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:534
+msgid ""
+"The <command role=\"hg-cmd\">hg commit</command> command lets us create a new "
+"changeset; we'll usually refer to this as <quote>making a commit</quote> or "
+"<quote>committing</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:540
+msgid "Setting up a username"
+msgstr "配置用户名称"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:542
+msgid ""
+"When you try to run <command role=\"hg-cmd\">hg commit</command> for the "
+"first time, it is not guaranteed to succeed.  Mercurial records your name and "
+"address with each change that you commit, so that you and others will later "
+"be able to tell who made each change.  Mercurial tries to automatically "
+"figure out a sensible username to commit the change with.  It will attempt "
+"each of the following methods, in order:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:551
+msgid ""
+"If you specify a <option role=\"hg-opt-commit\">-u</option> option to the "
+"<command role=\"hg-cmd\">hg commit</command> command on the command line, "
+"followed by a username, this is always given the highest precedence."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:556
+msgid ""
+"If you have set the <envar>HGUSER</envar> environment variable, this is "
+"checked next."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:559
+msgid ""
+"If you create a file in your home directory called <filename role=\"special"
+"\">.hgrc</filename>, with a <envar role=\"rc-item-ui\">username</envar> "
+"entry, that will be used next.  To see what the contents of this file should "
+"look like, refer to <xref linkend=\"sec:tour-basic:username\"/> below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:567
+msgid ""
+"If you have set the <envar>EMAIL</envar> environment variable, this will be "
+"used next."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:570
+msgid ""
+"Mercurial will query your system to find out your local user name and host "
+"name, and construct a username from these components. Since this often "
+"results in a username that is not very useful, it will print a warning if it "
+"has to do this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:577
+msgid ""
+"If all of these mechanisms fail, Mercurial will fail, printing an error "
+"message.  In this case, it will not let you commit until you set up a "
+"username."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:581
+msgid ""
+"You should think of the <envar>HGUSER</envar> environment variable and the "
+"<option role=\"hg-opt-commit\">-u</option> option to the <command role=\"hg-"
+"cmd\">hg commit</command> command as ways to <emphasis>override</emphasis> "
+"Mercurial's default selection of username.  For normal use, the simplest and "
+"most robust way to set a username for yourself is by creating a <filename "
+"role=\"special\">.hgrc</filename> file; see below for details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch01-tour-basic.xml:590
+msgid "Creating a Mercurial configuration file"
+msgstr "创建 Mercurial 的配置文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch01-tour-basic.xml:592
+msgid ""
+"To set a user name, use your favourite editor to create a file called "
+"<filename role=\"special\">.hgrc</filename> in your home directory.  "
+"Mercurial will use this file to look up your personalised configuration "
+"settings.  The initial contents of your <filename role=\"special\">.hgrc</"
+"filename> should look like this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><remark>
+#: ../en/ch01-tour-basic.xml:600
+msgid "Figure out what the appropriate directory is on Windows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch01-tour-basic.xml:607
+msgid ""
+"The <quote><literal>[ui]</literal></quote> line begins a <emphasis>section</"
+"emphasis> of the config file, so you can read the <quote><literal>username "
+"= ...</literal></quote> line as meaning <quote>set the value of the "
+"<literal>username</literal> item in the <literal>ui</literal> section</"
+"quote>. A section continues until a new section begins, or the end of the "
+"file.  Mercurial ignores empty lines and treats any text from "
+"<quote><literal>#</literal></quote> to the end of a line as a comment."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch01-tour-basic.xml:620
+msgid "Choosing a user name"
+msgstr "选择用户名称"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch01-tour-basic.xml:622
+msgid ""
+"You can use any text you like as the value of the <literal>username</literal> "
+"config item, since this information is for reading by other people, but will "
+"not be interpreted by Mercurial.  The convention that most people follow is "
+"to use their name and email address, as in the example above."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><note><para>
+#: ../en/ch01-tour-basic.xml:629
+msgid ""
+"Mercurial's built-in web server obfuscates email addresses, to make it more "
+"difficult for the email harvesting tools that spammers use. This reduces the "
+"likelihood that you'll start receiving more junk email if you publish a "
+"Mercurial repository on the web."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:639
+msgid "Writing a commit message"
+msgstr "写提交日志"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:641
+msgid ""
+"When we commit a change, Mercurial drops us into a text editor, to enter a "
+"message that will describe the modifications we've made in this changeset.  "
+"This is called the <emphasis>commit message</emphasis>.  It will be a record "
+"for readers of what we did and why, and it will be printed by <command role="
+"\"hg-cmd\">hg log</command> after we've finished committing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:651
+msgid ""
+"The editor that the <command role=\"hg-cmd\">hg commit</command> command "
+"drops us into will contain an empty line or two, followed by a number of "
+"lines starting with <quote><literal>HG:</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:665
+msgid ""
+"Mercurial ignores the lines that start with <quote><literal>HG:</literal></"
+"quote>; it uses them only to tell us which files it's recording changes to.  "
+"Modifying or deleting these lines has no effect."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:671
+msgid "Writing a good commit message"
+msgstr "写好提交日志"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:673
+msgid ""
+"Since <command role=\"hg-cmd\">hg log</command> only prints the first line of "
+"a commit message by default, it's best to write a commit message whose first "
+"line stands alone.  Here's a real example of a commit message that "
+"<emphasis>doesn't</emphasis> follow this guideline, and hence has a summary "
+"that is not readable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:687
+msgid ""
+"As far as the remainder of the contents of the commit message are concerned, "
+"there are no hard-and-fast rules.  Mercurial itself doesn't interpret or care "
+"about the contents of the commit message, though your project may have "
+"policies that dictate a certain kind of formatting."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:693
+msgid ""
+"My personal preference is for short, but informative, commit messages that "
+"tell me something that I can't figure out with a quick glance at the output "
+"of <command role=\"hg-cmd\">hg log --patch</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:700
+msgid "Aborting a commit"
+msgstr "终止提交"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:702
+msgid ""
+"If you decide that you don't want to commit while in the middle of editing a "
+"commit message, simply exit from your editor without saving the file that "
+"it's editing.  This will cause nothing to happen to either the repository or "
+"the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:707
+msgid ""
+"If we run the <command role=\"hg-cmd\">hg commit</command> command without "
+"any arguments, it records all of the changes we've made, as reported by "
+"<command role=\"hg-cmd\">hg status</command> and <command role=\"hg-cmd\">hg "
+"diff</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:714
+msgid "Admiring our new handiwork"
+msgstr "欣赏我们的成果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:716
+msgid ""
+"Once we've finished the commit, we can use the <command role=\"hg-cmd\">hg "
+"tip</command> command to display the changeset we just created.  This command "
+"produces output that is identical to <command role=\"hg-cmd\">hg log</"
+"command>, but it only displays the newest revision in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:725
+msgid ""
+"We refer to the newest revision in the repository as the <emphasis>tip "
+"revision</emphasis>, or simply the <emphasis>tip</emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:729
+msgid ""
+"By the way, the <command role=\"hg-cmd\">hg tip</command> command accepts "
+"many of the same options as <command role=\"hg-cmd\">hg log</command>, so "
+"<option role=\"hg-opt-global\">-v</option> above indicates <quote>be verbose</"
+"quote>, <option role=\"hg-opt-tip\">-p</option> specifies <quote>print a "
+"patch</quote>.  The use of <option role=\"hg-opt-tip\">-p</option> to print "
+"patches is another example of the consistent naming we mentioned earlier."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:741
+msgid "Sharing changes"
+msgstr "共享修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:743
+msgid ""
+"We mentioned earlier that repositories in Mercurial are self-contained.  This "
+"means that the changeset we just created exists only in our <filename class="
+"\"directory\">my-hello</filename> repository.  Let's look at a few ways that "
+"we can propagate this change into other repositories."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:751
+msgid "Pulling changes from another repository"
+msgstr "从其它版本库取得修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:752
+msgid ""
+"To get started, let's clone our original <filename class=\"directory\">hello</"
+"filename> repository, which does not contain the change we just committed.  "
+"We'll call our temporary repository <filename class=\"directory\">hello-pull</"
+"filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:760
+msgid ""
+"We'll use the <command role=\"hg-cmd\">hg pull</command> command to bring "
+"changes from <filename class=\"directory\">my-hello</filename> into <filename "
+"class=\"directory\">hello-pull</filename>.  However, blindly pulling unknown "
+"changes into a repository is a somewhat scary prospect.  Mercurial provides "
+"the <command role=\"hg-cmd\">hg incoming</command> command to tell us what "
+"changes the <command role=\"hg-cmd\">hg pull</command> command "
+"<emphasis>would</emphasis> pull into the repository, without actually pulling "
+"the changes in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:773
+msgid ""
+"Suppose you're pulling changes from a repository on the network somewhere. "
+"While you are looking at the <command role=\"hg-cmd\">hg incoming</command> "
+"output, and before you pull those changes, someone might have committed "
+"something in the remote repository. This means that it's possible to pull "
+"more changes than you saw when using <command role=\"hg-cmd\">hg incoming</"
+"command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:781
+msgid ""
+"Bringing changes into a repository is a simple matter of running the <command "
+"role=\"hg-cmd\">hg pull</command> command, and telling it which repository to "
+"pull from."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:788
+msgid ""
+"As you can see from the before-and-after output of <command role=\"hg-cmd"
+"\">hg tip</command>, we have successfully pulled changes into our "
+"repository.  There remains one step before we can see these changes in the "
+"working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:796
+msgid "Updating the working directory"
+msgstr "更新工作目录"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:798
+msgid ""
+"We have so far glossed over the relationship between a repository and its "
+"working directory.  The <command role=\"hg-cmd\">hg pull</command> command "
+"that we ran in <xref linkend=\"sec:tour:pull\"/> brought changes into the "
+"repository, but if we check, there's no sign of those changes in the working "
+"directory.  This is because <command role=\"hg-cmd\">hg pull</command> does "
+"not (by default) touch the working directory.  Instead, we use the <command "
+"role=\"hg-cmd\">hg update</command> command to do this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:810
+msgid ""
+"It might seem a bit strange that <command role=\"hg-cmd\">hg pull</command> "
+"doesn't update the working directory automatically.  There's actually a good "
+"reason for this: you can use <command role=\"hg-cmd\">hg update</command> to "
+"update the working directory to the state it was in at <emphasis>any "
+"revision</emphasis> in the history of the repository.  If you had the working "
+"directory updated to an old revision&emdash;to hunt down the origin of a bug, "
+"say&emdash;and ran a <command role=\"hg-cmd\">hg pull</command> which "
+"automatically updated the working directory to a new revision, you might not "
+"be terribly happy."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:821
+msgid ""
+"However, since pull-then-update is such a common thing to do, Mercurial lets "
+"you combine the two by passing the <option role=\"hg-opt-pull\">-u</option> "
+"option to <command role=\"hg-cmd\">hg pull</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:826
+msgid ""
+"If you look back at the output of <command role=\"hg-cmd\">hg pull</command> "
+"in <xref linkend=\"sec:tour:pull\"/> when we ran it without <option role=\"hg-"
+"opt-pull\">-u</option>, you can see that it printed a helpful reminder that "
+"we'd have to take an explicit step to update the working directory:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:835
+msgid ""
+"To find out what revision the working directory is at, use the <command role="
+"\"hg-cmd\">hg parents</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:841
+msgid ""
+"If you look back at <xref linkend=\"fig:tour-basic:history\"/>, you'll see "
+"arrows connecting each changeset.  The node that the arrow leads "
+"<emphasis>from</emphasis> in each case is a parent, and the node that the "
+"arrow leads <emphasis>to</emphasis> is its child.  The working directory has "
+"a parent in just the same way; this is the changeset that the working "
+"directory currently contains."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:850
+msgid ""
+"To update the working directory to a particular revision, give a revision "
+"number or changeset ID to the <command role=\"hg-cmd\">hg update</command> "
+"command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:857
+msgid ""
+"If you omit an explicit revision, <command role=\"hg-cmd\">hg update</"
+"command> will update to the tip revision, as shown by the second call to "
+"<command role=\"hg-cmd\">hg update</command> in the example above."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:865
+msgid "Pushing changes to another repository"
+msgstr "发布修改到其它版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:867
+msgid ""
+"Mercurial lets us push changes to another repository, from the repository "
+"we're currently visiting.  As with the example of <command role=\"hg-cmd\">hg "
+"pull</command> above, we'll create a temporary repository to push our changes "
+"into."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:875
+msgid ""
+"The <command role=\"hg-cmd\">hg outgoing</command> command tells us what "
+"changes would be pushed into another repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:881
+msgid ""
+"And the <command role=\"hg-cmd\">hg push</command> command does the actual "
+"push."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:887
+msgid ""
+"As with <command role=\"hg-cmd\">hg pull</command>, the <command role=\"hg-cmd"
+"\">hg push</command> command does not update the working directory in the "
+"repository that it's pushing changes into. Unlike <command role=\"hg-cmd\">hg "
+"pull</command>, <command role=\"hg-cmd\">hg push</command> does not provide a "
+"<literal>-u</literal> option that updates the other repository's working "
+"directory.  This asymmetry is deliberate: the repository we're pushing to "
+"might be on a remote server and shared between several people.  If we were to "
+"update its working directory while someone was working in it, their work "
+"would be disrupted."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:899
+msgid ""
+"What happens if we try to pull or push changes and the receiving repository "
+"already has those changes? Nothing too exciting."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:906
+msgid "Sharing changes over a network"
+msgstr "通过网络共享修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:908
+msgid ""
+"The commands we have covered in the previous few sections are not limited to "
+"working with local repositories.  Each works in exactly the same fashion over "
+"a network connection; simply pass in a URL instead of a local path."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:916
+msgid ""
+"In this example, we can see what changes we could push to the remote "
+"repository, but the repository is understandably not set up to let anonymous "
+"users push to it."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch02-tour-merge.xml:5
+msgid "A tour of Mercurial: merging work"
+msgstr "Mercurial 教程: 合并工作"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch02-tour-merge.xml:7
+msgid ""
+"We've now covered cloning a repository, making changes in a repository, and "
+"pulling or pushing changes from one repository into another.  Our next step "
+"is <emphasis>merging</emphasis> changes from separate repositories."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch02-tour-merge.xml:13
+msgid "Merging streams of work"
+msgstr "合并的流程"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:15
+msgid ""
+"Merging is a fundamental part of working with a distributed revision control "
+"tool."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch02-tour-merge.xml:18
+msgid ""
+"Alice and Bob each have a personal copy of a repository for a project they're "
+"collaborating on.  Alice fixes a bug in her repository; Bob adds a new "
+"feature in his.  They want the shared repository to contain both the bug fix "
+"and the new feature."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch02-tour-merge.xml:24
+msgid ""
+"I frequently work on several different tasks for a single project at once, "
+"each safely isolated in its own repository. Working this way means that I "
+"often need to merge one piece of my own work with another."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:30
+msgid ""
+"Because merging is such a common thing to need to do, Mercurial makes it "
+"easy.  Let's walk through the process.  We'll begin by cloning yet another "
+"repository (see how often they spring up?) and making a change in it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:37
+msgid ""
+"We should now have two copies of <filename>hello.c</filename> with different "
+"contents.  The histories of the two repositories have also diverged, as "
+"illustrated in <xref linkend=\"fig:tour-merge:sep-repos\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><figure><title>
+#: ../en/ch02-tour-merge.xml:46
+msgid ""
+"Divergent recent histories of the <filename class=\"directory\">my-hello</"
+"filename> and <filename class=\"directory\">my-new-hello</filename> "
+"repositories"
+msgstr ""
+"<filename class=\"directory\">my-hello</filename> 与 <filename class="
+"\"directory\">my-new-hello</filename> 最新的历史分叉"
+
+#. type: Content of: <book><chapter><sect1><figure><mediaobject>
+#: ../en/ch02-tour-merge.xml:51
+msgid ""
+"<imageobject><imagedata fileref=\"figs/tour-merge-sep-repos.png\"/></"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:56
+msgid ""
+"We already know that pulling changes from our <filename class=\"directory"
+"\">my-hello</filename> repository will have no effect on the working "
+"directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:62
+msgid ""
+"However, the <command role=\"hg-cmd\">hg pull</command> command says "
+"something about <quote>heads</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch02-tour-merge.xml:66
+msgid "Head changesets"
+msgstr "顶点修改集"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:68
+msgid ""
+"A head is a change that has no descendants, or children, as they're also "
+"known.  The tip revision is thus a head, because the newest revision in a "
+"repository doesn't have any children, but a repository can contain more than "
+"one head."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch02-tour-merge.xml:75
+msgid ""
+"Repository contents after pulling from <filename class=\"directory\">my-"
+"hello</filename> into <filename class=\"directory\">my-new-hello</filename>"
+msgstr ""
+"从 <filename class=\"directory\">my-hello</filename> 拉到 <filename class="
+"\"directory\">my-new-hello</filename> 之后版本库的内容"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure>
+#: ../en/ch02-tour-merge.xml:78 ../en/ch02-tour-merge.xml:125
+#: ../en/ch02-tour-merge.xml:250 ../en/ch03-concepts.xml:55
+#: ../en/ch03-concepts.xml:104 ../en/ch03-concepts.xml:189
+#: ../en/ch03-concepts.xml:344 ../en/ch03-concepts.xml:359
+#: ../en/ch03-concepts.xml:400 ../en/ch03-concepts.xml:420
+#: ../en/ch03-concepts.xml:461 ../en/ch05-collab.xml:274
+#: ../en/ch08-undo.xml:363 ../en/ch08-undo.xml:410 ../en/ch08-undo.xml:475
+#: ../en/ch08-undo.xml:513 ../en/ch11-mq.xml:410
+msgid "  <placeholder type=\"mediaobject\" id=\"0\"/>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch02-tour-merge.xml:79
+msgid ""
+"<imageobject> <imagedata fileref=\"figs/tour-merge-pull.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:86
+msgid ""
+"In <xref linkend=\"fig:tour-merge:pull\"/>, you can see the effect of the "
+"pull from <filename class=\"directory\">my-hello</filename> into <filename "
+"class=\"directory\">my-new-hello</filename>.  The history that was already "
+"present in <filename class=\"directory\">my-new-hello</filename> is "
+"untouched, but a new revision has been added.  By referring to <xref linkend="
+"\"fig:tour-merge:sep-repos\"/>, we can see that the <emphasis>changeset ID</"
+"emphasis> remains the same in the new repository, but the <emphasis>revision "
+"number</emphasis> has changed.  (This, incidentally, is a fine example of why "
+"it's not safe to use revision numbers when discussing changesets.)  We can "
+"view the heads in a repository using the <command role=\"hg-cmd\">hg heads</"
+"command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch02-tour-merge.xml:105
+msgid "Performing the merge"
+msgstr "执行合并"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:107
+msgid ""
+"What happens if we try to use the normal <command role=\"hg-cmd\">hg update</"
+"command> command to update to the new tip?"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:113
+msgid ""
+"Mercurial is telling us that the <command role=\"hg-cmd\">hg update</command> "
+"command won't do a merge; it won't update the working directory when it "
+"thinks we might be wanting to do a merge, unless we force it to do so.  "
+"Instead, we use the <command role=\"hg-cmd\">hg merge</command> command to "
+"merge the two heads."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch02-tour-merge.xml:123
+msgid "Working directory and repository during merge, and following commit"
+msgstr "在合并期间,以及提交之后的工作目录与版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch02-tour-merge.xml:126
+msgid ""
+"<imageobject> <imagedata fileref=\"figs/tour-merge-merge.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:133
+msgid ""
+"This updates the working directory so that it contains changes from "
+"<emphasis>both</emphasis> heads, which is reflected in both the output of "
+"<command role=\"hg-cmd\">hg parents</command> and the contents of "
+"<filename>hello.c</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch02-tour-merge.xml:143
+msgid "Committing the results of the merge"
+msgstr "提交合并结果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:145
+msgid ""
+"Whenever we've done a merge, <command role=\"hg-cmd\">hg parents</command> "
+"will display two parents until we <command role=\"hg-cmd\">hg commit</"
+"command> the results of the merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:152
+msgid ""
+"We now have a new tip revision; notice that it has <emphasis>both</emphasis> "
+"of our former heads as its parents.  These are the same revisions that were "
+"previously displayed by <command role=\"hg-cmd\">hg parents</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:159
+msgid ""
+"In <xref linkend=\"fig:tour-merge:merge\"/>, you can see a representation of "
+"what happens to the working directory during the merge, and how this affects "
+"the repository when the commit happens.  During the merge, the working "
+"directory has two parent changesets, and these become the parents of the new "
+"changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch02-tour-merge.xml:170
+msgid "Merging conflicting changes"
+msgstr "合并有冲突的改变"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:172
+msgid ""
+"Most merges are simple affairs, but sometimes you'll find yourself merging "
+"changes where each modifies the same portions of the same files.  Unless both "
+"modifications are identical, this results in a <emphasis>conflict</emphasis>, "
+"where you have to decide how to reconcile the different changes into "
+"something coherent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><figure><title>
+#: ../en/ch02-tour-merge.xml:180
+msgid "Conflicting changes to a document"
+msgstr "冲突的修改"
+
+#. type: Content of: <book><chapter><sect1><figure><mediaobject>
+#: ../en/ch02-tour-merge.xml:182
+msgid ""
+"<imageobject><imagedata fileref=\"figs/tour-merge-conflict.png\"/></"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:187
+msgid ""
+"<xref linkend=\"fig:tour-merge:conflict\"/> illustrates an instance of two "
+"conflicting changes to a document.  We started with a single version of the "
+"file; then we made some changes; while someone else made different changes to "
+"the same text.  Our task in resolving the conflicting changes is to decide "
+"what the file should look like."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:194
+msgid ""
+"Mercurial doesn't have a built-in facility for handling conflicts. Instead, "
+"it runs an external program called <command>hgmerge</command>.  This is a "
+"shell script that is bundled with Mercurial; you can change it to behave "
+"however you please.  What it does by default is try to find one of several "
+"different merging tools that are likely to be installed on your system.  It "
+"first tries a few fully automatic merging tools; if these don't succeed "
+"(because the resolution process requires human guidance) or aren't present, "
+"the script tries a few different graphical merging tools."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:205
+msgid ""
+"It's also possible to get Mercurial to run another program or script instead "
+"of <command>hgmerge</command>, by setting the <envar>HGMERGE</envar> "
+"environment variable to the name of your preferred program."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch02-tour-merge.xml:211
+msgid "Using a graphical merge tool"
+msgstr "使用图形合并工具"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:213
+msgid ""
+"My preferred graphical merge tool is <command>kdiff3</command>, which I'll "
+"use to describe the features that are common to graphical file merging "
+"tools.  You can see a screenshot of <command>kdiff3</command> in action in "
+"<xref linkend=\"fig:tour-merge:kdiff3\"/>.  The kind of merge it is "
+"performing is called a <emphasis>three-way merge</emphasis>, because there "
+"are three different versions of the file of interest to us.  The tool thus "
+"splits the upper portion of the window into three panes:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch02-tour-merge.xml:223
+msgid ""
+"At the left is the <emphasis>base</emphasis> version of the file, i.e. the "
+"most recent version from which the two versions we're trying to merge are "
+"descended."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch02-tour-merge.xml:228
+msgid ""
+"In the middle is <quote>our</quote> version of the file, with the contents "
+"that we modified."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch02-tour-merge.xml:231
+msgid ""
+"On the right is <quote>their</quote> version of the file, the one that from "
+"the changeset that we're trying to merge with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:235
+msgid ""
+"In the pane below these is the current <emphasis>result</emphasis> of the "
+"merge. Our task is to replace all of the red text, which indicates unresolved "
+"conflicts, with some sensible merger of the <quote>ours</quote> and "
+"<quote>theirs</quote> versions of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:242
+msgid ""
+"All four of these panes are <emphasis>locked together</emphasis>; if we "
+"scroll vertically or horizontally in any of them, the others are updated to "
+"display the corresponding sections of their respective files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch02-tour-merge.xml:248
+msgid "Using <command>kdiff3</command> to merge versions of a file"
+msgstr "使用 <command>kdiff3</command> 合并文件的不同版本"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch02-tour-merge.xml:251
+msgid ""
+"<imageobject> <imagedata width=\"100%\" fileref=\"figs/kdiff3.png\"/></"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:259
+msgid ""
+"For each conflicting portion of the file, we can choose to resolve the "
+"conflict using some combination of text from the base version, ours, or "
+"theirs.  We can also manually edit the merged file at any time, in case we "
+"need to make further modifications."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:265
+msgid ""
+"There are <emphasis>many</emphasis> file merging tools available, too many to "
+"cover here.  They vary in which platforms they are available for, and in "
+"their particular strengths and weaknesses.  Most are tuned for merging files "
+"containing plain text, while a few are aimed at specialised file formats "
+"(generally XML)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch02-tour-merge.xml:274
+msgid "A worked example"
+msgstr "合并实例"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:276
+msgid ""
+"In this example, we will reproduce the file modification history of <xref "
+"linkend=\"fig:tour-merge:conflict\"/> above.  Let's begin by creating a "
+"repository with a base version of our document."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:283
+msgid "We'll clone the repository and make a change to the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:288
+msgid ""
+"And another clone, to simulate someone else making a change to the file. "
+"(This hints at the idea that it's not all that unusual to merge with yourself "
+"when you isolate tasks in separate repositories, and indeed to find and "
+"resolve conflicts while doing so.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:296
+msgid ""
+"Having created two different versions of the file, we'll set up an "
+"environment suitable for running our merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:302
+msgid ""
+"In this example, I won't use Mercurial's normal <command>hgmerge</command> "
+"program to do the merge, because it would drop my nice automated example-"
+"running tool into a graphical user interface.  Instead, I'll set "
+"<envar>HGMERGE</envar> to tell Mercurial to use the non-interactive "
+"<command>merge</command> command.  This is bundled with many Unix-like "
+"systems. If you're following this example on your computer, don't bother "
+"setting <envar>HGMERGE</envar>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:312
+msgid "<emphasis role=\"bold\">XXX FIX THIS EXAMPLE.</emphasis>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:317
+msgid ""
+"Because <command>merge</command> can't resolve the conflicting changes, it "
+"leaves <emphasis>merge markers</emphasis> inside the file that has conflicts, "
+"indicating which lines have conflicts, and whether they came from our version "
+"of the file or theirs."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:323
+msgid ""
+"Mercurial can tell from the way <command>merge</command> exits that it wasn't "
+"able to merge successfully, so it tells us what commands we'll need to run if "
+"we want to redo the merging operation.  This could be useful if, for example, "
+"we were running a graphical merge tool and quit because we were confused or "
+"realised we had made a mistake."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:330
+msgid ""
+"If automatic or manual merges fail, there's nothing to prevent us from "
+"<quote>fixing up</quote> the affected files ourselves, and committing the "
+"results of our merge:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch02-tour-merge.xml:339
+msgid "Simplifying the pull-merge-commit sequence"
+msgstr "简化拉-合并-提交程序"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:341
+msgid ""
+"The process of merging changes as outlined above is straightforward, but "
+"requires running three commands in sequence."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:347
+msgid ""
+"In the case of the final commit, you also need to enter a commit message, "
+"which is almost always going to be a piece of uninteresting "
+"<quote>boilerplate</quote> text."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:351
+msgid ""
+"It would be nice to reduce the number of steps needed, if this were "
+"possible.  Indeed, Mercurial is distributed with an extension called <literal "
+"role=\"hg-ext\">fetch</literal> that does just this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:356
+msgid ""
+"Mercurial provides a flexible extension mechanism that lets people extend its "
+"functionality, while keeping the core of Mercurial small and easy to deal "
+"with.  Some extensions add new commands that you can use from the command "
+"line, while others work <quote>behind the scenes,</quote> for example adding "
+"capabilities to the server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:363
+msgid ""
+"The <literal role=\"hg-ext\">fetch</literal> extension adds a new command "
+"called, not surprisingly, <command role=\"hg-cmd\">hg fetch</command>.  This "
+"extension acts as a combination of <command role=\"hg-cmd\">hg pull</"
+"command>, <command role=\"hg-cmd\">hg update</command> and <command role=\"hg-"
+"cmd\">hg merge</command>.  It begins by pulling changes from another "
+"repository into the current repository.  If it finds that the changes added a "
+"new head to the repository, it begins a merge, then commits the result of the "
+"merge with an automatically-generated commit message.  If no new heads were "
+"added, it updates the working directory to the new tip changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:376
+msgid ""
+"Enabling the <literal role=\"hg-ext\">fetch</literal> extension is easy.  "
+"Edit your <filename role=\"special\">.hgrc</filename>, and either go to the "
+"<literal role=\"rc-extensions\">extensions</literal> section or create an "
+"<literal role=\"rc-extensions\">extensions</literal> section. Then add a line "
+"that simply reads <quote><literal>fetch </literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:385
+msgid ""
+"(Normally, on the right-hand side of the <quote><literal>=</literal></quote> "
+"would appear the location of the extension, but since the <literal role=\"hg-"
+"ext\">fetch</literal> extension is in the standard distribution, Mercurial "
+"knows where to search for it.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch03-concepts.xml:5
+msgid "Behind the scenes"
+msgstr "Mercurial 内幕"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch03-concepts.xml:7
+msgid ""
+"Unlike many revision control systems, the concepts upon which Mercurial is "
+"built are simple enough that it's easy to understand how the software really "
+"works.  Knowing this certainly isn't necessary, but I find it useful to have "
+"a <quote>mental model</quote> of what's going on."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch03-concepts.xml:13
+msgid ""
+"This understanding gives me confidence that Mercurial has been carefully "
+"designed to be both <emphasis>safe</emphasis> and <emphasis>efficient</"
+"emphasis>.  And just as importantly, if it's easy for me to retain a good "
+"idea of what the software is doing when I perform a revision control task, "
+"I'm less likely to be surprised by its behaviour."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch03-concepts.xml:20
+msgid ""
+"In this chapter, we'll initially cover the core concepts behind Mercurial's "
+"design, then continue to discuss some of the interesting details of its "
+"implementation."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:25
+msgid "Mercurial's historical record"
+msgstr "Mercurial 的历史记录"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:28
+msgid "Tracking the history of a single file"
+msgstr "跟踪单一文件的历史"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:30
+msgid ""
+"When Mercurial tracks modifications to a file, it stores the history of that "
+"file in a metadata object called a <emphasis>filelog</emphasis>.  Each entry "
+"in the filelog contains enough information to reconstruct one revision of the "
+"file that is being tracked.  Filelogs are stored as files in the <filename "
+"role=\"special\" class=\"directory\">.hg/store/data</filename> directory.  A "
+"filelog contains two kinds of information: revision data, and an index to "
+"help Mercurial to find a revision efficiently."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:41
+msgid ""
+"A file that is large, or has a lot of history, has its filelog stored in "
+"separate data (<quote><literal>.d</literal></quote> suffix) and index "
+"(<quote><literal>.i</literal></quote> suffix) files.  For small files without "
+"much history, the revision data and index are combined in a single "
+"<quote><literal>.i</literal></quote> file.  The correspondence between a file "
+"in the working directory and the filelog that tracks its history in the "
+"repository is illustrated in <xref linkend=\"fig:concepts:filelog\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:53
+msgid ""
+"Relationships between files in working directory and filelogs in repository"
+msgstr "工作目录中的文件与版本库中的文件日志之间的关系"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:56
+msgid "<imageobject><imagedata fileref=\"figs/filelog.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:63
+msgid "Managing tracked files"
+msgstr "管理跟踪的文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:65
+msgid ""
+"Mercurial uses a structure called a <emphasis>manifest</emphasis> to collect "
+"together information about the files that it tracks.  Each entry in the "
+"manifest contains information about the files present in a single changeset.  "
+"An entry records which files are present in the changeset, the revision of "
+"each file, and a few other pieces of file metadata."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:75
+msgid "Recording changeset information"
+msgstr "记录修改集信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:77
+msgid ""
+"The <emphasis>changelog</emphasis> contains information about each "
+"changeset.  Each revision records who committed a change, the changeset "
+"comment, other pieces of changeset-related information, and the revision of "
+"the manifest to use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:85
+msgid "Relationships between revisions"
+msgstr "版本之间的关系"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:87
+msgid ""
+"Within a changelog, a manifest, or a filelog, each revision stores a pointer "
+"to its immediate parent (or to its two parents, if it's a merge revision).  "
+"As I mentioned above, there are also relationships between revisions "
+"<emphasis>across</emphasis> these structures, and they are hierarchical in "
+"nature."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:94
+msgid ""
+"For every changeset in a repository, there is exactly one revision stored in "
+"the changelog.  Each revision of the changelog contains a pointer to a single "
+"revision of the manifest.  A revision of the manifest stores a pointer to a "
+"single revision of each filelog tracked when that changeset was created.  "
+"These relationships are illustrated in <xref linkend=\"fig:concepts:metadata"
+"\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:103
+msgid "Metadata relationships"
+msgstr "元数据之间的关系"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:105
+msgid "<imageobject><imagedata fileref=\"figs/metadata.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:110
+msgid ""
+"As the illustration shows, there is <emphasis>not</emphasis> a <quote>one to "
+"one</quote> relationship between revisions in the changelog, manifest, or "
+"filelog. If the manifest hasn't changed between two changesets, the changelog "
+"entries for those changesets will point to the same revision of the "
+"manifest.  If a file that Mercurial tracks hasn't changed between two "
+"changesets, the entry for that file in the two revisions of the manifest will "
+"point to the same revision of its filelog."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:123
+msgid "Safe, efficient storage"
+msgstr "安全,高效的存储"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:125
+msgid ""
+"The underpinnings of changelogs, manifests, and filelogs are provided by a "
+"single structure called the <emphasis>revlog</emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:130
+msgid "Efficient storage"
+msgstr "高效存储"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:132
+msgid ""
+"The revlog provides efficient storage of revisions using a <emphasis>delta</"
+"emphasis> mechanism.  Instead of storing a complete copy of a file for each "
+"revision, it stores the changes needed to transform an older revision into "
+"the new revision.  For many kinds of file data, these deltas are typically a "
+"fraction of a percent of the size of a full copy of a file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:140
+msgid ""
+"Some obsolete revision control systems can only work with deltas of text "
+"files.  They must either store binary files as complete snapshots or encoded "
+"into a text representation, both of which are wasteful approaches.  Mercurial "
+"can efficiently handle deltas of files with arbitrary binary contents; it "
+"doesn't need to treat text as special."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:149
+msgid "Safe operation"
+msgstr "安全操作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:151
+msgid ""
+"Mercurial only ever <emphasis>appends</emphasis> data to the end of a revlog "
+"file. It never modifies a section of a file after it has written it.  This is "
+"both more robust and efficient than schemes that need to modify or rewrite "
+"data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:157
+msgid ""
+"In addition, Mercurial treats every write as part of a <emphasis>transaction</"
+"emphasis> that can span a number of files.  A transaction is "
+"<emphasis>atomic</emphasis>: either the entire transaction succeeds and its "
+"effects are all visible to readers in one go, or the whole thing is undone.  "
+"This guarantee of atomicity means that if you're running two copies of "
+"Mercurial, where one is reading data and one is writing it, the reader will "
+"never see a partially written result that might confuse it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:167
+msgid ""
+"The fact that Mercurial only appends to files makes it easier to provide this "
+"transactional guarantee.  The easier it is to do stuff like this, the more "
+"confident you should be that it's done correctly."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:174
+msgid "Fast retrieval"
+msgstr "快速检索"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:176
+msgid ""
+"Mercurial cleverly avoids a pitfall common to all earlier revision control "
+"systems: the problem of <emphasis>inefficient retrieval</emphasis>. Most "
+"revision control systems store the contents of a revision as an incremental "
+"series of modifications against a <quote>snapshot</quote>.  To reconstruct a "
+"specific revision, you must first read the snapshot, and then every one of "
+"the revisions between the snapshot and your target revision.  The more "
+"history that a file accumulates, the more revisions you must read, hence the "
+"longer it takes to reconstruct a particular revision."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:188
+msgid "Snapshot of a revlog, with incremental deltas"
+msgstr "版本日志的快照,以及增量差异"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:190
+msgid "<imageobject><imagedata fileref=\"figs/snapshot.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:195
+msgid ""
+"The innovation that Mercurial applies to this problem is simple but "
+"effective.  Once the cumulative amount of delta information stored since the "
+"last snapshot exceeds a fixed threshold, it stores a new snapshot "
+"(compressed, of course), instead of another delta.  This makes it possible to "
+"reconstruct <emphasis>any</emphasis> revision of a file quickly.  This "
+"approach works so well that it has since been copied by several other "
+"revision control systems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:204
+msgid ""
+"<xref linkend=\"fig:concepts:snapshot\"/> illustrates the idea.  In an entry "
+"in a revlog's index file, Mercurial stores the range of entries from the data "
+"file that it must read to reconstruct a particular revision."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch03-concepts.xml:210
+msgid "Aside: the influence of video compression"
+msgstr "旁白: 视频压缩的影响"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:212
+msgid ""
+"If you're familiar with video compression or have ever watched a TV feed "
+"through a digital cable or satellite service, you may know that most video "
+"compression schemes store each frame of video as a delta against its "
+"predecessor frame.  In addition, these schemes use <quote>lossy</quote> "
+"compression techniques to increase the compression ratio, so visual errors "
+"accumulate over the course of a number of inter-frame deltas."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:221
+msgid ""
+"Because it's possible for a video stream to <quote>drop out</quote> "
+"occasionally due to signal glitches, and to limit the accumulation of "
+"artefacts introduced by the lossy compression process, video encoders "
+"periodically insert a complete frame (called a <quote>key frame</quote>) into "
+"the video stream; the next delta is generated against that frame.  This means "
+"that if the video signal gets interrupted, it will resume once the next key "
+"frame is received.  Also, the accumulation of encoding errors restarts anew "
+"with each key frame."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:235
+msgid "Identification and strong integrity"
+msgstr "鉴别和强完整性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:237
+msgid ""
+"Along with delta or snapshot information, a revlog entry contains a "
+"cryptographic hash of the data that it represents.  This makes it difficult "
+"to forge the contents of a revision, and easy to detect accidental corruption."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:242
+msgid ""
+"Hashes provide more than a mere check against corruption; they are used as "
+"the identifiers for revisions.  The changeset identification hashes that you "
+"see as an end user are from revisions of the changelog.  Although filelogs "
+"and the manifest also use hashes, Mercurial only uses these behind the scenes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:249
+msgid ""
+"Mercurial verifies that hashes are correct when it retrieves file revisions "
+"and when it pulls changes from another repository.  If it encounters an "
+"integrity problem, it will complain and stop whatever it's doing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:254
+msgid ""
+"In addition to the effect it has on retrieval efficiency, Mercurial's use of "
+"periodic snapshots makes it more robust against partial data corruption.  If "
+"a revlog becomes partly corrupted due to a hardware error or system bug, it's "
+"often possible to reconstruct some or most revisions from the uncorrupted "
+"sections of the revlog, both before and after the corrupted section.  This "
+"would not be possible with a delta-only storage model."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:266
+msgid "Revision history, branching, and merging"
+msgstr "修订历史,分支与合并"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:268
+msgid ""
+"Every entry in a Mercurial revlog knows the identity of its immediate "
+"ancestor revision, usually referred to as its <emphasis>parent</emphasis>.  "
+"In fact, a revision contains room for not one parent, but two.  Mercurial "
+"uses a special hash, called the <quote>null ID</quote>, to represent the idea "
+"<quote>there is no parent here</quote>.  This hash is simply a string of "
+"zeroes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:276
+msgid ""
+"In <xref linkend=\"fig:concepts:revlog\"/>, you can see an example of the "
+"conceptual structure of a revlog.  Filelogs, manifests, and changelogs all "
+"have this same structure; they differ only in the kind of data stored in each "
+"delta or snapshot."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:282
+msgid ""
+"The first revision in a revlog (at the bottom of the image)  has the null ID "
+"in both of its parent slots.  For a <quote>normal</quote> revision, its first "
+"parent slot contains the ID of its parent revision, and its second contains "
+"the null ID, indicating that the revision has only one real parent.  Any two "
+"revisions that have the same parent ID are branches.  A revision that "
+"represents a merge between branches has two normal revision IDs in its parent "
+"slots."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><figure><title>
+#: ../en/ch03-concepts.xml:292
+msgid "The conceptual structure of a revlog"
+msgstr "版本日志的设计结构"
+
+#. type: Content of: <book><chapter><sect1><figure><mediaobject>
+#: ../en/ch03-concepts.xml:294
+msgid "<imageobject><imagedata fileref=\"figs/revlog.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:301
+msgid "The working directory"
+msgstr "工作目录"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:303
+msgid ""
+"In the working directory, Mercurial stores a snapshot of the files from the "
+"repository as of a particular changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:306
+msgid ""
+"The working directory <quote>knows</quote> which changeset it contains.  When "
+"you update the working directory to contain a particular changeset, Mercurial "
+"looks up the appropriate revision of the manifest to find out which files it "
+"was tracking at the time that changeset was committed, and which revision of "
+"each file was then current.  It then recreates a copy of each of those files, "
+"with the same contents it had when the changeset was committed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:315
+msgid ""
+"The <emphasis>dirstate</emphasis> contains Mercurial's knowledge of the "
+"working directory.  This details which changeset the working directory is "
+"updated to, and all of the files that Mercurial is tracking in the working "
+"directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:321
+msgid ""
+"Just as a revision of a revlog has room for two parents, so that it can "
+"represent either a normal revision (with one parent)  or a merge of two "
+"earlier revisions, the dirstate has slots for two parents.  When you use the "
+"<command role=\"hg-cmd\">hg update</command> command, the changeset that you "
+"update to is stored in the <quote>first parent</quote> slot, and the null ID "
+"in the second. When you <command role=\"hg-cmd\">hg merge</command> with "
+"another changeset, the first parent remains unchanged, and the second parent "
+"is filled in with the changeset you're merging with.  The <command role=\"hg-"
+"cmd\">hg parents</command> command tells you what the parents of the dirstate "
+"are."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:335
+msgid "What happens when you commit"
+msgstr "当你提交时发生的事情"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:337
+msgid ""
+"The dirstate stores parent information for more than just book-keeping "
+"purposes.  Mercurial uses the parents of the dirstate as <emphasis>the "
+"parents of a new changeset</emphasis> when you perform a commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:343
+msgid "The working directory can have two parents"
+msgstr "工作目录可以有两个父亲"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:345
+msgid "<imageobject><imagedata fileref=\"figs/wdir.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:350
+msgid ""
+"<xref linkend=\"fig:concepts:wdir\"/> shows the normal state of the working "
+"directory, where it has a single changeset as parent.  That changeset is the "
+"<emphasis>tip</emphasis>, the newest changeset in the repository that has no "
+"children."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:357
+msgid "The working directory gains new parents after a commit"
+msgstr "提交之后,工作目录的父亲就改变了"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:360
+msgid ""
+"<imageobject><imagedata fileref=\"figs/wdir-after-commit.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:365
+msgid ""
+"It's useful to think of the working directory as <quote>the changeset I'm "
+"about to commit</quote>.  Any files that you tell Mercurial that you've "
+"added, removed, renamed, or copied will be reflected in that changeset, as "
+"will modifications to any files that Mercurial is already tracking; the new "
+"changeset will have the parents of the working directory as its parents."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:373
+msgid ""
+"After a commit, Mercurial will update the parents of the working directory, "
+"so that the first parent is the ID of the new changeset, and the second is "
+"the null ID.  This is shown in <xref linkend=\"fig:concepts:wdir-after-commit"
+"\"/>. Mercurial doesn't touch any of the files in the working directory when "
+"you commit; it just modifies the dirstate to note its new parents."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:384
+msgid "Creating a new head"
+msgstr "创建新顶点"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:386
+msgid ""
+"It's perfectly normal to update the working directory to a changeset other "
+"than the current tip.  For example, you might want to know what your project "
+"looked like last Tuesday, or you could be looking through changesets to see "
+"which one introduced a bug.  In cases like this, the natural thing to do is "
+"update the working directory to the changeset you're interested in, and then "
+"examine the files in the working directory directly to see their contents as "
+"they were when you committed that changeset.  The effect of this is shown in "
+"<xref linkend=\"fig:concepts:wdir-pre-branch\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:398
+msgid "The working directory, updated to an older changeset"
+msgstr "同步到旧修改集的工作目录"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:401
+msgid ""
+"<imageobject><imagedata fileref=\"figs/wdir-pre-branch.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:406
+msgid ""
+"Having updated the working directory to an older changeset, what happens if "
+"you make some changes, and then commit? Mercurial behaves in the same way as "
+"I outlined above.  The parents of the working directory become the parents of "
+"the new changeset.  This new changeset has no children, so it becomes the new "
+"tip.  And the repository now contains two changesets that have no children; "
+"we call these <emphasis>heads</emphasis>.  You can see the structure that "
+"this creates in <xref linkend=\"fig:concepts:wdir-branch\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:418
+msgid "After a commit made while synced to an older changeset"
+msgstr "对同步到旧修改集的工作目录提交之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:421
+msgid "<imageobject><imagedata fileref=\"figs/wdir-branch.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch03-concepts.xml:427
+msgid ""
+"If you're new to Mercurial, you should keep in mind a common <quote>error</"
+"quote>, which is to use the <command role=\"hg-cmd\">hg pull</command> "
+"command without any options.  By default, the <command role=\"hg-cmd\">hg "
+"pull</command> command <emphasis>does not</emphasis> update the working "
+"directory, so you'll bring new changesets into your repository, but the "
+"working directory will stay synced at the same changeset as before the pull.  "
+"If you make some changes and commit afterwards, you'll thus create a new "
+"head, because your working directory isn't synced to whatever the current tip "
+"is."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch03-concepts.xml:439
+msgid ""
+"I put the word <quote>error</quote> in quotes because all that you need to do "
+"to rectify this situation is <command role=\"hg-cmd\">hg merge</command>, "
+"then <command role=\"hg-cmd\">hg commit</command>.  In other words, this "
+"almost never has negative consequences; it just surprises people.  I'll "
+"discuss other ways to avoid this behaviour, and why Mercurial behaves in this "
+"initially surprising way, later on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:451
+msgid "Merging heads"
+msgstr "合并顶点"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:453
+msgid ""
+"When you run the <command role=\"hg-cmd\">hg merge</command> command, "
+"Mercurial leaves the first parent of the working directory unchanged, and "
+"sets the second parent to the changeset you're merging with, as shown in "
+"<xref linkend=\"fig:concepts:wdir-merge\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch03-concepts.xml:460
+msgid "Merging two heads"
+msgstr "合并两个顶点"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch03-concepts.xml:462
+msgid ""
+"<imageobject> <imagedata fileref=\"figs/wdir-merge.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:469
+msgid ""
+"Mercurial also has to modify the working directory, to merge the files "
+"managed in the two changesets.  Simplified a little, the merging process goes "
+"like this, for every file in the manifests of both changesets."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:474
+msgid "If neither changeset has modified a file, do nothing with that file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:477
+msgid ""
+"If one changeset has modified a file, and the other hasn't, create the "
+"modified copy of the file in the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:481
+msgid ""
+"If one changeset has removed a file, and the other hasn't (or has also "
+"deleted it), delete the file from the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:485
+msgid ""
+"If one changeset has removed a file, but the other has modified the file, ask "
+"the user what to do: keep the modified file, or remove it?"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:489
+msgid ""
+"If both changesets have modified a file, invoke an external merge program to "
+"choose the new contents for the merged file.  This may require input from the "
+"user."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch03-concepts.xml:494
+msgid ""
+"If one changeset has modified a file, and the other has renamed or copied the "
+"file, make sure that the changes follow the new name of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:498
+msgid ""
+"There are more details&emdash;merging has plenty of corner cases&emdash;but "
+"these are the most common choices that are involved in a merge.  As you can "
+"see, most cases are completely automatic, and indeed most merges finish "
+"automatically, without requiring your input to resolve any conflicts."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:505
+msgid ""
+"When you're thinking about what happens when you commit after a merge, once "
+"again the working directory is <quote>the changeset I'm about to commit</"
+"quote>.  After the <command role=\"hg-cmd\">hg merge</command> command "
+"completes, the working directory has two parents; these will become the "
+"parents of the new changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:512
+msgid ""
+"Mercurial lets you perform multiple merges, but you must commit the results "
+"of each individual merge as you go.  This is necessary because Mercurial only "
+"tracks two parents for both revisions and the working directory.  While it "
+"would be technically possible to merge multiple changesets at once, the "
+"prospect of user confusion and making a terrible mess of a merge immediately "
+"becomes overwhelming."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:523
+msgid "Other interesting design features"
+msgstr "其它有趣的设计特性"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:525
+msgid ""
+"In the sections above, I've tried to highlight some of the most important "
+"aspects of Mercurial's design, to illustrate that it pays careful attention "
+"to reliability and performance.  However, the attention to detail doesn't "
+"stop there.  There are a number of other aspects of Mercurial's construction "
+"that I personally find interesting.  I'll detail a few of them here, separate "
+"from the <quote>big ticket</quote> items above, so that if you're interested, "
+"you can gain a better idea of the amount of thinking that goes into a well-"
+"designed system."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:536
+msgid "Clever compression"
+msgstr "智能压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:538
+msgid ""
+"When appropriate, Mercurial will store both snapshots and deltas in "
+"compressed form.  It does this by always <emphasis>trying to</emphasis> "
+"compress a snapshot or delta, but only storing the compressed version if it's "
+"smaller than the uncompressed version."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:544
+msgid ""
+"This means that Mercurial does <quote>the right thing</quote> when storing a "
+"file whose native form is compressed, such as a <literal>zip</literal> "
+"archive or a JPEG image.  When these types of files are compressed a second "
+"time, the resulting file is usually bigger than the once-compressed form, and "
+"so Mercurial will store the plain <literal>zip</literal> or JPEG."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:552
+msgid ""
+"Deltas between revisions of a compressed file are usually larger than "
+"snapshots of the file, and Mercurial again does <quote>the right thing</"
+"quote> in these cases.  It finds that such a delta exceeds the threshold at "
+"which it should store a complete snapshot of the file, so it stores the "
+"snapshot, again saving space compared to a naive delta-only approach."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch03-concepts.xml:561
+msgid "Network recompression"
+msgstr "网络重新压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:563
+msgid ""
+"When storing revisions on disk, Mercurial uses the <quote>deflate</quote> "
+"compression algorithm (the same one used by the popular <literal>zip</"
+"literal> archive format), which balances good speed with a respectable "
+"compression ratio.  However, when transmitting revision data over a network "
+"connection, Mercurial uncompresses the compressed revision data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:571
+msgid ""
+"If the connection is over HTTP, Mercurial recompresses the entire stream of "
+"data using a compression algorithm that gives a better compression ratio (the "
+"Burrows-Wheeler algorithm from the widely used <literal>bzip2</literal> "
+"compression package).  This combination of algorithm and compression of the "
+"entire stream (instead of a revision at a time) substantially reduces the "
+"number of bytes to be transferred, yielding better network performance over "
+"almost all kinds of network."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:581
+msgid ""
+"(If the connection is over <command>ssh</command>, Mercurial "
+"<emphasis>doesn't</emphasis> recompress the stream, because <command>ssh</"
+"command> can already do this itself.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:589
+msgid "Read/write ordering and atomicity"
+msgstr "读写顺序与原子性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:591
+msgid ""
+"Appending to files isn't the whole story when it comes to guaranteeing that a "
+"reader won't see a partial write.  If you recall <xref linkend=\"fig:concepts:"
+"metadata\"/>, revisions in the changelog point to revisions in the manifest, "
+"and revisions in the manifest point to revisions in filelogs.  This hierarchy "
+"is deliberate."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:599
+msgid ""
+"A writer starts a transaction by writing filelog and manifest data, and "
+"doesn't write any changelog data until those are finished.  A reader starts "
+"by reading changelog data, then manifest data, followed by filelog data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:604
+msgid ""
+"Since the writer has always finished writing filelog and manifest data before "
+"it writes to the changelog, a reader will never read a pointer to a partially "
+"written manifest revision from the changelog, and it will never read a "
+"pointer to a partially written filelog revision from the manifest."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:612
+msgid "Concurrent access"
+msgstr "并发访问"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:614
+msgid ""
+"The read/write ordering and atomicity guarantees mean that Mercurial never "
+"needs to <emphasis>lock</emphasis> a repository when it's reading data, even "
+"if the repository is being written to while the read is occurring. This has a "
+"big effect on scalability; you can have an arbitrary number of Mercurial "
+"processes safely reading data from a repository safely all at once, no matter "
+"whether it's being written to or not."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:623
+msgid ""
+"The lockless nature of reading means that if you're sharing a repository on a "
+"multi-user system, you don't need to grant other local users permission to "
+"<emphasis>write</emphasis> to your repository in order for them to be able to "
+"clone it or pull changes from it; they only need <emphasis>read</emphasis> "
+"permission.  (This is <emphasis>not</emphasis> a common feature among "
+"revision control systems, so don't take it for granted! Most require readers "
+"to be able to lock a repository to access it safely, and this requires write "
+"permission on at least one directory, which of course makes for all kinds of "
+"nasty and annoying security and administrative problems.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:636
+msgid ""
+"Mercurial uses locks to ensure that only one process can write to a "
+"repository at a time (the locking mechanism is safe even over filesystems "
+"that are notoriously hostile to locking, such as NFS).  If a repository is "
+"locked, a writer will wait for a while to retry if the repository becomes "
+"unlocked, but if the repository remains locked for too long, the process "
+"attempting to write will time out after a while. This means that your daily "
+"automated scripts won't get stuck forever and pile up if a system crashes "
+"unnoticed, for example.  (Yes, the timeout is configurable, from zero to "
+"infinity.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch03-concepts.xml:648
+msgid "Safe dirstate access"
+msgstr "安全的目录状态访问"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:650
+msgid ""
+"As with revision data, Mercurial doesn't take a lock to read the dirstate "
+"file; it does acquire a lock to write it.  To avoid the possibility of "
+"reading a partially written copy of the dirstate file, Mercurial writes to a "
+"file with a unique name in the same directory as the dirstate file, then "
+"renames the temporary file atomically to <filename>dirstate</filename>.  The "
+"file named <filename>dirstate</filename> is thus guaranteed to be complete, "
+"not partially written."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:663
+msgid "Avoiding seeks"
+msgstr "避免查找"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:665
+msgid ""
+"Critical to Mercurial's performance is the avoidance of seeks of the disk "
+"head, since any seek is far more expensive than even a comparatively large "
+"read operation."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:669
+msgid ""
+"This is why, for example, the dirstate is stored in a single file.  If there "
+"were a dirstate file per directory that Mercurial tracked, the disk would "
+"seek once per directory.  Instead, Mercurial reads the entire single dirstate "
+"file in one step."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:675
+msgid ""
+"Mercurial also uses a <quote>copy on write</quote> scheme when cloning a "
+"repository on local storage.  Instead of copying every revlog file from the "
+"old repository into the new repository, it makes a <quote>hard link</quote>, "
+"which is a shorthand way to say <quote>these two names point to the same "
+"file</quote>.  When Mercurial is about to write to one of a revlog's files, "
+"it checks to see if the number of names pointing at the file is greater than "
+"one.  If it is, more than one repository is using the file, so Mercurial "
+"makes a new copy of the file that is private to this repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:686
+msgid ""
+"A few revision control developers have pointed out that this idea of making a "
+"complete private copy of a file is not very efficient in its use of storage.  "
+"While this is true, storage is cheap, and this method gives the highest "
+"performance while deferring most book-keeping to the operating system.  An "
+"alternative scheme would most likely reduce performance and increase the "
+"complexity of the software, each of which is much more important to the "
+"<quote>feel</quote> of day-to-day use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:698
+msgid "Other contents of the dirstate"
+msgstr "目录状态的其它内容"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:700
+msgid ""
+"Because Mercurial doesn't force you to tell it when you're modifying a file, "
+"it uses the dirstate to store some extra information so it can determine "
+"efficiently whether you have modified a file.  For each file in the working "
+"directory, it stores the time that it last modified the file itself, and the "
+"size of the file at that time."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:707
+msgid ""
+"When you explicitly <command role=\"hg-cmd\">hg add</command>, <command role="
+"\"hg-cmd\">hg remove</command>, <command role=\"hg-cmd\">hg rename</command> "
+"or <command role=\"hg-cmd\">hg copy</command> files, Mercurial updates the "
+"dirstate so that it knows what to do with those files when you commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:714
+msgid ""
+"When Mercurial is checking the states of files in the working directory, it "
+"first checks a file's modification time.  If that has not changed, the file "
+"must not have been modified.  If the file's size has changed, the file must "
+"have been modified.  If the modification time has changed, but the size has "
+"not, only then does Mercurial need to read the actual contents of the file to "
+"see if they've changed. Storing these few extra pieces of information "
+"dramatically reduces the amount of data that Mercurial needs to read, which "
+"yields large performance improvements compared to other revision control "
+"systems."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch04-daily.xml:5
+msgid "Mercurial in daily use"
+msgstr "Mercurial 的日常使用"
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch04-daily.xml:8
+msgid "Telling Mercurial which files to track"
+msgstr "告诉 Mercurial 要跟踪哪些文件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:10
+msgid ""
+"Mercurial does not work with files in your repository unless you tell it to "
+"manage them.  The <command role=\"hg-cmd\">hg status</command> command will "
+"tell you which files Mercurial doesn't know about; it uses a <quote><literal>?"
+"</literal></quote> to display such files."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:17
+msgid ""
+"To tell Mercurial to track a file, use the <command role=\"hg-cmd\">hg add</"
+"command> command.  Once you have added a file, the entry in the output of "
+"<command role=\"hg-cmd\">hg status</command> for that file changes from "
+"<quote><literal>?</literal></quote> to <quote><literal>A</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:26
+msgid ""
+"After you run a <command role=\"hg-cmd\">hg commit</command>, the files that "
+"you added before the commit will no longer be listed in the output of "
+"<command role=\"hg-cmd\">hg status</command>.  The reason for this is that "
+"<command role=\"hg-cmd\">hg status</command> only tells you about "
+"<quote>interesting</quote> files&emdash;those that you have modified or told "
+"Mercurial to do something with&emdash;by default.  If you have a repository "
+"that contains thousands of files, you will rarely want to know about files "
+"that Mercurial is tracking, but that have not changed.  (You can still get "
+"this information; we'll return to this later.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:38
+msgid ""
+"Once you add a file, Mercurial doesn't do anything with it immediately.  "
+"Instead, it will take a snapshot of the file's state the next time you "
+"perform a commit.  It will then continue to track the changes you make to the "
+"file every time you commit, until you remove the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:45
+msgid "Explicit versus implicit file naming"
+msgstr "明确与隐含文件命名"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:47
+msgid ""
+"A useful behaviour that Mercurial has is that if you pass the name of a "
+"directory to a command, every Mercurial command will treat this as <quote>I "
+"want to operate on every file in this directory and its subdirectories</"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:54
+msgid ""
+"Notice in this example that Mercurial printed the names of the files it "
+"added, whereas it didn't do so when we added the file named <filename>a</"
+"filename> in the earlier example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:59
+msgid ""
+"What's going on is that in the former case, we explicitly named the file to "
+"add on the command line, so the assumption that Mercurial makes in such cases "
+"is that you know what you were doing, and it doesn't print any output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:64
+msgid ""
+"However, when we <emphasis>imply</emphasis> the names of files by giving the "
+"name of a directory, Mercurial takes the extra step of printing the name of "
+"each file that it does something with.  This makes it more clear what is "
+"happening, and reduces the likelihood of a silent and nasty surprise.  This "
+"behaviour is common to most Mercurial commands."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:73
+msgid "Aside: Mercurial tracks files, not directories"
+msgstr "旁白: Mercurial 只跟踪文件,不跟踪目录"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:75
+msgid ""
+"Mercurial does not track directory information.  Instead, it tracks the path "
+"to a file.  Before creating a file, it first creates any missing directory "
+"components of the path.  After it deletes a file, it then deletes any empty "
+"directories that were in the deleted file's path.  This sounds like a trivial "
+"distinction, but it has one minor practical consequence: it is not possible "
+"to represent a completely empty directory in Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:84
+msgid ""
+"Empty directories are rarely useful, and there are unintrusive workarounds "
+"that you can use to achieve an appropriate effect.  The developers of "
+"Mercurial thus felt that the complexity that would be required to manage "
+"empty directories was not worth the limited benefit this feature would bring."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:91
+msgid ""
+"If you need an empty directory in your repository, there are a few ways to "
+"achieve this. One is to create a directory, then <command role=\"hg-cmd\">hg "
+"add</command> a <quote>hidden</quote> file to that directory.  On Unix-like "
+"systems, any file name that begins with a period (<quote><literal>.</"
+"literal></quote>) is treated as hidden by most commands and GUI tools.  This "
+"approach is illustrated below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:102
+msgid ""
+"Another way to tackle a need for an empty directory is to simply create one "
+"in your automated build scripts before they will need it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch04-daily.xml:109
+msgid "How to stop tracking a file"
+msgstr "如何停止跟踪文件"
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:111
+msgid ""
+"Once you decide that a file no longer belongs in your repository, use the "
+"<command role=\"hg-cmd\">hg remove</command> command; this deletes the file, "
+"and tells Mercurial to stop tracking it.  A removed file is represented in "
+"the output of <command role=\"hg-cmd\">hg status</command> with a "
+"<quote><literal>R</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:120
+msgid ""
+"After you <command role=\"hg-cmd\">hg remove</command> a file, Mercurial will "
+"no longer track changes to that file, even if you recreate a file with the "
+"same name in your working directory.  If you do recreate a file with the same "
+"name and want Mercurial to track the new file, simply <command role=\"hg-cmd"
+"\">hg add</command> it. Mercurial will know that the newly added file is not "
+"related to the old file of the same name."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:129
+msgid "Removing a file does not affect its history"
+msgstr "删除文件不影响历史"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:131
+msgid "It is important to understand that removing a file has only two effects."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch04-daily.xml:134
+msgid "It removes the current version of the file from the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch04-daily.xml:137
+msgid ""
+"It stops Mercurial from tracking changes to the file, from the time of the "
+"next commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:140
+msgid ""
+"Removing a file <emphasis>does not</emphasis> in any way alter the "
+"<emphasis>history</emphasis> of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:143
+msgid ""
+"If you update the working directory to a changeset in which a file that you "
+"have removed was still tracked, it will reappear in the working directory, "
+"with the contents it had when you committed that changeset.  If you then "
+"update the working directory to a later changeset, in which the file had been "
+"removed, Mercurial will once again remove the file from the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:153
+msgid "Missing files"
+msgstr "丢失的文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:155
+msgid ""
+"Mercurial considers a file that you have deleted, but not used <command role="
+"\"hg-cmd\">hg remove</command> to delete, to be <emphasis>missing</"
+"emphasis>.  A missing file is represented with <quote><literal>!</literal></"
+"quote> in the output of <command role=\"hg-cmd\">hg status</command>.  "
+"Mercurial commands will not generally do anything with missing files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:165
+msgid ""
+"If your repository contains a file that <command role=\"hg-cmd\">hg status</"
+"command> reports as missing, and you want the file to stay gone, you can run "
+"<command role=\"hg-cmd\">hg remove <option role=\"hg-opt-remove\">--after</"
+"option></command> at any time later on, to tell Mercurial that you really did "
+"mean to remove the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:175
+msgid ""
+"On the other hand, if you deleted the missing file by accident, give <command "
+"role=\"hg-cmd\">hg revert</command> the name of the file to recover.  It will "
+"reappear, in unmodified form."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:184
+msgid "Aside: why tell Mercurial explicitly to remove a file?"
+msgstr "旁白: 为什么要明确告诉 Mercurial 删除文件?"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:187
+msgid ""
+"You might wonder why Mercurial requires you to explicitly tell it that you "
+"are deleting a file.  Early during the development of Mercurial, it let you "
+"delete a file however you pleased; Mercurial would notice the absence of the "
+"file automatically when you next ran a <command role=\"hg-cmd\">hg commit</"
+"command>, and stop tracking the file.  In practice, this made it too easy to "
+"accidentally remove a file without noticing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:198
+msgid "Useful shorthand&emdash;adding and removing files in one step"
+msgstr "有用的速记—一个步骤添加和删除文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:201
+msgid ""
+"Mercurial offers a combination command, <command role=\"hg-cmd\">hg "
+"addremove</command>, that adds untracked files and marks missing files as "
+"removed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:207
+msgid ""
+"The <command role=\"hg-cmd\">hg commit</command> command also provides a "
+"<option role=\"hg-opt-commit\">-A</option> option that performs this same add-"
+"and-remove, immediately followed by a commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch04-daily.xml:217
+msgid "Copying files"
+msgstr "复制文件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:219
+msgid ""
+"Mercurial provides a <command role=\"hg-cmd\">hg copy</command> command that "
+"lets you make a new copy of a file.  When you copy a file using this command, "
+"Mercurial makes a record of the fact that the new file is a copy of the "
+"original file.  It treats these copied files specially when you merge your "
+"work with someone else's."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:227
+msgid "The results of copying during a merge"
+msgstr "合并期间的复制结果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:229
+msgid ""
+"What happens during a merge is that changes <quote>follow</quote> a copy.  To "
+"best illustrate what this means, let's create an example.  We'll start with "
+"the usual tiny repository that contains a single file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:236
+msgid ""
+"We need to do some work in parallel, so that we'll have something to merge.  "
+"So let's clone our repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:242
+msgid ""
+"Back in our initial repository, let's use the <command role=\"hg-cmd\">hg "
+"copy</command> command to make a copy of the first file we created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:248
+msgid ""
+"If we look at the output of the <command role=\"hg-cmd\">hg status</command> "
+"command afterwards, the copied file looks just like a normal added file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:254
+msgid ""
+"But if we pass the <option role=\"hg-opt-status\">-C</option> option to "
+"<command role=\"hg-cmd\">hg status</command>, it prints another line of "
+"output: this is the file that our newly-added file was copied <emphasis>from</"
+"emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:262
+msgid ""
+"Now, back in the repository we cloned, let's make a change in parallel.  "
+"We'll add a line of content to the original file that we created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:268
+msgid ""
+"Now we have a modified <filename>file</filename> in this repository.  When we "
+"pull the changes from the first repository, and merge the two heads, "
+"Mercurial will propagate the changes that we made locally to <filename>file</"
+"filename> into its copy, <filename>new-file</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:278
+msgid "Why should changes follow copies?"
+msgstr "为什么复制后需要后续修改?"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:280
+msgid ""
+"This behaviour, of changes to a file propagating out to copies of the file, "
+"might seem esoteric, but in most cases it's highly desirable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:284
+msgid ""
+"First of all, remember that this propagation <emphasis>only</emphasis> "
+"happens when you merge.  So if you <command role=\"hg-cmd\">hg copy</command> "
+"a file, and subsequently modify the original file during the normal course of "
+"your work, nothing will happen."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:290
+msgid ""
+"The second thing to know is that modifications will only propagate across a "
+"copy as long as the repository that you're pulling changes from "
+"<emphasis>doesn't know</emphasis> about the copy."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:295
+msgid ""
+"The reason that Mercurial does this is as follows.  Let's say I make an "
+"important bug fix in a source file, and commit my changes. Meanwhile, you've "
+"decided to <command role=\"hg-cmd\">hg copy</command> the file in your "
+"repository, without knowing about the bug or having seen the fix, and you "
+"have started hacking on your copy of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:302
+msgid ""
+"If you pulled and merged my changes, and Mercurial <emphasis>didn't</"
+"emphasis> propagate changes across copies, your source file would now contain "
+"the bug, and unless you remembered to propagate the bug fix by hand, the bug "
+"would <emphasis>remain</emphasis> in your copy of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:308
+msgid ""
+"By automatically propagating the change that fixed the bug from the original "
+"file to the copy, Mercurial prevents this class of problem. To my knowledge, "
+"Mercurial is the <emphasis>only</emphasis> revision control system that "
+"propagates changes across copies like this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:314
+msgid ""
+"Once your change history has a record that the copy and subsequent merge "
+"occurred, there's usually no further need to propagate changes from the "
+"original file to the copied file, and that's why Mercurial only propagates "
+"changes across copies until this point, and no further."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:322
+msgid "How to make changes <emphasis>not</emphasis> follow a copy"
+msgstr "如何让复制后<emphasis>不</emphasis>修改?"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:325
+msgid ""
+"If, for some reason, you decide that this business of automatically "
+"propagating changes across copies is not for you, simply use your system's "
+"normal file copy command (on Unix-like systems, that's <command>cp</command>) "
+"to make a copy of a file, then <command role=\"hg-cmd\">hg add</command> the "
+"new copy by hand.  Before you do so, though, please do reread <xref linkend="
+"\"sec:daily:why-copy\"/>, and make an informed decision that this behaviour "
+"is not appropriate to your specific case."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:338
+msgid "Behaviour of the <command role=\"hg-cmd\">hg copy</command> command"
+msgstr "命令 <command role=\"hg-cmd\">hg copy</command> 的特性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:341
+msgid ""
+"When you use the <command role=\"hg-cmd\">hg copy</command> command, "
+"Mercurial makes a copy of each source file as it currently stands in the "
+"working directory.  This means that if you make some modifications to a file, "
+"then <command role=\"hg-cmd\">hg copy</command> it without first having "
+"committed those changes, the new copy will also contain the modifications you "
+"have made up until that point.  (I find this behaviour a little "
+"counterintuitive, which is why I mention it here.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:351
+msgid ""
+"The <command role=\"hg-cmd\">hg copy</command> command acts similarly to the "
+"Unix <command>cp</command> command (you can use the <command role=\"hg-cmd"
+"\">hg cp</command> alias if you prefer).  The last argument is the "
+"<emphasis>destination</emphasis>, and all prior arguments are "
+"<emphasis>sources</emphasis>.  If you pass it a single file as the source, "
+"and the destination does not exist, it creates a new file with that name."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:362
+msgid ""
+"If the destination is a directory, Mercurial copies its sources into that "
+"directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:367
+msgid ""
+"Copying a directory is recursive, and preserves the directory structure of "
+"the source."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:373
+msgid ""
+"If the source and destination are both directories, the source tree is "
+"recreated in the destination directory."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:378
+msgid ""
+"As with the <command role=\"hg-cmd\">hg rename</command> command, if you copy "
+"a file manually and then want Mercurial to know that you've copied the file, "
+"simply use the <option role=\"hg-opt-copy\">--after</option> option to "
+"<command role=\"hg-cmd\">hg copy</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch04-daily.xml:389
+msgid "Renaming files"
+msgstr "改名文件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:391
+msgid ""
+"It's rather more common to need to rename a file than to make a copy of it.  "
+"The reason I discussed the <command role=\"hg-cmd\">hg copy</command> command "
+"before talking about renaming files is that Mercurial treats a rename in "
+"essentially the same way as a copy.  Therefore, knowing what Mercurial does "
+"when you copy a file tells you what to expect when you rename a file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:399
+msgid ""
+"When you use the <command role=\"hg-cmd\">hg rename</command> command, "
+"Mercurial makes a copy of each source file, then deletes it and marks the "
+"file as removed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:405
+msgid ""
+"The <command role=\"hg-cmd\">hg status</command> command shows the newly "
+"copied file as added, and the copied-from file as removed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:411
+msgid ""
+"As with the results of a <command role=\"hg-cmd\">hg copy</command>, we must "
+"use the <option role=\"hg-opt-status\">-C</option> option to <command role="
+"\"hg-cmd\">hg status</command> to see that the added file is really being "
+"tracked by Mercurial as a copy of the original, now removed, file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:420
+msgid ""
+"As with <command role=\"hg-cmd\">hg remove</command> and <command role=\"hg-"
+"cmd\">hg copy</command>, you can tell Mercurial about a rename after the fact "
+"using the <option role=\"hg-opt-rename\">--after</option> option.  In most "
+"other respects, the behaviour of the <command role=\"hg-cmd\">hg rename</"
+"command> command, and the options it accepts, are similar to the <command "
+"role=\"hg-cmd\">hg copy</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:430
+msgid "Renaming files and merging changes"
+msgstr "改名文件与合并修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:432
+msgid ""
+"Since Mercurial's rename is implemented as copy-and-remove, the same "
+"propagation of changes happens when you merge after a rename as after a copy."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:436
+msgid ""
+"If I modify a file, and you rename it to a new name, and then we merge our "
+"respective changes, my modifications to the file under its original name will "
+"be propagated into the file under its new name. (This is something you might "
+"expect to <quote>simply work,</quote> but not all revision control systems "
+"actually do this.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:443
+msgid ""
+"Whereas having changes follow a copy is a feature where you can perhaps nod "
+"and say <quote>yes, that might be useful,</quote> it should be clear that "
+"having them follow a rename is definitely important.  Without this facility, "
+"it would simply be too easy for changes to become orphaned when files are "
+"renamed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:452
+msgid "Divergent renames and merging"
+msgstr "改名与合并的分歧"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:454
+msgid ""
+"The case of diverging names occurs when two developers start with a "
+"file&emdash;let's call it <filename>foo</filename>&emdash;in their respective "
+"repositories."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:461
+msgid "Anne renames the file to <filename>bar</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:465
+msgid "Meanwhile, Bob renames it to <filename>quux</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:470
+msgid ""
+"I like to think of this as a conflict because each developer has expressed "
+"different intentions about what the file ought to be named."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:474
+msgid ""
+"What do you think should happen when they merge their work? Mercurial's "
+"actual behaviour is that it always preserves <emphasis>both</emphasis> names "
+"when it merges changesets that contain divergent renames."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:481
+msgid ""
+"Notice that Mercurial does warn about the divergent renames, but it leaves it "
+"up to you to do something about the divergence after the merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:487
+msgid "Convergent renames and merging"
+msgstr "收敛改名与合并"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:489
+msgid ""
+"Another kind of rename conflict occurs when two people choose to rename "
+"different <emphasis>source</emphasis> files to the same "
+"<emphasis>destination</emphasis>. In this case, Mercurial runs its normal "
+"merge machinery, and lets you guide it to a suitable resolution."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch04-daily.xml:497
+msgid "Other name-related corner cases"
+msgstr "其它名称相关的角落"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch04-daily.xml:499
+msgid ""
+"Mercurial has a longstanding bug in which it fails to handle a merge where "
+"one side has a file with a given name, while another has a directory with the "
+"same name.  This is documented as <ulink role=\"hg-bug\" url=\"http://www."
+"selenic.com/mercurial/bts/issue29\">issue 29</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch04-daily.xml:511
+msgid "Recovering from mistakes"
+msgstr "从错误恢复"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:513
+msgid ""
+"Mercurial has some useful commands that will help you to recover from some "
+"common mistakes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:516
+msgid ""
+"The <command role=\"hg-cmd\">hg revert</command> command lets you undo "
+"changes that you have made to your working directory.  For example, if you "
+"<command role=\"hg-cmd\">hg add</command> a file by accident, just run "
+"<command role=\"hg-cmd\">hg revert</command> with the name of the file you "
+"added, and while the file won't be touched in any way, it won't be tracked "
+"for adding by Mercurial any longer, either.  You can also use <command role="
+"\"hg-cmd\">hg revert</command> to get rid of erroneous changes to a file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:526
+msgid ""
+"It's useful to remember that the <command role=\"hg-cmd\">hg revert</command> "
+"command is useful for changes that you have not yet committed.  Once you've "
+"committed a change, if you decide it was a mistake, you can still do "
+"something about it, though your options may be more limited."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch04-daily.xml:532
+msgid ""
+"For more information about the <command role=\"hg-cmd\">hg revert</command> "
+"command, and details about how to deal with changes you have already "
+"committed, see <xref linkend=\"chap:undo\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch05-collab.xml:5
+msgid "Collaborating with other people"
+msgstr "团体协作"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch05-collab.xml:7
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:14
+msgid "Mercurial's web interface"
+msgstr "Mercurial 的 web 接口"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:16
+msgid ""
+"Mercurial has a powerful web interface that provides several useful "
+"capabilities."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:19
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:24
+msgid ""
+"Also for human consumption, the web interface provides an RSS feed of the "
+"changes in a repository.  This lets you <quote>subscribe</quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:34
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:40
+msgid ""
+"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 <ulink url=\"http://www.selenic.com/repo/hg?style=gitweb"
+"\">http://www.selenic.com/repo/hg?style=gitweb</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:45
+msgid ""
+"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 <command role="
+"\"hg-cmd\">hg serve</command> command, which is best suited to short-term "
+"<quote>lightweight</quote> serving.  See <xref linkend=\"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 <xref linkend=\"sec:collab:cgi\"/> for details of "
+"CGI configuration."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:60
+msgid "Collaboration models"
+msgstr "协作模型"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:62
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:70
+msgid "Factors to keep in mind"
+msgstr "要牢记的因素"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:72
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:78
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:88
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:102
+msgid "Informal anarchy"
+msgstr "无政府状态"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:104
+msgid ""
+"I wouldn't suggest an <quote>anything goes</quote> approach as something "
+"sustainable, but it's a model that's easy to grasp, and it works perfectly "
+"well in a few unusual situations."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:109
+msgid ""
+"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 <quote>sprints</"
+"quote>.  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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:118
+msgid ""
+"A sprint is the perfect place to use the <command role=\"hg-cmd\">hg serve</"
+"command> command, since <command role=\"hg-cmd\">hg serve</command> does not "
+"require any fancy server infrastructure.  You can get started with <command "
+"role=\"hg-cmd\">hg serve</command> in moments, by reading <xref linkend=\"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:132
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:141
+msgid "A single central repository"
+msgstr "单一中央版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:143
+msgid ""
+"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 "
+"<quote>building block</quote> for more ambitious workflow schemes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:149
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:154
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:165
+msgid ""
+"In this kind of scenario, people usually use the <command>ssh</command> "
+"protocol to securely push changes to the central repository, as documented in "
+"<xref linkend=\"sec:collab:ssh\"/>.  It's also usual to publish a read-only "
+"copy of the repository over HTTP using CGI, as in <xref linkend=\"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:177
+msgid "Working with multiple branches"
+msgstr "使用多个分支工作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:179
+msgid ""
+"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 "
+"<quote>maintenance mode</quote> 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 <quote>branch</quote> to "
+"refer to one of these many slightly different directions in which development "
+"is proceeding."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:192
+msgid ""
+"Mercurial is particularly well suited to managing a number of simultaneous, "
+"but not identical, branches.  Each <quote>development direction</quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:201
+msgid ""
+"Here's an example of how this can work in practice.  Let's say you have one "
+"<quote>main branch</quote> on a central server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:207
+msgid "People clone it, make changes locally, test them, and push them back."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:210
+msgid ""
+"Once the main branch reaches a release milestone, you can use the <command "
+"role=\"hg-cmd\">hg tag</command> command to give a permanent name to the "
+"milestone revision."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:216
+msgid "Let's say some ongoing development occurs on the main branch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:221
+msgid ""
+"Using the tag that was recorded at the milestone, people who clone that "
+"repository at any time in the future can use <command role=\"hg-cmd\">hg "
+"update</command> to get a copy of the working directory exactly as it was "
+"when that tagged revision was committed."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:229
+msgid ""
+"In addition, immediately after the main branch is tagged, someone can then "
+"clone the main branch on the server to a new <quote>stable</quote> branch, "
+"also on the server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:235
+msgid ""
+"Someone who needs to make a change to the stable branch can then clone "
+"<emphasis>that</emphasis> repository, make their changes, commit, and push "
+"their changes back there."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:241
+msgid ""
+"Because Mercurial repositories are independent, and Mercurial doesn't move "
+"changes around automatically, the stable and main branches are "
+"<emphasis>isolated</emphasis> from each other.  The changes that you made on "
+"the main branch don't <quote>leak</quote> to the stable branch, and vice "
+"versa."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:248
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:256
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch05-collab.xml:263 ../en/ch05-collab.xml:273
+msgid "Feature branches"
+msgstr "特性分支"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:265
+msgid ""
+"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 <quote>master</quote> branch used by the entire project.  People "
+"working on an individual branch are typically quite isolated from "
+"developments on other branches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch05-collab.xml:275
+msgid ""
+"<imageobject><imagedata width=\"100%\" fileref=\"figs/feature-branches.png\"/"
+"></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:280
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:287
+msgid "The release train"
+msgstr "发布列车"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:289
+msgid ""
+"Some projects are organised on a <quote>train</quote> basis: a release is "
+"scheduled to happen every few months, and whatever features are ready when "
+"the <quote>train</quote> is ready to leave are allowed in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:294
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:303
+msgid "The Linux kernel model"
+msgstr "Linux 内核模型"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:305
+msgid ""
+"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</command>, 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:313
+msgid ""
+"At the center of the community sits Linus Torvalds, the creator of Linux.  He "
+"publishes a single source repository that is considered the "
+"<quote>authoritative</quote> current tree by the entire developer community. "
+"Anyone can clone Linus's tree, but he is very choosy about whose trees he "
+"pulls from."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:320
+msgid ""
+"Linus has a number of <quote>trusted lieutenants</quote>.  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 "
+"<quote>maintainers</quote>, 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:332
+msgid ""
+"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 <quote>stable</quote> "
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:343
+msgid ""
+"This model has two notable features.  The first is that it's <quote>pull "
+"only</quote>.  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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:350
+msgid ""
+"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 "
+"<quote>good</quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:361
+msgid ""
+"Reputation and acclaim don't necessarily cross subsystem or <quote>people</"
+"quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:368
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:378
+msgid "Pull-only versus shared-push collaboration"
+msgstr "只读与共享写协作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:380
+msgid ""
+"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 "
+"<quote>better than</quote> one in which multiple people can push changes to a "
+"shared repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:386
+msgid ""
+"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)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:394
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:402
+msgid "Where collaboration meets branch management"
+msgstr "协作与分支管理"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:404
+msgid ""
+"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 <xref linkend=\"chap:branch\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:416
+msgid "The technical side of sharing"
+msgstr "共享的技术因素"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:418
+msgid ""
+"The remainder of this chapter is devoted to the question of serving data to "
+"your collaborators."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:423
+msgid "Informal sharing with <command role=\"hg-cmd\">hg serve</command>"
+msgstr "使用 <command role=\"hg-cmd\">hg serve</command> 进行非正式共享"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:426
+msgid ""
+"Mercurial's <command role=\"hg-cmd\">hg serve</command> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:431
+msgid ""
+"Run <command role=\"hg-cmd\">hg serve</command> 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 <command role=\"hg-"
+"cmd\">hg serve</command> instance running on a laptop is likely to look "
+"something like <literal>http://my-laptop.local:8000/</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:442
+msgid ""
+"The <command role=\"hg-cmd\">hg serve</command> command is <emphasis>not</"
+"emphasis> a general-purpose web server. It can do only two things:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:446
+msgid ""
+"Allow people to browse the history of the repository it's serving, from their "
+"normal web browsers."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:450
+msgid ""
+"Speak Mercurial's wire protocol, so that people can <command role=\"hg-cmd"
+"\">hg clone</command> or <command role=\"hg-cmd\">hg pull</command> changes "
+"from that repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:455
+msgid ""
+"In particular, <command role=\"hg-cmd\">hg serve</command> won't allow remote "
+"users to <emphasis>modify</emphasis> your repository.  It's intended for read-"
+"only use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:459
+msgid ""
+"If you're getting started with Mercurial, there's nothing to prevent you from "
+"using <command role=\"hg-cmd\">hg serve</command> to serve up a repository on "
+"your own computer, then use commands like <command role=\"hg-cmd\">hg clone</"
+"command>, <command role=\"hg-cmd\">hg incoming</command>, 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:469
+msgid "A few things to keep in mind"
+msgstr "要牢记的几件事"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:471
+msgid ""
+"Because it provides unauthenticated read access to all clients, you should "
+"only use <command role=\"hg-cmd\">hg serve</command> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:477
+msgid ""
+"The <command role=\"hg-cmd\">hg serve</command> 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 <command role=\"hg-cmd\">hg serve</command> instance, "
+"the second thing you should do (<emphasis>after</emphasis> you make sure that "
+"they're using the correct URL) is check your firewall configuration."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:486
+msgid ""
+"By default, <command role=\"hg-cmd\">hg serve</command> 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 "
+"<option role=\"hg-opt-serve\">-p</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:492
+msgid ""
+"Normally, when <command role=\"hg-cmd\">hg serve</command> 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 <option role=\"hg-opt-global\">-v</option> "
+"option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:502
+msgid "Using the Secure Shell (ssh) protocol"
+msgstr "使用 ssh 协议"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:504
+msgid ""
+"You can pull and push changes securely over a network connection using the "
+"Secure Shell (<literal>ssh</literal>)  protocol.  To use this successfully, "
+"you may have to do a little bit of configuration on the client or server "
+"sides."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:509
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:515
+msgid ""
+"(If you <emphasis>are</emphasis> familiar with ssh, you'll probably find some "
+"of the material that follows to be elementary in nature.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:520
+msgid "How to read and write ssh URLs"
+msgstr "如何读写 ssh 路径"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:522
+msgid "An ssh URL tends to look like this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:525
+msgid ""
+"The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the "
+"ssh protocol."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:528
+msgid ""
+"The <quote><literal>bos@</literal></quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:533
+msgid ""
+"The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of "
+"the server to log into."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:537
+msgid ""
+"The <quote>:22</quote> identifies the port number to connect to the server "
+"on.  The default port is 22, so you only need to specify a colon and port "
+"number if you're <emphasis>not</emphasis> using port 22."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:542
+msgid ""
+"The remainder of the URL is the local path to the repository on the server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:546
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:553
+msgid ""
+"Mercurial treats the path to a repository on the server as relative to the "
+"remote user's home directory.  For example, if user <literal>foo</literal> on "
+"the server has a home directory of <filename class=\"directory\">/home/foo</"
+"filename>, then an ssh URL that contains a path component of <filename class="
+"\"directory\">bar</filename> <emphasis>really</emphasis> refers to the "
+"directory <filename class=\"directory\">/home/foo/bar</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:562
+msgid ""
+"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 <literal>otheruser</literal>), like this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:568
+msgid ""
+"And if you really want to specify an <emphasis>absolute</emphasis> path on "
+"the server, begin the path component with two slashes, as in this example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:575
+msgid "Finding an ssh client for your system"
+msgstr "为你的系统寻找 ssh 客户端"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:577
+msgid ""
+"Almost every Unix-like system comes with OpenSSH preinstalled.  If you're "
+"using such a system, run <literal>which ssh</literal> to find out if the "
+"<command>ssh</command> command is installed (it's usually in <filename class="
+"\"directory\">/usr/bin</filename>).  In the unlikely event that it isn't "
+"present, take a look at your system documentation to figure out how to "
+"install it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:585
+msgid ""
+"On Windows, you'll first need to download a suitable ssh client.  There are "
+"two alternatives."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:588
+msgid ""
+"Simon Tatham's excellent PuTTY package <citation>web:putty</citation> "
+"provides a complete suite of ssh client commands."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:592
+msgid ""
+"If you have a high tolerance for pain, you can use the Cygwin port of OpenSSH."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:595
+msgid ""
+"In either case, you'll need to edit your <filename role=\"special\">hg.ini</"
+"filename> 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> command as a command-line ssh client."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch05-collab.xml:605
+msgid ""
+"The path to <command>plink</command> shouldn't contain any whitespace "
+"characters, or Mercurial may not be able to run it correctly (so putting it "
+"in <filename class=\"directory\">C:\\Program Files</filename> is probably not "
+"a good idea)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:614
+msgid "Generating a key pair"
+msgstr "产生密钥对"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:616
+msgid ""
+"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> command will do the trick. On Windows, if "
+"you're using PuTTY, the <command>puttygen</command> command is what you'll "
+"need."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:624
+msgid ""
+"When you generate a key pair, it's usually <emphasis>highly</emphasis> "
+"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.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:630
+msgid ""
+"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 <filename role=\"special"
+"\">authorized_keys</filename> in their <filename role=\"special\" class="
+"\"directory\">.ssh</filename> directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:639
+msgid ""
+"On a Unix-like system, your public key will have a <filename>.pub</filename> "
+"extension.  If you're using <command>puttygen</command> 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 <filename role=\"special"
+"\">authorized_keys</filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:648
+msgid "Using an authentication agent"
+msgstr "使用认证代理"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:650
+msgid ""
+"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)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:659
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:666
+msgid ""
+"On Unix-like systems, the agent is called <command>ssh-agent</command>, and "
+"it's often run automatically for you when you log in.  You'll need to use the "
+"<command>ssh-add</command> command to add passphrases to the agent's store.  "
+"On Windows, if you're using PuTTY, the <command>pageant</command> command "
+"acts as the agent.  It adds an icon to your system tray that will let you "
+"manage stored passphrases."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:677
+msgid "Configuring the server side properly"
+msgstr "正确配置服务器端"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:679
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:687
+msgid ""
+"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</command> or <command>putty</"
+"command> 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, <emphasis>before</emphasis> you worry about whether "
+"there's a problem with Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:698
+msgid ""
+"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</command> or "
+"<command>putty</command> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:705
+msgid ""
+"If you get a <quote>connection refused</quote> error, either there isn't an "
+"SSH daemon running on the server at all, or it's inaccessible due to firewall "
+"configuration."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:710
+msgid ""
+"If you get a <quote>no route to host</quote> error, you either have an "
+"incorrect address for the server or a seriously locked down firewall that "
+"won't admit its existence at all."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:715
+msgid ""
+"If you get a <quote>permission denied</quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:720
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:730
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:736
+msgid ""
+"You might have forgotten to use <command>ssh-add</command> or "
+"<command>pageant</command> to store the passphrase."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:740
+msgid "You might have stored the passphrase for the wrong key."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:743
+msgid ""
+"If you're being prompted for the remote user's password, there are another "
+"few possible problems to check."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:746
+msgid ""
+"Either the user's home directory or their <filename role=\"special\" class="
+"\"directory\">.ssh</filename> directory might have excessively liberal "
+"permissions.  As a result, the ssh daemon will not trust or read their "
+"<filename role=\"special\">authorized_keys</filename> file.  For example, a "
+"group-writable home or <filename role=\"special\" class=\"directory\">.ssh</"
+"filename> directory will often cause this symptom."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:755
+msgid ""
+"The user's <filename role=\"special\">authorized_keys</filename> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:762
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:767
+msgid ""
+"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</command> 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 <literal>tty -s</literal>.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:781
+msgid ""
+"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:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:788
+msgid ""
+"If you see an error message instead of normal <command role=\"hg-cmd\">hg "
+"version</command> output, this is usually because you haven't installed "
+"Mercurial to <filename class=\"directory\">/usr/bin</filename>.  Don't worry "
+"if this is the case; you don't need to do that.  But you should check for a "
+"few possible problems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:795
+msgid ""
+"Is Mercurial really installed on the server at all? I know this sounds "
+"trivial, but it's worth checking!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:799
+msgid ""
+"Maybe your shell's search path (usually set via the <envar>PATH</envar> "
+"environment variable) is simply misconfigured."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:803
+msgid ""
+"Perhaps your <envar>PATH</envar> environment variable is only being set to "
+"point to the location of the <command>hg</command> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:810
+msgid ""
+"The <envar>PYTHONPATH</envar> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:817
+msgid ""
+"If you can run <command role=\"hg-cmd\">hg version</command> 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 <option role=\"hg-opt-global\">--debug</option> "
+"option to get a clearer picture of what's going on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:827
+msgid "Using compression with ssh"
+msgstr "通过 ssh 使用压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:829
+msgid ""
+"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 <emphasis>not</emphasis> to request compression."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:834
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:841
+msgid ""
+"Both <command>ssh</command> and <command>plink</command> accept a <option "
+"role=\"cmd-opt-ssh\">-C</option> option which turns on compression.  You can "
+"easily edit your <filename role=\"special\">~/.hgrc</filename> to enable "
+"compression for all of Mercurial's uses of the ssh protocol."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:849
+msgid ""
+"If you use <command>ssh</command>, you can configure it to always use "
+"compression when talking to your server.  To do this, edit your <filename "
+"role=\"special\">.ssh/config</filename> file (which may not yet exist), as "
+"follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:857
+msgid ""
+"This defines an alias, <literal>hg</literal>.  When you use it on the "
+"<command>ssh</command> command line or in a Mercurial <literal>ssh</literal>-"
+"protocol URL, it will cause <command>ssh</command> to connect to <literal>hg."
+"example.com</literal> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:868
+msgid "Serving over HTTP using CGI"
+msgstr "使用 CGI 通过 HTTP 提供服务"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:870
+msgid ""
+"Depending on how ambitious you are, configuring Mercurial's CGI interface can "
+"take anything from a few moments to several hours."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:874
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch05-collab.xml:880
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:890
+msgid "Web server configuration checklist"
+msgstr "Web 服务器配置检查表"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:892
+msgid ""
+"Before you continue, do take a few moments to check a few aspects of your "
+"system's setup."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:896
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:900
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:904
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:910
+msgid ""
+"If you don't have a web server installed, and don't have substantial "
+"experience configuring Apache, you should consider using the "
+"<literal>lighttpd</literal> web server instead of Apache.  Apache has a well-"
+"deserved reputation for baroque and confusing configuration. While "
+"<literal>lighttpd</literal> is less capable in some ways than Apache, most of "
+"these capabilities are not relevant to serving Mercurial repositories.  And "
+"<literal>lighttpd</literal> is undeniably <emphasis>much</emphasis> easier to "
+"get started with than Apache."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:923
+msgid "Basic CGI configuration"
+msgstr "基本 CGI 配置"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:925
+msgid ""
+"On Unix-like systems, it's common for users to have a subdirectory named "
+"something like <filename class=\"directory\">public_html</filename> in their "
+"home directory, from which they can serve up web pages.  A file named "
+"<filename>foo</filename> in this directory will be accessible at a URL of the "
+"form <literal>http://www.example.com/username/foo</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:933
+msgid ""
+"To get started, find the <filename role=\"special\">hgweb.cgi</filename> "
+"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 <ulink url=\"http://www.selenic.com/repo/hg/raw-file/"
+"tip/hgweb.cgi\">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:940 ../en/ch05-collab.xml:1109
+msgid ""
+"You'll need to copy this script into your <filename class=\"directory"
+"\">public_html</filename> directory, and ensure that it's executable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:945
+msgid ""
+"The <literal>755</literal> argument to <command>chmod</command> is a little "
+"more general than just making the script executable: it ensures that the "
+"script is executable by anyone, and that <quote>group</quote> and "
+"<quote>other</quote> write permissions are <emphasis>not</emphasis> set.  If "
+"you were to leave those write permissions enabled, Apache's <literal>suexec</"
+"literal> subsystem would likely refuse to execute the script.  In fact, "
+"<literal>suexec</literal> also insists that the <emphasis>directory</"
+"emphasis> in which the script resides must not be writable by others."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:959
+msgid "What could <emphasis>possibly</emphasis> go wrong?"
+msgstr "什么<emphasis>可能</emphasis>会出错?"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:962
+msgid ""
+"Once you've copied the CGI script into place, go into a web browser, and try "
+"to open the URL <ulink url=\"http://myhostname/ myuser/hgweb.cgi\">http://"
+"myhostname/ myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:976
+msgid ""
+"Your web server may have per-user directories disabled.  If you're using "
+"Apache, search your config file for a <literal>UserDir</literal> directive.  "
+"If there's none present, per-user directories will be disabled.  If one "
+"exists, but its value is <literal>disabled</literal>, then per-user "
+"directories will be disabled.  Otherwise, the string after <literal>UserDir</"
+"literal> gives the name of the subdirectory that Apache will look in under "
+"your home directory, for example <filename class=\"directory\">public_html</"
+"filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:987
+msgid ""
+"Your file access permissions may be too restrictive.  The web server must be "
+"able to traverse your home directory and directories under your <filename "
+"class=\"directory\">public_html</filename> directory, and read files under "
+"the latter too.  Here's a quick recipe to help you to make your permissions "
+"more appropriate."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:997
+msgid ""
+"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 <emphasis>too permissive</emphasis>.  Apache's "
+"<literal>suexec</literal> subsystem won't execute a script that's group- or "
+"world-writable, for example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1004
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1011
+msgid ""
+"If you find a similar-looking <literal>Directory</literal> group in your "
+"Apache configuration, the directive to look at inside it is <literal>Options</"
+"literal>. Add <literal>ExecCGI</literal> to the end of this list if it's "
+"missing, and restart the web server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1018
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1024
+msgid ""
+"The next possibility is that you might be served with a colourful Python "
+"backtrace claiming that it can't import a <literal>mercurial</literal>-"
+"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 <filename role="
+"\"special\">hgweb.cgi</filename> and follow the directions inside it to "
+"correctly set your <envar>PYTHONPATH</envar> environment variable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1038
+msgid ""
+"Finally, you are <emphasis>certain</emphasis> to by served with another "
+"colourful Python backtrace: this one will complain that it can't find "
+"<filename class=\"directory\">/path/to/repository</filename>.  Edit your "
+"<filename role=\"special\">hgweb.cgi</filename> script and replace the "
+"<filename class=\"directory\">/path/to/repository</filename> string with the "
+"complete path to the repository you want to serve up."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1048
+msgid ""
+"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!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:1054
+msgid "Configuring lighttpd"
+msgstr "配置 lighttpd"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1056
+msgid ""
+"To be exhaustive in my experiments, I tried configuring the increasingly "
+"popular <literal>lighttpd</literal> 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 <filename role=\"special\">hgweb.cgi</filename> script was properly edited."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1066
+msgid ""
+"Once I had Apache running, getting <literal>lighttpd</literal> to serve the "
+"repository was a snap (in other words, even if you're trying to use "
+"<literal>lighttpd</literal>, you should read the Apache section).  I first "
+"had to edit the <literal>mod_access</literal> section of its config file to "
+"enable <literal>mod_cgi</literal> and <literal>mod_userdir</literal>, 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1078
+msgid ""
+"With this done, <literal>lighttpd</literal> ran immediately for me.  If I had "
+"configured <literal>lighttpd</literal> 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 <literal>lighttpd</literal> 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 <literal>lighttpd</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:1091
+msgid "Sharing multiple repositories with one CGI script"
+msgstr "使用一个 CGI 脚本共享多个版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1093
+msgid ""
+"The <filename role=\"special\">hgweb.cgi</filename> 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 "
+"<filename role=\"special\">hgwebdir.cgi</filename> script."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1101
+msgid ""
+"The procedure to configure <filename role=\"special\">hgwebdir.cgi</filename> "
+"is only a little more involved than for <filename role=\"special\">hgweb.cgi</"
+"filename>.  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 "
+"<ulink url=\"http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi"
+"\">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1116
+msgid ""
+"With basic configuration out of the way, try to visit <ulink url=\"http://"
+"myhostname/ myuser/hgwebdir.cgi\">http://myhostname/ myuser/hgwebdir.cgi</"
+"ulink> 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 <xref linkend=\"sec:collab:wtf\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1125
+msgid ""
+"The <filename role=\"special\">hgwebdir.cgi</filename> script relies on an "
+"external configuration file.  By default, it searches for a file named "
+"<filename role=\"special\">hgweb.config</filename> 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 <quote>ini</quote> file, as "
+"understood by Python's <literal>ConfigParser</literal> <citation>web:"
+"configparser</citation> module."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1135
+msgid ""
+"The easiest way to configure <filename role=\"special\">hgwebdir.cgi</"
+"filename> is with a section named <literal>collections</literal>.  This will "
+"automatically publish <emphasis>every</emphasis> repository under the "
+"directories you name.  The section should look like this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1143
+msgid ""
+"Mercurial interprets this by looking at the directory name on the "
+"<emphasis>right</emphasis> hand side of the <quote><literal>=</literal></"
+"quote> sign; finding repositories in that directory hierarchy; and using the "
+"text on the <emphasis>left</emphasis> 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 <quote>virtual path</"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1152
+msgid ""
+"Given the example above, if we have a repository whose local path is "
+"<filename class=\"directory\">/my/root/this/repo</filename>, the CGI script "
+"will strip the leading <filename class=\"directory\">/my/root</filename> from "
+"the name, and publish the repository with a virtual path of <filename class="
+"\"directory\">this/repo</filename>.  If the base URL for our CGI script is "
+"<ulink url=\"http://myhostname/ myuser/hgwebdir.cgi\">http://myhostname/ "
+"myuser/hgwebdir.cgi</ulink>, the complete URL for that repository will be "
+"<ulink url=\"http://myhostname/ myuser/hgwebdir.cgi/this/repo\">http://"
+"myhostname/ myuser/hgwebdir.cgi/this/repo</ulink>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1166
+msgid ""
+"If we replace <filename class=\"directory\">/my/root</filename> on the left "
+"hand side of this example with <filename class=\"directory\">/my</filename>, "
+"then <filename role=\"special\">hgwebdir.cgi</filename> will only strip off "
+"<filename class=\"directory\">/my</filename> from the repository name, and "
+"will give us a virtual path of <filename class=\"directory\">root/this/repo</"
+"filename> instead of <filename class=\"directory\">this/repo</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1176
+msgid ""
+"The <filename role=\"special\">hgwebdir.cgi</filename> script will "
+"recursively search each directory listed in the <literal>collections</"
+"literal> section of its configuration file, but it will <literal>not</"
+"literal> recurse into the repositories it finds."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1182
+msgid ""
+"The <literal>collections</literal> mechanism makes it easy to publish many "
+"repositories in a <quote>fire and forget</quote> manner.  You only need to "
+"set up the CGI script and configuration file one time.  Afterwards, you can "
+"publish or unpublish a repository at any time by simply moving it into, or "
+"out of, the directory hierarchy in which you've configured <filename role="
+"\"special\">hgwebdir.cgi</filename> to look."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:1192
+msgid "Explicitly specifying which repositories to publish"
+msgstr "明确指出要发布的版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1195
+msgid ""
+"In addition to the <literal>collections</literal> mechanism, the <filename "
+"role=\"special\">hgwebdir.cgi</filename> script allows you to publish a "
+"specific list of repositories.  To do so, create a <literal>paths</literal> "
+"section, with contents of the following form."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1204
+msgid ""
+"In this case, the virtual path (the component that will appear in a URL) is "
+"on the left hand side of each definition, while the path to the repository is "
+"on the right.  Notice that there does not need to be any relationship between "
+"the virtual path you choose and the location of a repository in your "
+"filesystem."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1211
+msgid ""
+"If you wish, you can use both the <literal>collections</literal> and "
+"<literal>paths</literal> mechanisms simultaneously in a single configuration "
+"file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><note><para>
+#: ../en/ch05-collab.xml:1217
+msgid ""
+"If multiple repositories have the same virtual path, <filename role=\"special"
+"\">hgwebdir.cgi</filename> will not report an error.  Instead, it will behave "
+"unpredictably."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:1226
+msgid "Downloading source archives"
+msgstr "下载源代码档案包"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1228
+msgid ""
+"Mercurial's web interface lets users download an archive of any revision.  "
+"This archive will contain a snapshot of the working directory as of that "
+"revision, but it will not contain a copy of the repository data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1233
+msgid ""
+"By default, this feature is not enabled.  To enable it, you'll need to add an "
+"<envar role=\"rc-item-web\">allow_archive</envar> item to the <literal role="
+"\"rc-web\">web</literal> section of your <filename role=\"special\">~/.hgrc</"
+"filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch05-collab.xml:1241
+msgid "Web configuration options"
+msgstr "Web 配置选项"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1243
+msgid ""
+"Mercurial's web interfaces (the <command role=\"hg-cmd\">hg serve</command> "
+"command, and the <filename role=\"special\">hgweb.cgi</filename> and "
+"<filename role=\"special\">hgwebdir.cgi</filename> scripts) have a number of "
+"configuration options that you can set.  These belong in a section named "
+"<literal role=\"rc-web\">web</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1251
+msgid ""
+"<envar role=\"rc-item-web\">allow_archive</envar>: Determines which (if any) "
+"archive download mechanisms Mercurial supports.  If you enable this feature, "
+"users of the web interface will be able to download an archive of whatever "
+"revision of a repository they are viewing. To enable the archive feature, "
+"this item must take the form of a sequence of words drawn from the list below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1260
+msgid ""
+"<literal>bz2</literal>: A <command>tar</command> archive, compressed using "
+"<literal>bzip2</literal> compression.  This has the best compression ratio, "
+"but uses the most CPU time on the server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1266
+msgid ""
+"<literal>gz</literal>: A <command>tar</command> archive, compressed using "
+"<literal>gzip</literal> compression."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1270
+msgid ""
+"<literal>zip</literal>: A <command>zip</command> archive, compressed using "
+"LZW compression.  This format has the worst compression ratio, but is widely "
+"used in the Windows world."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1276
+msgid ""
+"If you provide an empty list, or don't have an <envar role=\"rc-item-web"
+"\">allow_archive</envar> entry at all, this feature will be disabled.  Here "
+"is an example of how to enable all three supported formats."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1283
+msgid ""
+"<envar role=\"rc-item-web\">allowpull</envar>: Boolean.  Determines whether "
+"the web interface allows remote users to <command role=\"hg-cmd\">hg pull</"
+"command> and <command role=\"hg-cmd\">hg clone</command> this repository over "
+"HTTP.  If set to <literal>no</literal> or <literal>false</literal>, only the "
+"<quote>human-oriented</quote> portion of the web interface is available."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1292
+msgid ""
+"<envar role=\"rc-item-web\">contact</envar>: String.  A free-form (but "
+"preferably brief) string identifying the person or group in charge of the "
+"repository.  This often contains the name and email address of a person or "
+"mailing list.  It often makes sense to place this entry in a repository's own "
+"<filename role=\"special\">.hg/hgrc</filename> file, but it can make sense to "
+"use in a global <filename role=\"special\">~/.hgrc</filename> if every "
+"repository has a single maintainer."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1303
+msgid ""
+"<envar role=\"rc-item-web\">maxchanges</envar>: Integer.  The default maximum "
+"number of changesets to display in a single page of output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1307
+msgid ""
+"<envar role=\"rc-item-web\">maxfiles</envar>: Integer.  The default maximum "
+"number of modified files to display in a single page of output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1311
+msgid ""
+"<envar role=\"rc-item-web\">stripes</envar>: Integer.  If the web interface "
+"displays alternating <quote>stripes</quote> to make it easier to visually "
+"align rows when you are looking at a table, this number controls the number "
+"of rows in each stripe."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1317
+msgid ""
+"<envar role=\"rc-item-web\">style</envar>: Controls the template Mercurial "
+"uses to display the web interface.  Mercurial ships with two web templates, "
+"named <literal>default</literal> and <literal>gitweb</literal> (the latter is "
+"much more visually attractive).  You can also specify a custom template of "
+"your own; see <xref linkend=\"chap:template\"/> for details. Here, you can "
+"see how to enable the <literal>gitweb</literal> style."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1330
+msgid ""
+"<envar role=\"rc-item-web\">templates</envar>: Path.  The directory in which "
+"to search for template files.  By default, Mercurial searches in the "
+"directory in which it was installed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1335
+msgid ""
+"If you are using <filename role=\"special\">hgwebdir.cgi</filename>, you can "
+"place a few configuration items in a <literal role=\"rc-web\">web</literal> "
+"section of the <filename role=\"special\">hgweb.config</filename> file "
+"instead of a <filename role=\"special\">~/.hgrc</filename> file, for "
+"convenience.  These items are <envar role=\"rc-item-web\">motd</envar> and "
+"<envar role=\"rc-item-web\">style</envar>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:1346
+msgid "Options specific to an individual repository"
+msgstr "针对单个版本库的选项"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1348
+msgid ""
+"A few <literal role=\"rc-web\">web</literal> configuration items ought to be "
+"placed in a repository's local <filename role=\"special\">.hg/hgrc</"
+"filename>, rather than a user's or global <filename role=\"special\">~/.hgrc</"
+"filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1353
+msgid ""
+"<envar role=\"rc-item-web\">description</envar>: String.  A free-form (but "
+"preferably brief) string that describes the contents or purpose of the "
+"repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1358
+msgid ""
+"<envar role=\"rc-item-web\">name</envar>: String.  The name to use for the "
+"repository in the web interface.  This overrides the default name, which is "
+"the last component of the repository's path."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:1366
+msgid ""
+"Options specific to the <command role=\"hg-cmd\">hg serve</command> command"
+msgstr "命令 <command role=\"hg-cmd\">hg serve</command> 的选项"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1369
+msgid ""
+"Some of the items in the <literal role=\"rc-web\">web</literal> section of a "
+"<filename role=\"special\">~/.hgrc</filename> file are only for use with the "
+"<command role=\"hg-cmd\">hg serve</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1375
+msgid ""
+"<envar role=\"rc-item-web\">accesslog</envar>: Path.  The name of a file into "
+"which to write an access log.  By default, the <command role=\"hg-cmd\">hg "
+"serve</command> command writes this information to standard output, not to a "
+"file.  Log entries are written in the standard <quote>combined</quote> file "
+"format used by almost all web servers."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1383
+msgid ""
+"<envar role=\"rc-item-web\">address</envar>: String.  The local address on "
+"which the server should listen for incoming connections.  By default, the "
+"server listens on all addresses."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1388
+msgid ""
+"<envar role=\"rc-item-web\">errorlog</envar>: Path.  The name of a file into "
+"which to write an error log.  By default, the <command role=\"hg-cmd\">hg "
+"serve</command> command writes this information to standard error, not to a "
+"file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1394
+msgid ""
+"<envar role=\"rc-item-web\">ipv6</envar>: Boolean.  Whether to use the IPv6 "
+"protocol. By default, IPv6 is not used."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch05-collab.xml:1398
+msgid ""
+"<envar role=\"rc-item-web\">port</envar>: Integer.  The TCP port number on "
+"which the server should listen.  The default port number used is 8000."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch05-collab.xml:1405
+msgid ""
+"Choosing the right <filename role=\"special\">~/.hgrc</filename> file to add "
+"<literal role=\"rc-web\">web</literal> items to"
+msgstr ""
+"选择正确的 <filename role=\"special\"> ~/.hgrc</filename> 文件增加到 <literal "
+"role=\"rc-web\">web</literal> 条目"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1409
+msgid ""
+"It is important to remember that a web server like Apache or "
+"<literal>lighttpd</literal> will run under a user ID that is different to "
+"yours. CGI scripts run by your server, such as <filename role=\"special"
+"\">hgweb.cgi</filename>, will usually also run under that user ID."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1416
+msgid ""
+"If you add <literal role=\"rc-web\">web</literal> items to your own personal "
+"<filename role=\"special\">~/.hgrc</filename> file, CGI scripts won't read "
+"that <filename role=\"special\">~/.hgrc</filename> file.  Those settings will "
+"thus only affect the behaviour of the <command role=\"hg-cmd\">hg serve</"
+"command> command when you run it.  To cause CGI scripts to see your settings, "
+"either create a <filename role=\"special\">~/.hgrc</filename> file in the "
+"home directory of the user ID that runs your web server, or add those "
+"settings to a system-wide <filename role=\"special\">~/.hgrc</filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch06-filenames.xml:5
+msgid "File names and pattern matching"
+msgstr "文件名称与模式匹配"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch06-filenames.xml:7
+msgid ""
+"Mercurial provides mechanisms that let you work with file names in a "
+"consistent and expressive way."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:11
+msgid "Simple file naming"
+msgstr "简单文件名称"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:13
+msgid ""
+"Mercurial uses a unified piece of machinery <quote>under the hood</quote> to "
+"handle file names.  Every command behaves uniformly with respect to file "
+"names.  The way in which commands work with file names is as follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:18
+msgid ""
+"If you explicitly name real files on the command line, Mercurial works with "
+"exactly those files, as you would expect.  &interaction.filenames.files;"
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:22
+msgid ""
+"When you provide a directory name, Mercurial will interpret this as "
+"<quote>operate on every file in this directory and its subdirectories</"
+"quote>. Mercurial traverses the files and subdirectories in a directory in "
+"alphabetical order.  When it encounters a subdirectory, it will traverse that "
+"subdirectory before continuing with the current directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:33
+msgid "Running commands without any file names"
+msgstr "不提供文件名称的执行命令"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:35
+msgid ""
+"Mercurial's commands that work with file names have useful default behaviours "
+"when you invoke them without providing any file names or patterns.  What kind "
+"of behaviour you should expect depends on what the command does.  Here are a "
+"few rules of thumb you can use to predict what a command is likely to do if "
+"you don't give it any names to work with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:42
+msgid ""
+"Most commands will operate on the entire working directory. This is what the "
+"<command role=\"hg-cmd\">hg add</command> command does, for example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:46
+msgid ""
+"If the command has effects that are difficult or impossible to reverse, it "
+"will force you to explicitly provide at least one name or pattern (see "
+"below).  This protects you from accidentally deleting files by running "
+"<command role=\"hg-cmd\">hg remove</command> with no arguments, for example."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:54
+msgid ""
+"It's easy to work around these default behaviours if they don't suit you.  If "
+"a command normally operates on the whole working directory, you can invoke it "
+"on just the current directory and its subdirectories by giving it the name "
+"<quote><filename class=\"directory\">.</filename></quote>."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:62
+msgid ""
+"Along the same lines, some commands normally print file names relative to the "
+"root of the repository, even if you're invoking them from a subdirectory.  "
+"Such a command will print file names relative to your subdirectory if you "
+"give it explicit names.  Here, we're going to run <command role=\"hg-cmd\">hg "
+"status</command> from a subdirectory, and get it to operate on the entire "
+"working directory while printing file names relative to our subdirectory, by "
+"passing it the output of the <command role=\"hg-cmd\">hg root</command> "
+"command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:76
+msgid "Telling you what's going on"
+msgstr "告诉你正在做什么"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:78
+msgid ""
+"The <command role=\"hg-cmd\">hg add</command> example in the preceding "
+"section illustrates something else that's helpful about Mercurial commands.  "
+"If a command operates on a file that you didn't name explicitly on the "
+"command line, it will usually print the name of the file, so that you will "
+"not be surprised what's going on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:85
+msgid ""
+"The principle here is of <emphasis>least surprise</emphasis>.  If you've "
+"exactly named a file on the command line, there's no point in repeating it "
+"back at you.  If Mercurial is acting on a file <emphasis>implicitly</"
+"emphasis>, because you provided no names, or a directory, or a pattern (see "
+"below), it's safest to tell you what it's doing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:92
+msgid ""
+"For commands that behave this way, you can silence them using the <option "
+"role=\"hg-opt-global\">-q</option> option.  You can also get them to print "
+"the name of every file, even those you've named explicitly, using the <option "
+"role=\"hg-opt-global\">-v</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:100
+msgid "Using patterns to identify files"
+msgstr "使用模式标识文件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:102
+msgid ""
+"In addition to working with file and directory names, Mercurial lets you use "
+"<emphasis>patterns</emphasis> to identify files.  Mercurial's pattern "
+"handling is expressive."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:106
+msgid ""
+"On Unix-like systems (Linux, MacOS, etc.), the job of matching file names to "
+"patterns normally falls to the shell.  On these systems, you must explicitly "
+"tell Mercurial that a name is a pattern.  On Windows, the shell does not "
+"expand patterns, so Mercurial will automatically identify names that are "
+"patterns, and expand them for you."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:113
+msgid ""
+"To provide a pattern in place of a regular name on the command line, the "
+"mechanism is simple:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:116
+msgid ""
+"That is, a pattern is identified by a short text string that says what kind "
+"of pattern this is, followed by a colon, followed by the actual pattern."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:120
+msgid ""
+"Mercurial supports two kinds of pattern syntax.  The most frequently used is "
+"called <literal>glob</literal>; this is the same kind of pattern matching "
+"used by the Unix shell, and should be familiar to Windows command prompt "
+"users, too."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:125
+msgid ""
+"When Mercurial does automatic pattern matching on Windows, it uses "
+"<literal>glob</literal> syntax.  You can thus omit the <quote><literal>glob:</"
+"literal></quote> prefix on Windows, but it's safe to use it, too."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:130
+msgid ""
+"The <literal>re</literal> syntax is more powerful; it lets you specify "
+"patterns using regular expressions, also known as regexps."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:134
+msgid ""
+"By the way, in the examples that follow, notice that I'm careful to wrap all "
+"of my patterns in quote characters, so that they won't get expanded by the "
+"shell before Mercurial sees them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch06-filenames.xml:140
+msgid "Shell-style <literal>glob</literal> patterns"
+msgstr "外壳风格的 <literal>glob</literal>  模式"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:142
+msgid ""
+"This is an overview of the kinds of patterns you can use when you're matching "
+"on glob patterns."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:145
+msgid ""
+"The <quote><literal>*</literal></quote> character matches any string, within "
+"a single directory."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:150
+msgid ""
+"The <quote><literal>**</literal></quote> pattern matches any string, and "
+"crosses directory boundaries.  It's not a standard Unix glob token, but it's "
+"accepted by several popular Unix shells, and is very useful."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:157
+msgid ""
+"The <quote><literal>?</literal></quote> pattern matches any single character."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:162
+msgid ""
+"The <quote><literal>[</literal></quote> character begins a "
+"<emphasis>character class</emphasis>.  This matches any single character "
+"within the class.  The class ends with a <quote><literal>]</literal></quote> "
+"character.  A class may contain multiple <emphasis>range</emphasis>s of the "
+"form <quote><literal>a-f</literal></quote>, which is shorthand for "
+"<quote><literal>abcdef</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:172
+msgid ""
+"If the first character after the <quote><literal>[</literal></quote> in a "
+"character class is a <quote><literal>!</literal></quote>, it "
+"<emphasis>negates</emphasis> the class, making it match any single character "
+"not in the class."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:178
+msgid ""
+"A <quote><literal>{</literal></quote> begins a group of subpatterns, where "
+"the whole group matches if any subpattern in the group matches.  The "
+"<quote><literal>,</literal></quote> character separates subpatterns, and "
+"<quote><literal>}</literal></quote> ends the group."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch06-filenames.xml:187
+msgid "Watch out!"
+msgstr "千万小心!"
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch06-filenames.xml:189
+msgid ""
+"Don't forget that if you want to match a pattern in any directory, you should "
+"not be using the <quote><literal>*</literal></quote> match-any token, as this "
+"will only match within one directory.  Instead, use the <quote><literal>**</"
+"literal></quote> token.  This small example illustrates the difference "
+"between the two."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch06-filenames.xml:201
+msgid "Regular expression matching with <literal>re</literal> patterns"
+msgstr "使用 <literal>re</literal> 模式的正则表达式匹配"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:204
+msgid ""
+"Mercurial accepts the same regular expression syntax as the Python "
+"programming language (it uses Python's regexp engine internally). This is "
+"based on the Perl language's regexp syntax, which is the most popular dialect "
+"in use (it's also used in Java, for example)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:210
+msgid ""
+"I won't discuss Mercurial's regexp dialect in any detail here, as regexps are "
+"not often used.  Perl-style regexps are in any case already exhaustively "
+"documented on a multitude of web sites, and in many books.  Instead, I will "
+"focus here on a few things you should know if you find yourself needing to "
+"use regexps with Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:217
+msgid ""
+"A regexp is matched against an entire file name, relative to the root of the "
+"repository.  In other words, even if you're already in subbdirectory "
+"<filename class=\"directory\">foo</filename>, if you want to match files "
+"under this directory, your pattern must start with <quote><literal>foo/</"
+"literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:224
+msgid ""
+"One thing to note, if you're familiar with Perl-style regexps, is that "
+"Mercurial's are <emphasis>rooted</emphasis>.  That is, a regexp starts "
+"matching against the beginning of a string; it doesn't look for a match "
+"anywhere within the string.  To match anywhere in a string, start your "
+"pattern with <quote><literal>.*</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:234
+msgid "Filtering files"
+msgstr "过滤文件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:236
+msgid ""
+"Not only does Mercurial give you a variety of ways to specify files; it lets "
+"you further winnow those files using <emphasis>filters</emphasis>.  Commands "
+"that work with file names accept two filtering options."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:241
+msgid ""
+"<option role=\"hg-opt-global\">-I</option>, or <option role=\"hg-opt-global"
+"\">--include</option>, lets you specify a pattern that file names must match "
+"in order to be processed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:246
+msgid ""
+"<option role=\"hg-opt-global\">-X</option>, or <option role=\"hg-opt-global"
+"\">--exclude</option>, gives you a way to <emphasis>avoid</emphasis> "
+"processing files, if they match this pattern."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:251
+msgid ""
+"You can provide multiple <option role=\"hg-opt-global\">-I</option> and "
+"<option role=\"hg-opt-global\">-X</option> options on the command line, and "
+"intermix them as you please.  Mercurial interprets the patterns you provide "
+"using glob syntax by default (but you can use regexps if you need to)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:258
+msgid ""
+"You can read a <option role=\"hg-opt-global\">-I</option> filter as "
+"<quote>process only the files that match this filter</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:264
+msgid ""
+"The <option role=\"hg-opt-global\">-X</option> filter is best read as "
+"<quote>process only the files that don't match this pattern</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:272
+msgid "Ignoring unwanted files and directories"
+msgstr "忽略不需要的文件和目录"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:274
+msgid "XXX."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch06-filenames.xml:278
+msgid "Case sensitivity"
+msgstr "大小写敏感性"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:280
+msgid ""
+"If you're working in a mixed development environment that contains both Linux "
+"(or other Unix) systems and Macs or Windows systems, you should keep in the "
+"back of your mind the knowledge that they treat the case (<quote>N</quote> "
+"versus <quote>n</quote>) of file names in incompatible ways.  This is not "
+"very likely to affect you, and it's easy to deal with if it does, but it "
+"could surprise you if you don't know about it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:289
+msgid ""
+"Operating systems and filesystems differ in the way they handle the "
+"<emphasis>case</emphasis> of characters in file and directory names.  There "
+"are three common ways to handle case in names."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:294
+msgid ""
+"Completely case insensitive.  Uppercase and lowercase versions of a letter "
+"are treated as identical, both when creating a file and during subsequent "
+"accesses.  This is common on older DOS-based systems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:299
+msgid ""
+"Case preserving, but insensitive.  When a file or directory is created, the "
+"case of its name is stored, and can be retrieved and displayed by the "
+"operating system.  When an existing file is being looked up, its case is "
+"ignored.  This is the standard arrangement on Windows and MacOS.  The names "
+"<filename>foo</filename> and <filename>FoO</filename> identify the same "
+"file.  This treatment of uppercase and lowercase letters as interchangeable "
+"is also referred to as <emphasis>case folding</emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch06-filenames.xml:310
+msgid ""
+"Case sensitive.  The case of a name is significant at all times. The names "
+"<filename>foo</filename> and {FoO} identify different files.  This is the way "
+"Linux and Unix systems normally work."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch06-filenames.xml:316
+msgid ""
+"On Unix-like systems, it is possible to have any or all of the above ways of "
+"handling case in action at once.  For example, if you use a USB thumb drive "
+"formatted with a FAT32 filesystem on a Linux system, Linux will handle names "
+"on that filesystem in a case preserving, but insensitive, way."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch06-filenames.xml:323
+msgid "Safe, portable repository storage"
+msgstr "安全,可移植的版本库存储"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:325
+msgid ""
+"Mercurial's repository storage mechanism is <emphasis>case safe</emphasis>.  "
+"It translates file names so that they can be safely stored on both case "
+"sensitive and case insensitive filesystems.  This means that you can use "
+"normal file copying tools to transfer a Mercurial repository onto, for "
+"example, a USB thumb drive, and safely move that drive and repository back "
+"and forth between a Mac, a PC running Windows, and a Linux box."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch06-filenames.xml:336
+msgid "Detecting case conflicts"
+msgstr "检测大小写冲突"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:338
+msgid ""
+"When operating in the working directory, Mercurial honours the naming policy "
+"of the filesystem where the working directory is located.  If the filesystem "
+"is case preserving, but insensitive, Mercurial will treat names that differ "
+"only in case as the same."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:344
+msgid ""
+"An important aspect of this approach is that it is possible to commit a "
+"changeset on a case sensitive (typically Linux or Unix) filesystem that will "
+"cause trouble for users on case insensitive (usually Windows and MacOS) "
+"users.  If a Linux user commits changes to two files, one named "
+"<filename>myfile.c</filename> and the other named <filename>MyFile.C</"
+"filename>, they will be stored correctly in the repository.  And in the "
+"working directories of other Linux users, they will be correctly represented "
+"as separate files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:355
+msgid ""
+"If a Windows or Mac user pulls this change, they will not initially have a "
+"problem, because Mercurial's repository storage mechanism is case safe.  "
+"However, once they try to <command role=\"hg-cmd\">hg update</command> the "
+"working directory to that changeset, or <command role=\"hg-cmd\">hg merge</"
+"command> with that changeset, Mercurial will spot the conflict between the "
+"two file names that the filesystem would treat as the same, and forbid the "
+"update or merge from occurring."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch06-filenames.xml:367
+msgid "Fixing a case conflict"
+msgstr "修正大小写冲突"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:369
+msgid ""
+"If you are using Windows or a Mac in a mixed environment where some of your "
+"collaborators are using Linux or Unix, and Mercurial reports a case folding "
+"conflict when you try to <command role=\"hg-cmd\">hg update</command> or "
+"<command role=\"hg-cmd\">hg merge</command>, the procedure to fix the problem "
+"is simple."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:376
+msgid ""
+"Just find a nearby Linux or Unix box, clone the problem repository onto it, "
+"and use Mercurial's <command role=\"hg-cmd\">hg rename</command> command to "
+"change the names of any offending files or directories so that they will no "
+"longer cause case folding conflicts.  Commit this change, <command role=\"hg-"
+"cmd\">hg pull</command> or <command role=\"hg-cmd\">hg push</command> it "
+"across to your Windows or MacOS system, and <command role=\"hg-cmd\">hg "
+"update</command> to the revision with the non-conflicting names."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch06-filenames.xml:386
+msgid ""
+"The changeset with case-conflicting names will remain in your project's "
+"history, and you still won't be able to <command role=\"hg-cmd\">hg update</"
+"command> your working directory to that changeset on a Windows or MacOS "
+"system, but you can continue development unimpeded."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch06-filenames.xml:393
+msgid ""
+"Prior to version 0.9.3, Mercurial did not use a case safe repository storage "
+"mechanism, and did not detect case folding conflicts.  If you are using an "
+"older version of Mercurial on Windows or MacOS, I strongly recommend that you "
+"upgrade."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch07-branch.xml:5
+msgid "Managing releases and branchy development"
+msgstr "发布管理与分支开发"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch07-branch.xml:7
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch07-branch.xml:12
+msgid ""
+"Many software projects issue periodic <quote>major</quote> releases that "
+"contain substantial new features.  In parallel, they may issue <quote>minor</"
+"quote> releases.  These are usually identical to the major releases off which "
+"they're based, but with a few bugs fixed."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch07-branch.xml:18
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:25
+msgid "Giving a persistent name to a revision"
+msgstr "给版本指定一个永久的名称"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:27
+msgid ""
+"Once you decide that you'd like to call a particular revision a "
+"<quote>release</quote>, 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;"
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:34
+msgid ""
+"Mercurial lets you give a permanent name to any revision using the <command "
+"role=\"hg-cmd\">hg tag</command> command.  Not surprisingly, these names are "
+"called <quote>tags</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:40
+msgid ""
+"A tag is nothing more than a <quote>symbolic name</quote> 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:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch07-branch.xml:49
+msgid "Colon (ASCII 58, <quote><literal>:</literal></quote>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch07-branch.xml:52
+msgid "Carriage return (ASCII 13, <quote><literal>\\r</literal></quote>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch07-branch.xml:55
+msgid "Newline (ASCII 10, <quote><literal>\\n</literal></quote>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:59
+msgid ""
+"You can use the <command role=\"hg-cmd\">hg tags</command> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:67
+msgid ""
+"Notice that <literal>tip</literal> is listed in the output of <command role="
+"\"hg-cmd\">hg tags</command>.  The <literal>tip</literal> tag is a special "
+"<quote>floating</quote> tag, which always identifies the newest revision in "
+"the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:73
+msgid ""
+"In the output of the <command role=\"hg-cmd\">hg tags</command> 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 <literal>tip</"
+"literal> is always going to be the first tag listed in the output of <command "
+"role=\"hg-cmd\">hg tags</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:80
+msgid ""
+"When you run <command role=\"hg-cmd\">hg log</command>, if it displays a "
+"revision that has tags associated with it, it will print those tags."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:86
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:93
+msgid ""
+"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 <quote>too many</quote> (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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:101
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:109
+msgid ""
+"If you want to remove a tag that you no longer want, use <command role=\"hg-"
+"cmd\">hg tag --remove</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:114
+msgid ""
+"You can also modify a tag at any time, so that it identifies a different "
+"revision, by simply issuing a new <command role=\"hg-cmd\">hg tag</command> "
+"command. You'll have to use the <option role=\"hg-opt-tag\">-f</option> "
+"option to tell Mercurial that you <emphasis>really</emphasis> want to update "
+"the tag."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:123
+msgid ""
+"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."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:129
+msgid ""
+"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 "
+"<filename role=\"special\">.hgtags</filename>.  When you run the <command "
+"role=\"hg-cmd\">hg tag</command> command, Mercurial modifies this file, then "
+"automatically commits the change to it.  This means that every time you run "
+"<command role=\"hg-cmd\">hg tag</command>, you'll see a corresponding "
+"changeset in the output of <command role=\"hg-cmd\">hg log</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch07-branch.xml:142
+msgid "Handling tag conflicts during a merge"
+msgstr "在合并期间处理标签冲突"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:144
+msgid ""
+"You won't often need to care about the <filename role=\"special\">.hgtags</"
+"filename> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:151
+msgid ""
+"If you're resolving a conflict in the <filename role=\"special\">.hgtags</"
+"filename> file during a merge, there's one twist to modifying the <filename "
+"role=\"special\">.hgtags</filename> file: when Mercurial is parsing the tags "
+"in a repository, it <emphasis>never</emphasis> reads the working copy of the "
+"<filename role=\"special\">.hgtags</filename> file.  Instead, it reads the "
+"<emphasis>most recently committed</emphasis> revision of the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:161
+msgid ""
+"An unfortunate consequence of this design is that you can't actually verify "
+"that your merged <filename role=\"special\">.hgtags</filename> file is "
+"correct until <emphasis>after</emphasis> you've committed a change.  So if "
+"you find yourself resolving a conflict on <filename role=\"special\">.hgtags</"
+"filename> during a merge, be sure to run <command role=\"hg-cmd\">hg tags</"
+"command> after you commit.  If it finds an error in the <filename role="
+"\"special\">.hgtags</filename> file, it will report the location of the "
+"error, which you can then fix and commit.  You should then run <command role="
+"\"hg-cmd\">hg tags</command> again, just to be sure that your fix is correct."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch07-branch.xml:176
+msgid "Tags and cloning"
+msgstr "标签与克隆"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:178
+msgid ""
+"You may have noticed that the <command role=\"hg-cmd\">hg clone</command> "
+"command has a <option role=\"hg-opt-clone\">-r</option> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:186
+msgid ""
+"Recall that a tag is stored as a revision to the <filename role=\"special\">."
+"hgtags</filename> file, so that when you create a tag, the changeset in which "
+"it's recorded necessarily refers to an older changeset.  When you run "
+"<command role=\"hg-cmd\">hg clone -r foo</command> to clone a repository as "
+"of tag <literal>foo</literal>, the new clone <emphasis>will not contain the "
+"history that created the tag</emphasis> 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 <emphasis>not</emphasis> the tag "
+"you might have expected."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch07-branch.xml:201
+msgid "When permanent tags are too much"
+msgstr "当永久标签太多的时候"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:203
+msgid ""
+"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 "
+"<literal>4237e45506ee</literal> is really <literal>v2.0.2</literal>.  If "
+"you're trying to track down a subtle bug, you might want a tag to remind you "
+"of something like <quote>Anne saw the symptoms with this revision</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch07-branch.xml:213
+msgid ""
+"For cases like this, what you might want to use are <emphasis>local</"
+"emphasis> tags. You can create a local tag with the <option role=\"hg-opt-tag"
+"\">-l</option> option to the <command role=\"hg-cmd\">hg tag</command> "
+"command.  This will store the tag in a file called <filename role=\"special"
+"\">.hg/localtags</filename>.  Unlike <filename role=\"special\">.hgtags</"
+"filename>, <filename role=\"special\">.hg/localtags</filename> is not "
+"revision controlled.  Any tags you create using <option role=\"hg-opt-tag\">-"
+"l</option> remain strictly local to the repository you're currently working "
+"in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:228
+msgid "The flow of changes&emdash;big picture vs. little"
+msgstr "修改流程—宏观与微观"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:230
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:234
+msgid ""
+"There might be a push for a new <quote>main</quote> release; a new minor "
+"bugfix release to the last main release; and an unexpected <quote>hot fix</"
+"quote> to an old release that is now in maintenance mode."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:239
+msgid ""
+"The usual way people refer to these different concurrent directions of "
+"development is as <quote>branches</quote>.  However, we've already seen "
+"numerous times that Mercurial treats <emphasis>all of history</emphasis> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch07-branch.xml:246
+msgid ""
+"<quote>Big picture</quote> branches represent the sweep of a project's "
+"evolution; people give them names, and talk about them in conversation."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch07-branch.xml:250
+msgid ""
+"<quote>Little picture</quote> branches are artefacts of the day-to-day "
+"activity of developing and merging changes.  They expose the narrative of how "
+"the code was developed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:258
+msgid "Managing big-picture branches in repositories"
+msgstr "在版本库中管理分支"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:260
+msgid ""
+"The easiest way to isolate a <quote>big picture</quote> branch in Mercurial "
+"is in a dedicated repository.  If you have an existing shared "
+"repository&emdash;let's call it <literal>myproject</literal>&emdash;that "
+"reaches a <quote>1.0</quote> 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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:270
+msgid ""
+"You can then clone a new shared <literal>myproject-1.0.1</literal> repository "
+"as of that tag."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:276
+msgid ""
+"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 <literal>myproject-1.0.1</"
+"literal> repository, make their changes, and push them back."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:283
+msgid ""
+"Meanwhile, development for the next major release can continue, isolated and "
+"unabated, in the <literal>myproject</literal> repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:291
+msgid "Don't repeat yourself: merging across branches"
+msgstr "不要重复劳动:在分支间合并"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:293
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:301
+msgid ""
+"In the simplest instance, all you need to do is pull changes from your "
+"maintenance branch into your local clone of the target branch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:307
+msgid ""
+"You'll then need to merge the heads of the two branches, and push back to the "
+"main branch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:314
+msgid "Naming branches within one repository"
+msgstr "版本库中的命名分支"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:316
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:323
+msgid ""
+"If you're more in the <quote>power user</quote> category (<emphasis>and</"
+"emphasis> 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 <quote>small picture</quote> and <quote>big "
+"picture</quote> branches.  While Mercurial works with multiple <quote>small "
+"picture</quote> branches in a repository all the time (for example after you "
+"pull changes in, but before you merge them), it can <emphasis>also</emphasis> "
+"work with multiple <quote>big picture</quote> branches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:334
+msgid ""
+"The key to working this way is that Mercurial lets you assign a persistent "
+"<emphasis>name</emphasis> to a branch.  There always exists a branch named "
+"<literal>default</literal>.  Even before you start naming branches yourself, "
+"you can find traces of the <literal>default</literal> branch if you look for "
+"them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:341
+msgid ""
+"As an example, when you run the <command role=\"hg-cmd\">hg commit</command> "
+"command, and it pops up your editor so that you can enter a commit message, "
+"look for a line that contains the text <quote><literal>HG: branch default</"
+"literal></quote> at the bottom. This is telling you that your commit will "
+"occur on the branch named <literal>default</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:348
+msgid ""
+"To start working with named branches, use the <command role=\"hg-cmd\">hg "
+"branches</command> command.  This command lists the named branches already "
+"present in your repository, telling you which changeset is the tip of each."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:355
+msgid ""
+"Since you haven't created any named branches yet, the only one that exists is "
+"<literal>default</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:358
+msgid ""
+"To find out what the <quote>current</quote> branch is, run the <command role="
+"\"hg-cmd\">hg branch</command> command, giving it no arguments.  This tells "
+"you what branch the parent of the current changeset is on."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:365
+msgid ""
+"To create a new branch, run the <command role=\"hg-cmd\">hg branch</command> "
+"command again.  This time, give it one argument: the name of the branch you "
+"want to create."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:371
+msgid ""
+"After you've created a branch, you might wonder what effect the <command role="
+"\"hg-cmd\">hg branch</command> command has had.  What do the <command role="
+"\"hg-cmd\">hg status</command> and <command role=\"hg-cmd\">hg tip</command> "
+"commands report?"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:378
+msgid ""
+"Nothing has changed in the working directory, and there's been no new history "
+"created.  As this suggests, running the <command role=\"hg-cmd\">hg branch</"
+"command> command has no permanent effect; it only tells Mercurial what branch "
+"name to use the <emphasis>next</emphasis> time you commit a changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:385
+msgid ""
+"When you commit a change, Mercurial records the name of the branch on which "
+"you committed.  Once you've switched from the <literal>default</literal> "
+"branch to another and committed, you'll see the name of the new branch show "
+"up in the output of <command role=\"hg-cmd\">hg log</command>, <command role="
+"\"hg-cmd\">hg tip</command>, and other commands that display the same kind of "
+"output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:395
+msgid ""
+"The <command role=\"hg-cmd\">hg log</command>-like commands will print the "
+"branch name of every changeset that's not on the <literal>default</literal> "
+"branch.  As a result, if you never use named branches, you'll never see this "
+"information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:400
+msgid ""
+"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 <command "
+"role=\"hg-cmd\">hg branch</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:408
+msgid ""
+"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.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:414
+msgid "Dealing with multiple named branches in a repository"
+msgstr "在版本库中处理多个命名分支"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:417
+msgid ""
+"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 <command role=\"hg-cmd\">hg update</command> or <command role=\"hg-cmd"
+"\">hg pull -u</command>.  It will update the working directory to the tip of "
+"this branch, no matter what the <quote>repo-wide</quote> tip is.  To update "
+"to a revision that's on a different named branch, you may need to use the "
+"<option role=\"hg-opt-update\">-C</option> option to <command role=\"hg-cmd"
+"\">hg update</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:427
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:433
+msgid ""
+"We're on the <literal>bar</literal> branch, but there also exists an older "
+"<command role=\"hg-cmd\">hg foo</command> branch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:437
+msgid ""
+"We can <command role=\"hg-cmd\">hg update</command> back and forth between "
+"the tips of the <literal>foo</literal> and <literal>bar</literal> branches "
+"without needing to use the <option role=\"hg-opt-update\">-C</option> option, "
+"because this only involves going backwards and forwards linearly through our "
+"change history."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:446
+msgid ""
+"If we go back to the <literal>foo</literal> branch and then run <command role="
+"\"hg-cmd\">hg update</command>, it will keep us on <literal>foo</literal>, "
+"not move us to the tip of <literal>bar</literal>."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:453
+msgid ""
+"Committing a new change on the <literal>foo</literal> branch introduces a new "
+"head."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:460
+msgid "Branch names and merging"
+msgstr "分支名称与合并"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:462
+msgid ""
+"As you've probably noticed, merges in Mercurial are not symmetrical. Let's "
+"say our repository has two heads, 17 and 23.  If I <command role=\"hg-cmd"
+"\">hg update</command> to 17 and then <command role=\"hg-cmd\">hg merge</"
+"command> with 23, Mercurial records 17 as the first parent of the merge, and "
+"23 as the second.  Whereas if I <command role=\"hg-cmd\">hg update</command> "
+"to 23 and then <command role=\"hg-cmd\">hg merge</command> with 17, it "
+"records 23 as the first parent, and 17 as the second."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:472
+msgid ""
+"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 "
+"<literal>foo</literal>, and you merge with <literal>bar</literal>, the branch "
+"name will still be <literal>foo</literal> after you merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:479
+msgid ""
+"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 <literal>foo</literal> "
+"branch, and so are you.  We commit different changes; I pull your changes; I "
+"now have two heads, each claiming to be on the <literal>foo</literal> "
+"branch.  The result of a merge will be a single head on the <literal>foo</"
+"literal> branch, as you might hope."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:487
+msgid ""
+"But if I'm working on the <literal>bar</literal> branch, and I merge work "
+"from the <literal>foo</literal> branch, the result will remain on the "
+"<literal>bar</literal> branch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:493
+msgid ""
+"To give a more concrete example, if I'm working on the <literal>bleeding-"
+"edge</literal> branch, and I want to bring in the latest fixes from the "
+"<literal>stable</literal> branch, Mercurial will choose the <quote>right</"
+"quote> (<literal>bleeding-edge</literal>) branch name when I pull and merge "
+"from <literal>stable</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch07-branch.xml:502
+msgid "Branch naming is generally useful"
+msgstr "分支名称通常都很有用"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:504
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:509
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch07-branch.xml:514
+msgid ""
+"If you're working with shared repositories, you can set up a <literal role="
+"\"hook\">pretxnchangegroup</literal> hook on each that will block incoming "
+"changes that have the <quote>wrong</quote> branch name.  This provides a "
+"simple, but effective, defence against people accidentally pushing changes "
+"from a <quote>bleeding edge</quote> branch to a <quote>stable</quote> "
+"branch.  Such a hook might look like this inside the shared repo's <filename "
+"role=\"special\"> /.hgrc</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch08-undo.xml:5
+msgid "Finding and fixing mistakes"
+msgstr "查找和修改错误"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch08-undo.xml:7
+msgid ""
+"To err might be human, but to really handle the consequences well takes a top-"
+"notch revision control system.  In this chapter, we'll discuss some of the "
+"techniques you can use when you find that a problem has crept into your "
+"project.  Mercurial has some highly capable features that will help you to "
+"isolate the sources of problems, and to handle them appropriately."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:15
+msgid "Erasing local history"
+msgstr "销毁本地历史"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:18
+msgid "The accidental commit"
+msgstr "意外的提交"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:20
+msgid ""
+"I have the occasional but persistent problem of typing rather more quickly "
+"than I can think, which sometimes results in me committing a changeset that "
+"is either incomplete or plain wrong.  In my case, the usual kind of "
+"incomplete changeset is one in which I've created a new source file, but "
+"forgotten to <command role=\"hg-cmd\">hg add</command> it.  A <quote>plain "
+"wrong</quote> changeset is not as common, but no less annoying."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:31
+msgid "Rolling back a transaction"
+msgstr "回滚一个事务"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:33
+msgid ""
+"In <xref linkend=\"sec:concepts:txn\"/>, I mentioned that Mercurial treats "
+"each modification of a repository as a <emphasis>transaction</emphasis>.  "
+"Every time you commit a changeset or pull changes from another repository, "
+"Mercurial remembers what you did.  You can undo, or <emphasis>roll back</"
+"emphasis>, exactly one of these actions using the <command role=\"hg-cmd\">hg "
+"rollback</command> command.  (See <xref linkend=\"sec:undo:rollback-after-push"
+"\"/> for an important caveat about the use of this command.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:43
+msgid ""
+"Here's a mistake that I often find myself making: committing a change in "
+"which I've created a new file, but forgotten to <command role=\"hg-cmd\">hg "
+"add</command> it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:50
+msgid ""
+"Looking at the output of <command role=\"hg-cmd\">hg status</command> after "
+"the commit immediately confirms the error."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:56
+msgid ""
+"The commit captured the changes to the file <filename>a</filename>, but not "
+"the new file <filename>b</filename>.  If I were to push this changeset to a "
+"repository that I shared with a colleague, the chances are high that "
+"something in <filename>a</filename> would refer to <filename>b</filename>, "
+"which would not be present in their repository when they pulled my changes.  "
+"I would thus become the object of some indignation."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:65
+msgid ""
+"However, luck is with me&emdash;I've caught my error before I pushed the "
+"changeset.  I use the <command role=\"hg-cmd\">hg rollback</command> command, "
+"and Mercurial makes that last changeset vanish."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:72
+msgid ""
+"Notice that the changeset is no longer present in the repository's history, "
+"and the working directory once again thinks that the file <filename>a</"
+"filename> is modified.  The commit and rollback have left the working "
+"directory exactly as it was prior to the commit; the changeset has been "
+"completely erased.  I can now safely <command role=\"hg-cmd\">hg add</"
+"command> the file <filename>b</filename>, and rerun my commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:85
+msgid "The erroneous pull"
+msgstr "错误的抓取"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:87
+msgid ""
+"It's common practice with Mercurial to maintain separate development branches "
+"of a project in different repositories.  Your development team might have one "
+"shared repository for your project's <quote>0.9</quote> release, and another, "
+"containing different changes, for the <quote>1.0</quote> release."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:94
+msgid ""
+"Given this, you can imagine that the consequences could be messy if you had a "
+"local <quote>0.9</quote> repository, and accidentally pulled changes from the "
+"shared <quote>1.0</quote> repository into it.  At worst, you could be paying "
+"insufficient attention, and push those changes into the shared <quote>0.9</"
+"quote> tree, confusing your entire team (but don't worry, we'll return to "
+"this horror scenario later).  However, it's more likely that you'll notice "
+"immediately, because Mercurial will display the URL it's pulling from, or you "
+"will see it pull a suspiciously large number of changes into the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:106
+msgid ""
+"The <command role=\"hg-cmd\">hg rollback</command> command will work nicely "
+"to expunge all of the changesets that you just pulled.  Mercurial groups all "
+"changes from one <command role=\"hg-cmd\">hg pull</command> into a single "
+"transaction, so one <command role=\"hg-cmd\">hg rollback</command> is all you "
+"need to undo this mistake."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:115
+msgid "Rolling back is useless once you've pushed"
+msgstr "当完成推送后,回滚是无效的"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:117
+msgid ""
+"The value of the <command role=\"hg-cmd\">hg rollback</command> command drops "
+"to zero once you've pushed your changes to another repository.  Rolling back "
+"a change makes it disappear entirely, but <emphasis>only</emphasis> in the "
+"repository in which you perform the <command role=\"hg-cmd\">hg rollback</"
+"command>.  Because a rollback eliminates history, there's no way for the "
+"disappearance of a change to propagate between repositories."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:126
+msgid ""
+"If you've pushed a change to another repository&emdash;particularly if it's a "
+"shared repository&emdash;it has essentially <quote>escaped into the wild,</"
+"quote> and you'll have to recover from your mistake in a different way.  What "
+"will happen if you push a changeset somewhere, then roll it back, then pull "
+"from the repository you pushed to, is that the changeset will reappear in "
+"your repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:135
+msgid ""
+"(If you absolutely know for sure that the change you want to roll back is the "
+"most recent change in the repository that you pushed to, <emphasis>and</"
+"emphasis> you know that nobody else could have pulled it from that "
+"repository, you can roll back the changeset there, too, but you really should "
+"really not rely on this working reliably.  If you do this, sooner or later a "
+"change really will make it into a repository that you don't directly control "
+"(or have forgotten about), and come back to bite you.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:147
+msgid "You can only roll back once"
+msgstr "你只能回滚一次"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:149
+msgid ""
+"Mercurial stores exactly one transaction in its transaction log; that "
+"transaction is the most recent one that occurred in the repository. This "
+"means that you can only roll back one transaction.  If you expect to be able "
+"to roll back one transaction, then its predecessor, this is not the behaviour "
+"you will get."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:158
+msgid ""
+"Once you've rolled back one transaction in a repository, you can't roll back "
+"again in that repository until you perform another commit or pull."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:165
+msgid "Reverting the mistaken change"
+msgstr "撤销错误的修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:167
+msgid ""
+"If you make a modification to a file, and decide that you really didn't want "
+"to change the file at all, and you haven't yet committed your changes, the "
+"<command role=\"hg-cmd\">hg revert</command> command is the one you'll need.  "
+"It looks at the changeset that's the parent of the working directory, and "
+"restores the contents of the file to their state as of that changeset. "
+"(That's a long-winded way of saying that, in the normal case, it undoes your "
+"modifications.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:176
+msgid ""
+"Let's illustrate how the <command role=\"hg-cmd\">hg revert</command> command "
+"works with yet another small example.  We'll begin by modifying a file that "
+"Mercurial is already tracking."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:183
+msgid ""
+"If we don't want that change, we can simply <command role=\"hg-cmd\">hg "
+"revert</command> the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:189
+msgid ""
+"The <command role=\"hg-cmd\">hg revert</command> command provides us with an "
+"extra degree of safety by saving our modified file with a <filename>.orig</"
+"filename> extension."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:196
+msgid ""
+"Here is a summary of the cases that the <command role=\"hg-cmd\">hg revert</"
+"command> command can deal with.  We will describe each of these in more "
+"detail in the section that follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:201
+msgid "If you modify a file, it will restore the file to its unmodified state."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:204
+msgid ""
+"If you <command role=\"hg-cmd\">hg add</command> a file, it will undo the "
+"<quote>added</quote> state of the file, but leave the file itself untouched."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:208
+msgid ""
+"If you delete a file without telling Mercurial, it will restore the file to "
+"its unmodified contents."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:211
+msgid ""
+"If you use the <command role=\"hg-cmd\">hg remove</command> command to remove "
+"a file, it will undo the <quote>removed</quote> state of the file, and "
+"restore the file to its unmodified contents."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:218
+msgid "File management errors"
+msgstr "文件管理错误"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:220
+msgid ""
+"The <command role=\"hg-cmd\">hg revert</command> command is useful for more "
+"than just modified files.  It lets you reverse the results of all of "
+"Mercurial's file management commands&emdash;<command role=\"hg-cmd\">hg add</"
+"command>, <command role=\"hg-cmd\">hg remove</command>, and so on."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:226
+msgid ""
+"If you <command role=\"hg-cmd\">hg add</command> a file, then decide that in "
+"fact you don't want Mercurial to track it, use <command role=\"hg-cmd\">hg "
+"revert</command> to undo the add.  Don't worry; Mercurial will not modify the "
+"file in any way.  It will just <quote>unmark</quote> the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:234
+msgid ""
+"Similarly, if you ask Mercurial to <command role=\"hg-cmd\">hg remove</"
+"command> a file, you can use <command role=\"hg-cmd\">hg revert</command> to "
+"restore it to the contents it had as of the parent of the working directory.  "
+"&interaction.daily.revert.remove; This works just as well for a file that you "
+"deleted by hand, without telling Mercurial (recall that in Mercurial "
+"terminology, this kind of file is called <quote>missing</quote>)."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:245
+msgid ""
+"If you revert a <command role=\"hg-cmd\">hg copy</command>, the copied-to "
+"file remains in your working directory afterwards, untracked.  Since a copy "
+"doesn't affect the copied-from file in any way, Mercurial doesn't do anything "
+"with the copied-from file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch08-undo.xml:254
+msgid "A slightly special case: reverting a rename"
+msgstr "一个稍微特别的案例:撤销改名"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:256
+msgid ""
+"If you <command role=\"hg-cmd\">hg rename</command> a file, there is one "
+"small detail that you should remember.  When you <command role=\"hg-cmd\">hg "
+"revert</command> a rename, it's not enough to provide the name of the renamed-"
+"to file, as you can see here."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:264
+msgid ""
+"As you can see from the output of <command role=\"hg-cmd\">hg status</"
+"command>, the renamed-to file is no longer identified as added, but the "
+"renamed-<emphasis>from</emphasis> file is still removed! This is counter-"
+"intuitive (at least to me), but at least it's easy to deal with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:273
+msgid ""
+"So remember, to revert a <command role=\"hg-cmd\">hg rename</command>, you "
+"must provide <emphasis>both</emphasis> the source and destination names."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:278
+msgid "% TODO: the output doesn't look like it will be removed!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:281
+msgid ""
+"(By the way, if you rename a file, then modify the renamed-to file, then "
+"revert both components of the rename, when Mercurial restores the file that "
+"was removed as part of the rename, it will be unmodified. If you need the "
+"modifications in the renamed-to file to show up in the renamed-from file, "
+"don't forget to copy them over.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:288
+msgid ""
+"These fiddly aspects of reverting a rename arguably constitute a small bug in "
+"Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:295
+msgid "Dealing with committed changes"
+msgstr "处理已经提交的修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:297
+msgid ""
+"Consider a case where you have committed a change $a$, and another change $b$ "
+"on top of it; you then realise that change $a$ was incorrect.  Mercurial lets "
+"you <quote>back out</quote> an entire changeset automatically, and building "
+"blocks that let you reverse part of a changeset by hand."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:303
+msgid ""
+"Before you read this section, here's something to keep in mind: the <command "
+"role=\"hg-cmd\">hg backout</command> command undoes changes by "
+"<emphasis>adding</emphasis> history, not by modifying or erasing it.  It's "
+"the right tool to use if you're fixing bugs, but not if you're trying to undo "
+"some change that has catastrophic consequences.  To deal with those, see "
+"<xref linkend=\"sec:undo:aaaiiieee\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:312
+msgid "Backing out a changeset"
+msgstr "恢复一个修改集"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:314
+msgid ""
+"The <command role=\"hg-cmd\">hg backout</command> command lets you "
+"<quote>undo</quote> the effects of an entire changeset in an automated "
+"fashion.  Because Mercurial's history is immutable, this command "
+"<emphasis>does not</emphasis> get rid of the changeset you want to undo.  "
+"Instead, it creates a new changeset that <emphasis>reverses</emphasis> the "
+"effect of the to-be-undone changeset."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:323
+msgid ""
+"The operation of the <command role=\"hg-cmd\">hg backout</command> command is "
+"a little intricate, so let's illustrate it with some examples.  First, we'll "
+"create a repository with some simple changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:330
+msgid ""
+"The <command role=\"hg-cmd\">hg backout</command> command takes a single "
+"changeset ID as its argument; this is the changeset to back out.  Normally, "
+"<command role=\"hg-cmd\">hg backout</command> will drop you into a text "
+"editor to write a commit message, so you can record why you're backing the "
+"change out.  In this example, we provide a commit message on the command line "
+"using the <option role=\"hg-opt-backout\">-m</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:341
+msgid "Backing out the tip changeset"
+msgstr "恢复顶点修改集"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:343
+msgid "We're going to start by backing out the last changeset we committed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:348
+msgid ""
+"You can see that the second line from <filename>myfile</filename> is no "
+"longer present.  Taking a look at the output of <command role=\"hg-cmd\">hg "
+"log</command> gives us an idea of what the <command role=\"hg-cmd\">hg "
+"backout</command> command has done.  &interaction.backout.simple.log; Notice "
+"that the new changeset that <command role=\"hg-cmd\">hg backout</command> has "
+"created is a child of the changeset we backed out.  It's easier to see this "
+"in <xref linkend=\"fig:undo:backout\"/>, which presents a graphical view of "
+"the change history.  As you can see, the history is nice and linear."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch08-undo.xml:361 ../en/ch08-undo.xml:473
+msgid ""
+"Backing out a change using the <command role=\"hg-cmd\">hg backout</command> "
+"command"
+msgstr "使用 <command role=\"hg-cmd\">hg backout</command> 恢复一个修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch08-undo.xml:364
+msgid "<imageobject><imagedata fileref=\"figs/undo-simple.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:371
+msgid "Backing out a non-tip change"
+msgstr "恢复非顶点的修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:373
+msgid ""
+"If you want to back out a change other than the last one you committed, pass "
+"the <option role=\"hg-opt-backout\">--merge</option> option to the <command "
+"role=\"hg-cmd\">hg backout</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:380
+msgid ""
+"This makes backing out any changeset a <quote>one-shot</quote> operation "
+"that's usually simple and fast."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:386
+msgid ""
+"If you take a look at the contents of <filename>myfile</filename> after the "
+"backout finishes, you'll see that the first and third changes are present, "
+"but not the second."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:393
+msgid ""
+"As the graphical history in <xref linkend=\"fig:undo:backout-non-tip\"/> "
+"illustrates, Mercurial actually commits <emphasis>two</emphasis> changes in "
+"this kind of situation (the box-shaped nodes are the ones that Mercurial "
+"commits automatically).  Before Mercurial begins the backout process, it "
+"first remembers what the current parent of the working directory is.  It then "
+"backs out the target changeset, and commits that as a changeset.  Finally, it "
+"merges back to the previous parent of the working directory, and commits the "
+"result of the merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:404
+msgid ""
+"% TODO: to me it looks like mercurial doesn't commit the second merge "
+"automatically!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch08-undo.xml:408
+msgid ""
+"Automated backout of a non-tip change using the <command role=\"hg-cmd\">hg "
+"backout</command> command"
+msgstr "使用 <command role=\"hg-cmd\">hg backout</command> 自动恢复非顶点的修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch08-undo.xml:411
+msgid ""
+"<imageobject><imagedata fileref=\"figs/undo-non-tip.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:416
+msgid ""
+"The result is that you end up <quote>back where you were</quote>, only with "
+"some extra history that undoes the effect of the changeset you wanted to back "
+"out."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch08-undo.xml:421
+msgid "Always use the <option role=\"hg-opt-backout\">--merge</option> option"
+msgstr "始终使用选项 <option role=\"hg-opt-backout\">--merge</option>"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch08-undo.xml:424
+msgid ""
+"In fact, since the <option role=\"hg-opt-backout\">--merge</option> option "
+"will do the <quote>right thing</quote> whether or not the changeset you're "
+"backing out is the tip (i.e. it won't try to merge if it's backing out the "
+"tip, since there's no need), you should <emphasis>always</emphasis> use this "
+"option when you run the <command role=\"hg-cmd\">hg backout</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:435
+msgid "Gaining more control of the backout process"
+msgstr "在恢复处理中获得更多控制"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:437
+msgid ""
+"While I've recommended that you always use the <option role=\"hg-opt-backout"
+"\">--merge</option> option when backing out a change, the <command role=\"hg-"
+"cmd\">hg backout</command> command lets you decide how to merge a backout "
+"changeset.  Taking control of the backout process by hand is something you "
+"will rarely need to do, but it can be useful to understand what the <command "
+"role=\"hg-cmd\">hg backout</command> command is doing for you automatically.  "
+"To illustrate this, let's clone our first repository, but omit the backout "
+"change that it contains."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:450
+msgid ""
+"As with our earlier example, We'll commit a third changeset, then back out "
+"its parent, and see what happens."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:456
+msgid ""
+"Our new changeset is again a descendant of the changeset we backout out; it's "
+"thus a new head, <emphasis>not</emphasis> a descendant of the changeset that "
+"was the tip.  The <command role=\"hg-cmd\">hg backout</command> command was "
+"quite explicit in telling us this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:464
+msgid ""
+"Again, it's easier to see what has happened by looking at a graph of the "
+"revision history, in <xref linkend=\"fig:undo:backout-manual\"/>.  This makes "
+"it clear that when we use <command role=\"hg-cmd\">hg backout</command> to "
+"back out a change other than the tip, Mercurial adds a new head to the "
+"repository (the change it committed is box-shaped)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch08-undo.xml:476
+msgid "<imageobject><imagedata fileref=\"figs/undo-manual.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:481
+msgid ""
+"After the <command role=\"hg-cmd\">hg backout</command> command has "
+"completed, it leaves the new <quote>backout</quote> changeset as the parent "
+"of the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:488
+msgid "Now we have two isolated sets of changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:492
+msgid ""
+"Let's think about what we expect to see as the contents of <filename>myfile</"
+"filename> now.  The first change should be present, because we've never "
+"backed it out.  The second change should be missing, as that's the change we "
+"backed out.  Since the history graph shows the third change as a separate "
+"head, we <emphasis>don't</emphasis> expect to see the third change present in "
+"<filename>myfile</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:502
+msgid ""
+"To get the third change back into the file, we just do a normal merge of our "
+"two heads."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:507
+msgid ""
+"Afterwards, the graphical history of our repository looks like <xref linkend="
+"\"fig:undo:backout-manual-merge\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch08-undo.xml:512
+msgid "Manually merging a backout change"
+msgstr "手工合并恢复修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch08-undo.xml:514
+msgid ""
+"<imageobject><imagedata fileref=\"figs/undo-manual-merge.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:521
+msgid "Why <command role=\"hg-cmd\">hg backout</command> works as it does"
+msgstr "<command role=\"hg-cmd\">hg backout</command> 的内幕"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:524
+msgid ""
+"Here's a brief description of how the <command role=\"hg-cmd\">hg backout</"
+"command> command works."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:527
+msgid ""
+"It ensures that the working directory is <quote>clean</quote>, i.e. that the "
+"output of <command role=\"hg-cmd\">hg status</command> would be empty."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:531
+msgid ""
+"It remembers the current parent of the working directory.  Let's call this "
+"changeset <literal>orig</literal>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:535
+msgid ""
+"It does the equivalent of a <command role=\"hg-cmd\">hg update</command> to "
+"sync the working directory to the changeset you want to back out.  Let's call "
+"this changeset <literal>backout</literal>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:540
+msgid ""
+"It finds the parent of that changeset.  Let's call that changeset "
+"<literal>parent</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:543
+msgid ""
+"For each file that the <literal>backout</literal> changeset affected, it does "
+"the equivalent of a <command role=\"hg-cmd\">hg revert -r parent</command> on "
+"that file, to restore it to the contents it had before that changeset was "
+"committed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:550
+msgid ""
+"It commits the result as a new changeset.  This changeset has "
+"<literal>backout</literal> as its parent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:554
+msgid ""
+"If you specify <option role=\"hg-opt-backout\">--merge</option> on the "
+"command line, it merges with <literal>orig</literal>, and commits the result "
+"of the merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:560
+msgid ""
+"An alternative way to implement the <command role=\"hg-cmd\">hg backout</"
+"command> command would be to <command role=\"hg-cmd\">hg export</command> the "
+"to-be-backed-out changeset as a diff, then use the <option role=\"cmd-opt-"
+"patch\">--reverse</option> option to the <command>patch</command> command to "
+"reverse the effect of the change without fiddling with the working "
+"directory.  This sounds much simpler, but it would not work nearly as well."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:570
+msgid ""
+"The reason that <command role=\"hg-cmd\">hg backout</command> does an update, "
+"a commit, a merge, and another commit is to give the merge machinery the best "
+"chance to do a good job when dealing with all the changes <emphasis>between</"
+"emphasis> the change you're backing out and the current tip."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:577
+msgid ""
+"If you're backing out a changeset that's 100 revisions back in your project's "
+"history, the chances that the <command>patch</command> command will be able "
+"to apply a reverse diff cleanly are not good, because intervening changes are "
+"likely to have <quote>broken the context</quote> that <command>patch</"
+"command> uses to determine whether it can apply a patch (if this sounds like "
+"gibberish, see <xref linkend=\"sec:mq:patch\"/> for a discussion of the "
+"<command>patch</command> command).  Also, Mercurial's merge machinery will "
+"handle files and directories being renamed, permission changes, and "
+"modifications to binary files, none of which <command>patch</command> can "
+"deal with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:594
+msgid "Changes that should never have been"
+msgstr "不该发生的修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:596
+msgid ""
+"Most of the time, the <command role=\"hg-cmd\">hg backout</command> command "
+"is exactly what you need if you want to undo the effects of a change.  It "
+"leaves a permanent record of exactly what you did, both when committing the "
+"original changeset and when you cleaned up after it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:602
+msgid ""
+"On rare occasions, though, you may find that you've committed a change that "
+"really should not be present in the repository at all.  For example, it would "
+"be very unusual, and usually considered a mistake, to commit a software "
+"project's object files as well as its source files.  Object files have almost "
+"no intrinsic value, and they're <emphasis>big</emphasis>, so they increase "
+"the size of the repository and the amount of time it takes to clone or pull "
+"changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:611
+msgid ""
+"Before I discuss the options that you have if you commit a <quote>brown paper "
+"bag</quote> change (the kind that's so bad that you want to pull a brown "
+"paper bag over your head), let me first discuss some approaches that probably "
+"won't work."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:616
+msgid ""
+"Since Mercurial treats history as accumulative&emdash;every change builds on "
+"top of all changes that preceded it&emdash;you generally can't just make "
+"disastrous changes disappear.  The one exception is when you've just "
+"committed a change, and it hasn't been pushed or pulled into another "
+"repository.  That's when you can safely use the <command role=\"hg-cmd\">hg "
+"rollback</command> command, as I detailed in <xref linkend=\"sec:undo:rollback"
+"\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:625
+msgid ""
+"After you've pushed a bad change to another repository, you <emphasis>could</"
+"emphasis> still use <command role=\"hg-cmd\">hg rollback</command> to make "
+"your local copy of the change disappear, but it won't have the consequences "
+"you want.  The change will still be present in the remote repository, so it "
+"will reappear in your local repository the next time you pull."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:633
+msgid ""
+"If a situation like this arises, and you know which repositories your bad "
+"change has propagated into, you can <emphasis>try</emphasis> to get rid of "
+"the changeefrom <emphasis>every</emphasis> one of those repositories.  This "
+"is, of course, not a satisfactory solution: if you miss even a single "
+"repository while you're expunging, the change is still <quote>in the wild</"
+"quote>, and could propagate further."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:641
+msgid ""
+"If you've committed one or more changes <emphasis>after</emphasis> the change "
+"that you'd like to see disappear, your options are further reduced. Mercurial "
+"doesn't provide a way to <quote>punch a hole</quote> in history, leaving "
+"changesets intact."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:647
+msgid ""
+"XXX This needs filling out.  The <literal>hg-replay</literal> script in the "
+"<literal>examples</literal> directory works, but doesn't handle merge "
+"changesets.  Kind of an important omission."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:653
+msgid "Protect yourself from <quote>escaped</quote> changes"
+msgstr "使用<quote>校验</quote>修改来保护你自己"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:656
+msgid ""
+"If you've committed some changes to your local repository and they've been "
+"pushed or pulled somewhere else, this isn't necessarily a disaster.  You can "
+"protect yourself ahead of time against some classes of bad changeset.  This "
+"is particularly easy if your team usually pulls changes from a central "
+"repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:663
+msgid ""
+"By configuring some hooks on that repository to validate incoming changesets "
+"(see chapter <xref linkend=\"chap:hook\"/>), you can automatically prevent "
+"some kinds of bad changeset from being pushed to the central repository at "
+"all.  With such a configuration in place, some kinds of bad changeset will "
+"naturally tend to <quote>die out</quote> because they can't propagate into "
+"the central repository.  Better yet, this happens without any need for "
+"explicit intervention."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:673
+msgid ""
+"For instance, an incoming change hook that verifies that a changeset will "
+"actually compile can prevent people from inadvertantly <quote>breaking the "
+"build</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:680
+msgid "Finding the source of a bug"
+msgstr "查找问题的根源"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:682
+msgid ""
+"While it's all very well to be able to back out a changeset that introduced a "
+"bug, this requires that you know which changeset to back out.  Mercurial "
+"provides an invaluable command, called <command role=\"hg-cmd\">hg bisect</"
+"command>, that helps you to automate this process and accomplish it very "
+"efficiently."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:689
+msgid ""
+"The idea behind the <command role=\"hg-cmd\">hg bisect</command> command is "
+"that a changeset has introduced some change of behaviour that you can "
+"identify with a simple binary test.  You don't know which piece of code "
+"introduced the change, but you know how to test for the presence of the bug.  "
+"The <command role=\"hg-cmd\">hg bisect</command> command uses your test to "
+"direct its search for the changeset that introduced the code that caused the "
+"bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:698
+msgid ""
+"Here are a few scenarios to help you understand how you might apply this "
+"command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:701
+msgid ""
+"The most recent version of your software has a bug that you remember wasn't "
+"present a few weeks ago, but you don't know when it was introduced.  Here, "
+"your binary test checks for the presence of that bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:706
+msgid ""
+"You fixed a bug in a rush, and now it's time to close the entry in your "
+"team's bug database.  The bug database requires a changeset ID when you close "
+"an entry, but you don't remember which changeset you fixed the bug in.  Once "
+"again, your binary test checks for the presence of the bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:713
+msgid ""
+"Your software works correctly, but runs 15% slower than the last time you "
+"measured it.  You want to know which changeset introduced the performance "
+"regression.  In this case, your binary test measures the performance of your "
+"software, to see whether it's <quote>fast</quote> or <quote>slow</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:720
+msgid ""
+"The sizes of the components of your project that you ship exploded recently, "
+"and you suspect that something changed in the way you build your project."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:725
+msgid ""
+"From these examples, it should be clear that the <command role=\"hg-cmd\">hg "
+"bisect</command> command is not useful only for finding the sources of bugs.  "
+"You can use it to find any <quote>emergent property</quote> of a repository "
+"(anything that you can't find from a simple text search of the files in the "
+"tree) for which you can write a binary test."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:732
+msgid ""
+"We'll introduce a little bit of terminology here, just to make it clear which "
+"parts of the search process are your responsibility, and which are "
+"Mercurial's.  A <emphasis>test</emphasis> is something that <emphasis>you</"
+"emphasis> run when <command role=\"hg-cmd\">hg bisect</command> chooses a "
+"changeset.  A <emphasis>probe</emphasis> is what <command role=\"hg-cmd\">hg "
+"bisect</command> runs to tell whether a revision is good.  Finally, we'll use "
+"the word <quote>bisect</quote>, as both a noun and a verb, to stand in for "
+"the phrase <quote>search using the <command role=\"hg-cmd\">hg bisect</"
+"command> command</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:745
+msgid ""
+"One simple way to automate the searching process would be simply to probe "
+"every changeset.  However, this scales poorly.  If it took ten minutes to "
+"test a single changeset, and you had 10,000 changesets in your repository, "
+"the exhaustive approach would take on average 35 <emphasis>days</emphasis> to "
+"find the changeset that introduced a bug.  Even if you knew that the bug was "
+"introduced by one of the last 500 changesets, and limited your search to "
+"those, you'd still be looking at over 40 hours to find the changeset that "
+"introduced your bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:755
+msgid ""
+"What the <command role=\"hg-cmd\">hg bisect</command> command does is use its "
+"knowledge of the <quote>shape</quote> of your project's revision history to "
+"perform a search in time proportional to the <emphasis>logarithm</emphasis> "
+"of the number of changesets to check (the kind of search it performs is "
+"called a dichotomic search).  With this approach, searching through 10,000 "
+"changesets will take less than three hours, even at ten minutes per test (the "
+"search will require about 14 tests).  Limit your search to the last hundred "
+"changesets, and it will take only about an hour (roughly seven tests)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:766
+msgid ""
+"The <command role=\"hg-cmd\">hg bisect</command> command is aware of the "
+"<quote>branchy</quote> nature of a Mercurial project's revision history, so "
+"it has no problems dealing with branches, merges, or multiple heads in a "
+"repository.  It can prune entire branches of history with a single probe, "
+"which is how it operates so efficiently."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:774
+msgid "Using the <command role=\"hg-cmd\">hg bisect</command> command"
+msgstr "使用命令 <command role=\"hg-cmd\">hg bisect</command>"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:777
+msgid ""
+"Here's an example of <command role=\"hg-cmd\">hg bisect</command> in action."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch08-undo.xml:781
+msgid ""
+"In versions 0.9.5 and earlier of Mercurial, <command role=\"hg-cmd\">hg "
+"bisect</command> was not a core command: it was distributed with Mercurial as "
+"an extension. This section describes the built-in command, not the old "
+"extension."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:788
+msgid ""
+"Now let's create a repository, so that we can try out the <command role=\"hg-"
+"cmd\">hg bisect</command> command in isolation."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:794
+msgid ""
+"We'll simulate a project that has a bug in it in a simple-minded way: create "
+"trivial changes in a loop, and nominate one specific change that will have "
+"the <quote>bug</quote>.  This loop creates 35 changesets, each adding a "
+"single file to the repository. We'll represent our <quote>bug</quote> with a "
+"file that contains the text <quote>i have a gub</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:804
+msgid ""
+"The next thing that we'd like to do is figure out how to use the <command "
+"role=\"hg-cmd\">hg bisect</command> command.  We can use Mercurial's normal "
+"built-in help mechanism for this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:811
+msgid ""
+"The <command role=\"hg-cmd\">hg bisect</command> command works in steps.  "
+"Each step proceeds as follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:814
+msgid "You run your binary test."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:816
+msgid ""
+"If the test succeeded, you tell <command role=\"hg-cmd\">hg bisect</command> "
+"by running the <command role=\"hg-cmd\">hg bisect good</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:821
+msgid ""
+"If it failed, run the <command role=\"hg-cmd\">hg bisect bad</command> "
+"command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:825
+msgid ""
+"The command uses your information to decide which changeset to test next."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch08-undo.xml:828
+msgid ""
+"It updates the working directory to that changeset, and the process begins "
+"again."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:831
+msgid ""
+"The process ends when <command role=\"hg-cmd\">hg bisect</command> identifies "
+"a unique changeset that marks the point where your test transitioned from "
+"<quote>succeeding</quote> to <quote>failing</quote>."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:836
+msgid ""
+"To start the search, we must run the <command role=\"hg-cmd\">hg bisect --"
+"reset</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:841
+msgid ""
+"In our case, the binary test we use is simple: we check to see if any file in "
+"the repository contains the string <quote>i have a gub</quote>.  If it does, "
+"this changeset contains the change that <quote>caused the bug</quote>.  By "
+"convention, a changeset that has the property we're searching for is "
+"<quote>bad</quote>, while one that doesn't is <quote>good</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:849
+msgid ""
+"Most of the time, the revision to which the working directory is synced "
+"(usually the tip) already exhibits the problem introduced by the buggy "
+"change, so we'll mark it as <quote>bad</quote>."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:856
+msgid ""
+"Our next task is to nominate a changeset that we know <emphasis>doesn't</"
+"emphasis> have the bug; the <command role=\"hg-cmd\">hg bisect</command> "
+"command will <quote>bracket</quote> its search between the first pair of good "
+"and bad changesets.  In our case, we know that revision 10 didn't have the "
+"bug.  (I'll have more words about choosing the first <quote>good</quote> "
+"changeset later.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:866
+msgid "Notice that this command printed some output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:868
+msgid ""
+"It told us how many changesets it must consider before it can identify the "
+"one that introduced the bug, and how many tests that will require."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:872
+msgid ""
+"It updated the working directory to the next changeset to test, and told us "
+"which changeset it's testing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:877
+msgid ""
+"We now run our test in the working directory.  We use the <command>grep</"
+"command> command to see if our <quote>bad</quote> file is present in the "
+"working directory.  If it is, this revision is bad; if not, this revision is "
+"good.  &interaction.bisect.search.step1;"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:883
+msgid ""
+"This test looks like a perfect candidate for automation, so let's turn it "
+"into a shell function."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:887
+msgid ""
+"We can now run an entire test step with a single command, <literal>mytest</"
+"literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:892
+msgid "A few more invocations of our canned test step command, and we're done."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:897
+msgid ""
+"Even though we had 40 changesets to search through, the <command role=\"hg-cmd"
+"\">hg bisect</command> command let us find the changeset that introduced our "
+"<quote>bug</quote> with only five tests.  Because the number of tests that "
+"the <command role=\"hg-cmd\">hg bisect</command> command performs grows "
+"logarithmically with the number of changesets to search, the advantage that "
+"it has over the <quote>brute force</quote> search approach increases with "
+"every changeset you add."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:908
+msgid "Cleaning up after your search"
+msgstr "搜索后的清理"
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:910
+msgid ""
+"When you're finished using the <command role=\"hg-cmd\">hg bisect</command> "
+"command in a repository, you can use the <command role=\"hg-cmd\">hg bisect "
+"reset</command> command to drop the information it was using to drive your "
+"search.  The command doesn't use much space, so it doesn't matter if you "
+"forget to run this command.  However, <command role=\"hg-cmd\">hg bisect</"
+"command> won't let you start a new search in that repository until you do a "
+"<command role=\"hg-cmd\">hg bisect reset</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch08-undo.xml:925
+msgid "Tips for finding bugs effectively"
+msgstr "有效查找问题的技巧"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:928
+msgid "Give consistent input"
+msgstr "给出一致的输入"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:930
+msgid ""
+"The <command role=\"hg-cmd\">hg bisect</command> command requires that you "
+"correctly report the result of every test you perform.  If you tell it that a "
+"test failed when it really succeeded, it <emphasis>might</emphasis> be able "
+"to detect the inconsistency.  If it can identify an inconsistency in your "
+"reports, it will tell you that a particular changeset is both good and bad. "
+"However, it can't do this perfectly; it's about as likely to report the wrong "
+"changeset as the source of the bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:942
+msgid "Automate as much as possible"
+msgstr "尽量自动"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:944
+msgid ""
+"When I started using the <command role=\"hg-cmd\">hg bisect</command> "
+"command, I tried a few times to run my tests by hand, on the command line.  "
+"This is an approach that I, at least, am not suited to.  After a few tries, I "
+"found that I was making enough mistakes that I was having to restart my "
+"searches several times before finally getting correct results."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:952
+msgid ""
+"My initial problems with driving the <command role=\"hg-cmd\">hg bisect</"
+"command> command by hand occurred even with simple searches on small "
+"repositories; if the problem you're looking for is more subtle, or the number "
+"of tests that <command role=\"hg-cmd\">hg bisect</command> must perform "
+"increases, the likelihood of operator error ruining the search is much "
+"higher.  Once I started automating my tests, I had much better results."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:961
+msgid "The key to automated testing is twofold:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:963
+msgid "always test for the same symptom, and"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:965
+msgid ""
+"always feed consistent input to the <command role=\"hg-cmd\">hg bisect</"
+"command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:968
+msgid ""
+"In my tutorial example above, the <command>grep</command> command tests for "
+"the symptom, and the <literal>if</literal> statement takes the result of this "
+"check and ensures that we always feed the same input to the <command role="
+"\"hg-cmd\">hg bisect</command> command.  The <literal>mytest</literal> "
+"function marries these together in a reproducible way, so that every test is "
+"uniform and consistent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:978
+msgid "Check your results"
+msgstr "检查你的结果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:980
+msgid ""
+"Because the output of a <command role=\"hg-cmd\">hg bisect</command> search "
+"is only as good as the input you give it, don't take the changeset it reports "
+"as the absolute truth.  A simple way to cross-check its report is to manually "
+"run your test at each of the following changesets:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:986
+msgid ""
+"The changeset that it reports as the first bad revision.  Your test should "
+"still report this as bad."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:990
+msgid ""
+"The parent of that changeset (either parent, if it's a merge). Your test "
+"should report this changeset as good."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:994
+msgid ""
+"A child of that changeset.  Your test should report this changeset as bad."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:1000
+msgid "Beware interference between bugs"
+msgstr "谨防问题之间的冲突"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1002
+msgid ""
+"It's possible that your search for one bug could be disrupted by the presence "
+"of another.  For example, let's say your software crashes at revision 100, "
+"and worked correctly at revision 50.  Unknown to you, someone else introduced "
+"a different crashing bug at revision 60, and fixed it at revision 80.  This "
+"could distort your results in one of several ways."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1010
+msgid ""
+"It is possible that this other bug completely <quote>masks</quote> yours, "
+"which is to say that it occurs before your bug has a chance to manifest "
+"itself.  If you can't avoid that other bug (for example, it prevents your "
+"project from building), and so can't tell whether your bug is present in a "
+"particular changeset, the <command role=\"hg-cmd\">hg bisect</command> "
+"command cannot help you directly.  Instead, you can mark a changeset as "
+"untested by running <command role=\"hg-cmd\">hg bisect --skip</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1020
+msgid ""
+"A different problem could arise if your test for a bug's presence is not "
+"specific enough.  If you check for <quote>my program crashes</quote>, then "
+"both your crashing bug and an unrelated crashing bug that masks it will look "
+"like the same thing, and mislead <command role=\"hg-cmd\">hg bisect</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1027
+msgid ""
+"Another useful situation in which to use <command role=\"hg-cmd\">hg bisect --"
+"skip</command> is if you can't test a revision because your project was in a "
+"broken and hence untestable state at that revision, perhaps because someone "
+"checked in a change that prevented the project from building."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:1036
+msgid "Bracket your search lazily"
+msgstr "减少你的查找工作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1038
+msgid ""
+"Choosing the first <quote>good</quote> and <quote>bad</quote> changesets that "
+"will mark the end points of your search is often easy, but it bears a little "
+"discussion nevertheless.  From the perspective of <command role=\"hg-cmd\">hg "
+"bisect</command>, the <quote>newest</quote> changeset is conventionally "
+"<quote>bad</quote>, and the older changeset is <quote>good</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1046
+msgid ""
+"If you're having trouble remembering when a suitable <quote>good</quote> "
+"change was, so that you can tell <command role=\"hg-cmd\">hg bisect</"
+"command>, you could do worse than testing changesets at random.  Just "
+"remember to eliminate contenders that can't possibly exhibit the bug (perhaps "
+"because the feature with the bug isn't present yet) and those where another "
+"problem masks the bug (as I discussed above)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1055
+msgid ""
+"Even if you end up <quote>early</quote> by thousands of changesets or months "
+"of history, you will only add a handful of tests to the total number that "
+"<command role=\"hg-cmd\">hg bisect</command> must perform, thanks to its "
+"logarithmic behaviour."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch09-hook.xml:5
+msgid "Handling repository events with hooks"
+msgstr "使用钩子处理版本库事件"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch09-hook.xml:7
+msgid ""
+"Mercurial offers a powerful mechanism to let you perform automated actions in "
+"response to events that occur in a repository.  In some cases, you can even "
+"control Mercurial's response to those events."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch09-hook.xml:12
+msgid ""
+"The name Mercurial uses for one of these actions is a <emphasis>hook</"
+"emphasis>. Hooks are called <quote>triggers</quote> in some revision control "
+"systems, but the two names refer to the same idea."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:18
+msgid "An overview of hooks in Mercurial"
+msgstr "Mercurial 钩子概述"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:20
+msgid ""
+"Here is a brief list of the hooks that Mercurial supports. We will revisit "
+"each of these hooks in more detail later, in <xref linkend=\"sec:hook:ref\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:25
+msgid ""
+"<literal role=\"hook\">changegroup</literal>: This is run after a group of "
+"changesets has been brought into the repository from elsewhere."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:29
+msgid ""
+"<literal role=\"hook\">commit</literal>: This is run after a new changeset "
+"has been created in the local repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:33
+msgid ""
+"<literal role=\"hook\">incoming</literal>: This is run once for each new "
+"changeset that is brought into the repository from elsewhere.  Notice the "
+"difference from <literal role=\"hook\">changegroup</literal>, which is run "
+"once per <emphasis>group</emphasis> of changesets brought in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:40
+msgid ""
+"<literal role=\"hook\">outgoing</literal>: This is run after a group of "
+"changesets has been transmitted from this repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:44
+msgid ""
+"<literal role=\"hook\">prechangegroup</literal>: This is run before starting "
+"to bring a group of changesets into the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:49
+msgid ""
+"<literal role=\"hook\">precommit</literal>: Controlling. This is run before "
+"starting a commit."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:53
+msgid ""
+"<literal role=\"hook\">preoutgoing</literal>: Controlling. This is run before "
+"starting to transmit a group of changesets from this repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:58
+msgid ""
+"<literal role=\"hook\">pretag</literal>: Controlling. This is run before "
+"creating a tag."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:62
+msgid ""
+"<literal role=\"hook\">pretxnchangegroup</literal>: Controlling. This is run "
+"after a group of changesets has been brought into the local repository from "
+"another, but before the transaction completes that will make the changes "
+"permanent in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:70
+msgid ""
+"<literal role=\"hook\">pretxncommit</literal>: Controlling. This is run after "
+"a new changeset has been created in the local repository, but before the "
+"transaction completes that will make it permanent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:76
+msgid ""
+"<literal role=\"hook\">preupdate</literal>: Controlling. This is run before "
+"starting an update or merge of the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:81
+msgid ""
+"<literal role=\"hook\">tag</literal>: This is run after a tag is created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:85
+msgid ""
+"<literal role=\"hook\">update</literal>: This is run after an update or merge "
+"of the working directory has finished."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:90
+msgid ""
+"Each of the hooks whose description begins with the word <quote>Controlling</"
+"quote> has the ability to determine whether an activity can proceed.  If the "
+"hook succeeds, the activity may proceed; if it fails, the activity is either "
+"not permitted or undone, depending on the hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:99
+msgid "Hooks and security"
+msgstr "钩子与安全性"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:102
+msgid "Hooks are run with your privileges"
+msgstr "钩子以你的特权执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:104
+msgid ""
+"When you run a Mercurial command in a repository, and the command causes a "
+"hook to run, that hook runs on <emphasis>your</emphasis> system, under "
+"<emphasis>your</emphasis> user account, with <emphasis>your</emphasis> "
+"privilege level.  Since hooks are arbitrary pieces of executable code, you "
+"should treat them with an appropriate level of suspicion.  Do not install a "
+"hook unless you are confident that you know who created it and what it does."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:115
+msgid ""
+"In some cases, you may be exposed to hooks that you did not install "
+"yourself.  If you work with Mercurial on an unfamiliar system, Mercurial will "
+"run hooks defined in that system's global <filename role=\"special\">~/.hgrc</"
+"filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:122
+msgid ""
+"If you are working with a repository owned by another user, Mercurial can run "
+"hooks defined in that user's repository, but it will still run them as "
+"<quote>you</quote>.  For example, if you <command role=\"hg-cmd\">hg pull</"
+"command> from that repository, and its <filename role=\"special\">.hg/hgrc</"
+"filename> defines a local <literal role=\"hook\">outgoing</literal> hook, "
+"that hook will run under your user account, even though you don't own that "
+"repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch09-hook.xml:134
+msgid ""
+"This only applies if you are pulling from a repository on a local or network "
+"filesystem.  If you're pulling over http or ssh, any <literal role=\"hook"
+"\">outgoing</literal> hook will run under whatever account is executing the "
+"server process, on the server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:142
+msgid ""
+"XXX To see what hooks are defined in a repository, use the <command role=\"hg-"
+"cmd\">hg config hooks</command> command.  If you are working in one "
+"repository, but talking to another that you do not own (e.g. using <command "
+"role=\"hg-cmd\">hg pull</command> or <command role=\"hg-cmd\">hg incoming</"
+"command>), remember that it is the other repository's hooks you should be "
+"checking, not your own."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:153
+msgid "Hooks do not propagate"
+msgstr "钩子不会传播"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:155
+msgid ""
+"In Mercurial, hooks are not revision controlled, and do not propagate when "
+"you clone, or pull from, a repository.  The reason for this is simple: a hook "
+"is a completely arbitrary piece of executable code.  It runs under your user "
+"identity, with your privilege level, on your machine."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:162
+msgid ""
+"It would be extremely reckless for any distributed revision control system to "
+"implement revision-controlled hooks, as this would offer an easily "
+"exploitable way to subvert the accounts of users of the revision control "
+"system."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:168
+msgid ""
+"Since Mercurial does not propagate hooks, if you are collaborating with other "
+"people on a common project, you should not assume that they are using the "
+"same Mercurial hooks as you are, or that theirs are correctly configured.  "
+"You should document the hooks you expect people to use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:175
+msgid ""
+"In a corporate intranet, this is somewhat easier to control, as you can for "
+"example provide a <quote>standard</quote> installation of Mercurial on an NFS "
+"filesystem, and use a site-wide <filename role=\"special\">~/.hgrc</filename> "
+"file to define hooks that all users will see.  However, this too has its "
+"limits; see below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:184
+msgid "Hooks can be overridden"
+msgstr "钩子可以被覆盖"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:186
+msgid ""
+"Mercurial allows you to override a hook definition by redefining the hook.  "
+"You can disable it by setting its value to the empty string, or change its "
+"behaviour as you wish."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:191
+msgid ""
+"If you deploy a system- or site-wide <filename role=\"special\">~/.hgrc</"
+"filename> file that defines some hooks, you should thus understand that your "
+"users can disable or override those hooks."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:199
+msgid "Ensuring that critical hooks are run"
+msgstr "确保关键钩子的执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:201
+msgid ""
+"Sometimes you may want to enforce a policy that you do not want others to be "
+"able to work around.  For example, you may have a requirement that every "
+"changeset must pass a rigorous set of tests.  Defining this requirement via a "
+"hook in a site-wide <filename role=\"special\">~/.hgrc</filename> won't work "
+"for remote users on laptops, and of course local users can subvert it at will "
+"by overriding the hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:210
+msgid ""
+"Instead, you can set up your policies for use of Mercurial so that people are "
+"expected to propagate changes through a well-known <quote>canonical</quote> "
+"server that you have locked down and configured appropriately."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:216
+msgid ""
+"One way to do this is via a combination of social engineering and "
+"technology.  Set up a restricted-access account; users can push changes over "
+"the network to repositories managed by this account, but they cannot log into "
+"the account and run normal shell commands.  In this scenario, a user can "
+"commit a changeset that contains any old garbage they want."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:225
+msgid ""
+"When someone pushes a changeset to the server that everyone pulls from, the "
+"server will test the changeset before it accepts it as permanent, and reject "
+"it if it fails to pass the test suite.  If people only pull changes from this "
+"filtering server, it will serve to ensure that all changes that people pull "
+"have been automatically vetted."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:236
+msgid "Care with <literal>pretxn</literal> hooks in a shared-access repository"
+msgstr "在共享版本库中注意 <literal>pretxn</literal> 钩子"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:239
+msgid ""
+"If you want to use hooks to do some automated work in a repository that a "
+"number of people have shared access to, you need to be careful in how you do "
+"this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:244
+msgid ""
+"Mercurial only locks a repository when it is writing to the repository, and "
+"only the parts of Mercurial that write to the repository pay attention to "
+"locks.  Write locks are necessary to prevent multiple simultaneous writers "
+"from scribbling on each other's work, corrupting the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:251
+msgid ""
+"Because Mercurial is careful with the order in which it reads and writes "
+"data, it does not need to acquire a lock when it wants to read data from the "
+"repository.  The parts of Mercurial that read from the repository never pay "
+"attention to locks.  This lockless reading scheme greatly increases "
+"performance and concurrency."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:259
+msgid ""
+"With great performance comes a trade-off, though, one which has the potential "
+"to cause you trouble unless you're aware of it.  To describe this requires a "
+"little detail about how Mercurial adds changesets to a repository and reads "
+"those changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:266
+msgid ""
+"When Mercurial <emphasis>writes</emphasis> metadata, it writes it straight "
+"into the destination file.  It writes file data first, then manifest data "
+"(which contains pointers to the new file data), then changelog data (which "
+"contains pointers to the new manifest data).  Before the first write to each "
+"file, it stores a record of where the end of the file was in its transaction "
+"log.  If the transaction must be rolled back, Mercurial simply truncates each "
+"file back to the size it was before the transaction began."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:277
+msgid ""
+"When Mercurial <emphasis>reads</emphasis> metadata, it reads the changelog "
+"first, then everything else.  Since a reader will only access parts of the "
+"manifest or file metadata that it can see in the changelog, it can never see "
+"partially written data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:283
+msgid ""
+"Some controlling hooks (<literal role=\"hook\">pretxncommit</literal> and "
+"<literal role=\"hook\">pretxnchangegroup</literal>) run when a transaction is "
+"almost complete. All of the metadata has been written, but Mercurial can "
+"still roll the transaction back and cause the newly-written data to disappear."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:291
+msgid ""
+"If one of these hooks runs for long, it opens a window of time during which a "
+"reader can see the metadata for changesets that are not yet permanent, and "
+"should not be thought of as <quote>really there</quote>.  The longer the hook "
+"runs, the longer that window is open."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:299
+msgid "The problem illustrated"
+msgstr "问题的演示"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:301
+msgid ""
+"In principle, a good use for the <literal role=\"hook\">pretxnchangegroup</"
+"literal> hook would be to automatically build and test incoming changes "
+"before they are accepted into a central repository.  This could let you "
+"guarantee that nobody can push changes to this repository that <quote>break "
+"the build</quote>. But if a client can pull changes while they're being "
+"tested, the usefulness of the test is zero; an unsuspecting someone can pull "
+"untested changes, potentially breaking their build."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:312
+msgid ""
+"The safest technological answer to this challenge is to set up such a "
+"<quote>gatekeeper</quote> repository as <emphasis>unidirectional</emphasis>.  "
+"Let it take changes pushed in from the outside, but do not allow anyone to "
+"pull changes from it (use the <literal role=\"hook\">preoutgoing</literal> "
+"hook to lock it down).  Configure a <literal role=\"hook\">changegroup</"
+"literal> hook so that if a build or test succeeds, the hook will push the new "
+"changes out to another repository that people <emphasis>can</emphasis> pull "
+"from."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:324
+msgid ""
+"In practice, putting a centralised bottleneck like this in place is not often "
+"a good idea, and transaction visibility has nothing to do with the problem.  "
+"As the size of a project&emdash;and the time it takes to build and "
+"test&emdash;grows, you rapidly run into a wall with this <quote>try before "
+"you buy</quote> approach, where you have more changesets to test than time in "
+"which to deal with them.  The inevitable result is frustration on the part of "
+"all involved."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:335
+msgid ""
+"An approach that scales better is to get people to build and test before they "
+"push, then run automated builds and tests centrally <emphasis>after</"
+"emphasis> a push, to be sure all is well.  The advantage of this approach is "
+"that it does not impose a limit on the rate at which the repository can "
+"accept changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:346
+msgid "A short tutorial on using hooks"
+msgstr "使用钩子的简短指南"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:348
+msgid ""
+"It is easy to write a Mercurial hook.  Let's start with a hook that runs when "
+"you finish a <command role=\"hg-cmd\">hg commit</command>, and simply prints "
+"the hash of the changeset you just created.  The hook is called <literal role="
+"\"hook\">commit</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:355
+msgid "All hooks follow the pattern in this example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:359
+msgid ""
+"You add an entry to the <literal role=\"rc-hooks\">hooks</literal> section of "
+"your <filename role=\"special\">~/.hgrc</filename>.  On the left is the name "
+"of the event to trigger on; on the right is the action to take.  As you can "
+"see, you can run an arbitrary shell command in a hook.  Mercurial passes "
+"extra information to the hook using environment variables (look for "
+"<envar>HG_NODE</envar> in the example)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:369
+msgid "Performing multiple actions per event"
+msgstr "每个事件执行多个操作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:371
+msgid ""
+"Quite often, you will want to define more than one hook for a particular kind "
+"of event, as shown below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:376
+msgid ""
+"Mercurial lets you do this by adding an <emphasis>extension</emphasis> to the "
+"end of a hook's name.  You extend a hook's name by giving the name of the "
+"hook, followed by a full stop (the <quote><literal>.</literal></quote> "
+"character), followed by some more text of your choosing.  For example, "
+"Mercurial will run both <literal>commit.foo</literal> and <literal>commit."
+"bar</literal> when the <literal>commit</literal> event occurs."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:387
+msgid ""
+"To give a well-defined order of execution when there are multiple hooks "
+"defined for an event, Mercurial sorts hooks by extension, and executes the "
+"hook commands in this sorted order.  In the above example, it will execute "
+"<literal>commit.bar</literal> before <literal>commit.foo</literal>, and "
+"<literal>commit</literal> before both."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:396
+msgid ""
+"It is a good idea to use a somewhat descriptive extension when you define a "
+"new hook.  This will help you to remember what the hook was for.  If the hook "
+"fails, you'll get an error message that contains the hook name and extension, "
+"so using a descriptive extension could give you an immediate hint as to why "
+"the hook failed (see <xref linkend=\"sec:hook:perm\"/> for an example)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:407
+msgid "Controlling whether an activity can proceed"
+msgstr "控制处理的活动"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:409
+msgid ""
+"In our earlier examples, we used the <literal role=\"hook\">commit</literal> "
+"hook, which is run after a commit has completed.  This is one of several "
+"Mercurial hooks that run after an activity finishes.  Such hooks have no way "
+"of influencing the activity itself."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:416
+msgid ""
+"Mercurial defines a number of events that occur before an activity starts; or "
+"after it starts, but before it finishes.  Hooks that trigger on these events "
+"have the added ability to choose whether the activity can continue, or will "
+"abort."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:422
+msgid ""
+"The <literal role=\"hook\">pretxncommit</literal> hook runs after a commit "
+"has all but completed.  In other words, the metadata representing the "
+"changeset has been written out to disk, but the transaction has not yet been "
+"allowed to complete.  The <literal role=\"hook\">pretxncommit</literal> hook "
+"has the ability to decide whether the transaction can complete, or must be "
+"rolled back."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:431
+msgid ""
+"If the <literal role=\"hook\">pretxncommit</literal> hook exits with a status "
+"code of zero, the transaction is allowed to complete; the commit finishes; "
+"and the <literal role=\"hook\">commit</literal> hook is run.  If the <literal "
+"role=\"hook\">pretxncommit</literal> hook exits with a non-zero status code, "
+"the transaction is rolled back; the metadata representing the changeset is "
+"erased; and the <literal role=\"hook\">commit</literal> hook is not run."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:443
+msgid ""
+"The hook in the example above checks that a commit comment contains a bug "
+"ID.  If it does, the commit can complete.  If not, the commit is rolled back."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:451
+msgid "Writing your own hooks"
+msgstr "编写钩子"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:453
+msgid ""
+"When you are writing a hook, you might find it useful to run Mercurial either "
+"with the <option role=\"hg-opt-global\">-v</option> option, or the <envar "
+"role=\"rc-item-ui\">verbose</envar> config item set to <quote>true</quote>.  "
+"When you do so, Mercurial will print a message before it calls each hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:462
+msgid "Choosing how your hook should run"
+msgstr "选择钩子的执行方式"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:464
+msgid ""
+"You can write a hook either as a normal program&emdash;typically a shell "
+"script&emdash;or as a Python function that is executed within the Mercurial "
+"process."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:469
+msgid ""
+"Writing a hook as an external program has the advantage that it requires no "
+"knowledge of Mercurial's internals.  You can call normal Mercurial commands "
+"to get any added information you need.  The trade-off is that external hooks "
+"are slower than in-process hooks."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:476
+msgid ""
+"An in-process Python hook has complete access to the Mercurial API, and does "
+"not <quote>shell out</quote> to another process, so it is inherently faster "
+"than an external hook.  It is also easier to obtain much of the information "
+"that a hook requires by using the Mercurial API than by running Mercurial "
+"commands."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:484
+msgid ""
+"If you are comfortable with Python, or require high performance, writing your "
+"hooks in Python may be a good choice.  However, when you have a "
+"straightforward hook to write and you don't need to care about performance "
+"(probably the majority of hooks), a shell script is perfectly fine."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:493
+msgid "Hook parameters"
+msgstr "钩子的参数"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:495
+msgid ""
+"Mercurial calls each hook with a set of well-defined parameters.  In Python, "
+"a parameter is passed as a keyword argument to your hook function.  For an "
+"external program, a parameter is passed as an environment variable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:501
+msgid ""
+"Whether your hook is written in Python or as a shell script, the hook-"
+"specific parameter names and values will be the same.  A boolean parameter "
+"will be represented as a boolean value in Python, but as the number 1 (for "
+"<quote>true</quote>) or 0 (for <quote>false</quote>) as an environment "
+"variable for an external hook.  If a hook parameter is named <literal>foo</"
+"literal>, the keyword argument for a Python hook will also be named "
+"<literal>foo</literal>, while the environment variable for an external hook "
+"will be named <literal>HG_FOO</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:515
+msgid "Hook return values and activity control"
+msgstr "钩子的返回值与活动控制"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:517
+msgid ""
+"A hook that executes successfully must exit with a status of zero if "
+"external, or return boolean <quote>false</quote> if in-process.  Failure is "
+"indicated with a non-zero exit status from an external hook, or an in-process "
+"hook returning boolean <quote>true</quote>.  If an in-process hook raises an "
+"exception, the hook is considered to have failed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:525
+msgid ""
+"For a hook that controls whether an activity can proceed, zero/false means "
+"<quote>allow</quote>, while non-zero/true/exception means <quote>deny</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:532
+msgid "Writing an external hook"
+msgstr "编写外部钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:534
+msgid ""
+"When you define an external hook in your <filename role=\"special\">~/.hgrc</"
+"filename> and the hook is run, its value is passed to your shell, which "
+"interprets it.  This means that you can use normal shell constructs in the "
+"body of the hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:541
+msgid ""
+"An executable hook is always run with its current directory set to a "
+"repository's root directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:545
+msgid ""
+"Each hook parameter is passed in as an environment variable; the name is "
+"upper-cased, and prefixed with the string <quote><literal>HG_</literal></"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:550
+msgid ""
+"With the exception of hook parameters, Mercurial does not set or modify any "
+"environment variables when running a hook.  This is useful to remember if you "
+"are writing a site-wide hook that may be run by a number of different users "
+"with differing environment variables set. In multi-user situations, you "
+"should not rely on environment variables being set to the values you have in "
+"your environment when testing the hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:561
+msgid "Telling Mercurial to use an in-process hook"
+msgstr "让 Mercurial 使用进程内钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:563
+msgid ""
+"The <filename role=\"special\">~/.hgrc</filename> syntax for defining an in-"
+"process hook is slightly different than for an executable hook.  The value of "
+"the hook must start with the text <quote><literal>python:</literal></quote>, "
+"and continue with the fully-qualified name of a callable object to use as the "
+"hook's value."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:571
+msgid ""
+"The module in which a hook lives is automatically imported when a hook is "
+"run.  So long as you have the module name and <envar>PYTHONPATH</envar> "
+"right, it should <quote>just work</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:577
+msgid ""
+"The following <filename role=\"special\">~/.hgrc</filename> example snippet "
+"illustrates the syntax and meaning of the notions we just described."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:583
+msgid ""
+"When Mercurial runs the <literal>commit.example</literal> hook, it imports "
+"<literal>mymodule.submodule</literal>, looks for the callable object named "
+"<literal>myhook</literal>, and calls it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:591
+msgid "Writing an in-process hook"
+msgstr "编写进程内钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:593
+msgid ""
+"The simplest in-process hook does nothing, but illustrates the basic shape of "
+"the hook API:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:598
+msgid ""
+"The first argument to a Python hook is always a <literal role=\"py-mod-"
+"mercurial.ui\">ui</literal> object.  The second is a repository object; at "
+"the moment, it is always an instance of <literal role=\"py-mod-mercurial."
+"localrepo\">localrepository</literal>.  Following these two arguments are "
+"other keyword arguments.  Which ones are passed in depends on the hook being "
+"called, but a hook can ignore arguments it doesn't care about by dropping "
+"them into a keyword argument dict, as with <literal>**kwargs</literal> above."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:613
+msgid "Some hook examples"
+msgstr "钩子样例"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:616
+msgid "Writing meaningful commit messages"
+msgstr "编写有意义的提交日志"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:618
+msgid ""
+"It's hard to imagine a useful commit message being very short. The simple "
+"<literal role=\"hook\">pretxncommit</literal> hook of the example below will "
+"prevent you from committing a changeset with a message that is less than ten "
+"bytes long."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:628
+msgid "Checking for trailing whitespace"
+msgstr "检查行尾空格"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:630
+msgid ""
+"An interesting use of a commit-related hook is to help you to write cleaner "
+"code.  A simple example of <quote>cleaner code</quote> is the dictum that a "
+"change should not add any new lines of text that contain <quote>trailing "
+"whitespace</quote>.  Trailing whitespace is a series of space and tab "
+"characters at the end of a line of text.  In most cases, trailing whitespace "
+"is unnecessary, invisible noise, but it is occasionally problematic, and "
+"people often prefer to get rid of it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:641
+msgid ""
+"You can use either the <literal role=\"hook\">precommit</literal> or <literal "
+"role=\"hook\">pretxncommit</literal> hook to tell whether you have a trailing "
+"whitespace problem.  If you use the <literal role=\"hook\">precommit</"
+"literal> hook, the hook will not know which files you are committing, so it "
+"will have to check every modified file in the repository for trailing white "
+"space.  If you want to commit a change to just the file <filename>foo</"
+"filename>, but the file <filename>bar</filename> contains trailing "
+"whitespace, doing a check in the <literal role=\"hook\">precommit</literal> "
+"hook will prevent you from committing <filename>foo</filename> due to the "
+"problem with <filename>bar</filename>.  This doesn't seem right."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:657
+msgid ""
+"Should you choose the <literal role=\"hook\">pretxncommit</literal> hook, the "
+"check won't occur until just before the transaction for the commit "
+"completes.  This will allow you to check for problems only the exact files "
+"that are being committed.  However, if you entered the commit message "
+"interactively and the hook fails, the transaction will roll back; you'll have "
+"to re-enter the commit message after you fix the trailing whitespace and run "
+"<command role=\"hg-cmd\">hg commit</command> again."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:670
+msgid ""
+"In this example, we introduce a simple <literal role=\"hook\">pretxncommit</"
+"literal> hook that checks for trailing whitespace.  This hook is short, but "
+"not very helpful.  It exits with an error status if a change adds a line with "
+"trailing whitespace to any file, but does not print any information that "
+"might help us to identify the offending file or line.  It also has the nice "
+"property of not paying attention to unmodified lines; only lines that "
+"introduce new trailing whitespace cause problems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:681
+msgid ""
+"The above version is much more complex, but also more useful.  It parses a "
+"unified diff to see if any lines add trailing whitespace, and prints the name "
+"of the file and the line number of each such occurrence.  Even better, if the "
+"change adds trailing whitespace, this hook saves the commit comment and "
+"prints the name of the save file before exiting and telling Mercurial to roll "
+"the transaction back, so you can use the <option role=\"hg-opt-commit\">-l "
+"filename</option> option to <command role=\"hg-cmd\">hg commit</command> to "
+"reuse the saved commit message once you've corrected the problem."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:695
+msgid ""
+"As a final aside, note in the example above the use of <command>perl</"
+"command>'s in-place editing feature to get rid of trailing whitespace from a "
+"file.  This is concise and useful enough that I will reproduce it here."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:705
+msgid "Bundled hooks"
+msgstr "内置的钩子"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch09-hook.xml:707
+msgid ""
+"Mercurial ships with several bundled hooks.  You can find them in the "
+"<filename class=\"directory\">hgext</filename> directory of a Mercurial "
+"source tree.  If you are using a Mercurial binary package, the hooks will be "
+"located in the <filename class=\"directory\">hgext</filename> directory of "
+"wherever your package installer put Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:716
+msgid ""
+"<literal role=\"hg-ext\">acl</literal>&emdash;access control for parts of a "
+"repository"
+msgstr "<literal role=\"hg-ext\">acl</literal>—版本库的访问控制"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:719
+msgid ""
+"The <literal role=\"hg-ext\">acl</literal> extension lets you control which "
+"remote users are allowed to push changesets to a networked server.  You can "
+"protect any portion of a repository (including the entire repo), so that a "
+"specific remote user can push changes that do not affect the protected "
+"portion."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:727
+msgid ""
+"This extension implements access control based on the identity of the user "
+"performing a push, <emphasis>not</emphasis> on who committed the changesets "
+"they're pushing.  It makes sense to use this hook only if you have a locked-"
+"down server environment that authenticates remote users, and you want to be "
+"sure that only specific users are allowed to push changes to that server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:737
+msgid "Configuring the <literal role=\"hook\">acl</literal> hook"
+msgstr "配置 <literal role=\"hook\">acl</literal> 钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:740
+msgid ""
+"In order to manage incoming changesets, the <literal role=\"hg-ext\">acl</"
+"literal> hook must be used as a <literal role=\"hook\">pretxnchangegroup</"
+"literal> hook.  This lets it see which files are modified by each incoming "
+"changeset, and roll back a group of changesets if they modify "
+"<quote>forbidden</quote> files.  Example:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:750
+msgid ""
+"The <literal role=\"hg-ext\">acl</literal> extension is configured using "
+"three sections."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:754
+msgid ""
+"The <literal role=\"rc-acl\">acl</literal> section has only one entry, <envar "
+"role=\"rc-item-acl\">sources</envar>, which lists the sources of incoming "
+"changesets that the hook should pay attention to.  You don't normally need to "
+"configure this section."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:761
+msgid ""
+"<envar role=\"rc-item-acl\">serve</envar>: Control incoming changesets that "
+"are arriving from a remote repository over http or ssh.  This is the default "
+"value of <envar role=\"rc-item-acl\">sources</envar>, and usually the only "
+"setting you'll need for this configuration item."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:769
+msgid ""
+"<envar role=\"rc-item-acl\">pull</envar>: Control incoming changesets that "
+"are arriving via a pull from a local repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:774
+msgid ""
+"<envar role=\"rc-item-acl\">push</envar>: Control incoming changesets that "
+"are arriving via a push from a local repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:779
+msgid ""
+"<envar role=\"rc-item-acl\">bundle</envar>: Control incoming changesets that "
+"are arriving from another repository via a bundle."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:785
+msgid ""
+"The <literal role=\"rc-acl.allow\">acl.allow</literal> section controls the "
+"users that are allowed to add changesets to the repository.  If this section "
+"is not present, all users that are not explicitly denied are allowed.  If "
+"this section is present, all users that are not explicitly allowed are denied "
+"(so an empty section means that all users are denied)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:794
+msgid ""
+"The <literal role=\"rc-acl.deny\">acl.deny</literal> section determines which "
+"users are denied from adding changesets to the repository.  If this section "
+"is not present or is empty, no users are denied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:800
+msgid ""
+"The syntaxes for the <literal role=\"rc-acl.allow\">acl.allow</literal> and "
+"<literal role=\"rc-acl.deny\">acl.deny</literal> sections are identical.  On "
+"the left of each entry is a glob pattern that matches files or directories, "
+"relative to the root of the repository; on the right, a user name."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:808
+msgid ""
+"In the following example, the user <literal>docwriter</literal> can only push "
+"changes to the <filename class=\"directory\">docs</filename> subtree of the "
+"repository, while <literal>intern</literal> can push changes to any file or "
+"directory except <filename class=\"directory\">source/sensitive</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:822 ../en/ch09-hook.xml:1089 ../en/ch09-hook.xml:1279
+msgid "Testing and troubleshooting"
+msgstr "测试与问题处理"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:824
+msgid ""
+"If you want to test the <literal role=\"hg-ext\">acl</literal> hook, run it "
+"with Mercurial's debugging output enabled.  Since you'll probably be running "
+"it on a server where it's not convenient (or sometimes possible) to pass in "
+"the <option role=\"hg-opt-global\">--debug</option> option, don't forget that "
+"you can enable debugging output in your <filename role=\"special\">~/.hgrc</"
+"filename>:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:835
+msgid ""
+"With this enabled, the <literal role=\"hg-ext\">acl</literal> hook will print "
+"enough information to let you figure out why it is allowing or forbidding "
+"pushes from specific users."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:844
+msgid ""
+"<literal role=\"hg-ext\">bugzilla</literal>&emdash;integration with Bugzilla"
+msgstr "<literal role=\"hg-ext\">bugzilla</literal>—与 Bugzilla 的集成"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:848
+msgid ""
+"The <literal role=\"hg-ext\">bugzilla</literal> extension adds a comment to a "
+"Bugzilla bug whenever it finds a reference to that bug ID in a commit "
+"comment.  You can install this hook on a shared server, so that any time a "
+"remote user pushes changes to this server, the hook gets run."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:855
+msgid ""
+"It adds a comment to the bug that looks like this (you can configure the "
+"contents of the comment&emdash;see below):"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:864
+msgid ""
+"The value of this hook is that it automates the process of updating a bug any "
+"time a changeset refers to it.  If you configure the hook properly, it makes "
+"it easy for people to browse straight from a Bugzilla bug to a changeset that "
+"refers to that bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:871
+msgid ""
+"You can use the code in this hook as a starting point for some more exotic "
+"Bugzilla integration recipes.  Here are a few possibilities:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:876
+msgid ""
+"Require that every changeset pushed to the server have a valid bug ID in its "
+"commit comment.  In this case, you'd want to configure the hook as a <literal "
+"role=\"hook\">pretxncommit</literal> hook.  This would allow the hook to "
+"reject changes that didn't contain bug IDs."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:884
+msgid ""
+"Allow incoming changesets to automatically modify the <emphasis>state</"
+"emphasis> of a bug, as well as simply adding a comment.  For example, the "
+"hook could recognise the string <quote>fixed bug 31337</quote> as indicating "
+"that it should update the state of bug 31337 to <quote>requires testing</"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:894
+msgid "Configuring the <literal role=\"hook\">bugzilla</literal> hook"
+msgstr "配置 <literal role=\"hook\">bugzilla</literal> 钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:897
+msgid ""
+"You should configure this hook in your server's <filename role=\"special\">~/."
+"hgrc</filename> as an <literal role=\"hook\">incoming</literal> hook, for "
+"example as follows:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:905
+msgid ""
+"Because of the specialised nature of this hook, and because Bugzilla was not "
+"written with this kind of integration in mind, configuring this hook is a "
+"somewhat involved process."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:911
+msgid ""
+"Before you begin, you must install the MySQL bindings for Python on the host"
+"(s) where you'll be running the hook.  If this is not available as a binary "
+"package for your system, you can download it from <citation>web:mysql-python</"
+"citation>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:918
+msgid ""
+"Configuration information for this hook lives in the <literal role=\"rc-"
+"bugzilla\">bugzilla</literal> section of your <filename role=\"special\">~/."
+"hgrc</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:923
+msgid ""
+"<envar role=\"rc-item-bugzilla\">version</envar>: The version of Bugzilla "
+"installed on the server.  The database schema that Bugzilla uses changes "
+"occasionally, so this hook has to know exactly which schema to use. At the "
+"moment, the only version supported is <literal>2.16</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:932
+msgid ""
+"<envar role=\"rc-item-bugzilla\">host</envar>: The hostname of the MySQL "
+"server that stores your Bugzilla data.  The database must be configured to "
+"allow connections from whatever host you are running the <literal role=\"hook"
+"\">bugzilla</literal> hook on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:939
+msgid ""
+"<envar role=\"rc-item-bugzilla\">user</envar>: The username with which to "
+"connect to the MySQL server.  The database must be configured to allow this "
+"user to connect from whatever host you are running the <literal role=\"hook"
+"\">bugzilla</literal> hook on.  This user must be able to access and modify "
+"Bugzilla tables.  The default value of this item is <literal>bugs</literal>, "
+"which is the standard name of the Bugzilla user in a MySQL database."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:950
+msgid ""
+"<envar role=\"rc-item-bugzilla\">password</envar>: The MySQL password for the "
+"user you configured above.  This is stored as plain text, so you should make "
+"sure that unauthorised users cannot read the <filename role=\"special\">~/."
+"hgrc</filename> file where you store this information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:959
+msgid ""
+"<envar role=\"rc-item-bugzilla\">db</envar>: The name of the Bugzilla "
+"database on the MySQL server.  The default value of this item is "
+"<literal>bugs</literal>, which is the standard name of the MySQL database "
+"where Bugzilla stores its data."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:966
+msgid ""
+"<envar role=\"rc-item-bugzilla\">notify</envar>: If you want Bugzilla to send "
+"out a notification email to subscribers after this hook has added a comment "
+"to a bug, you will need this hook to run a command whenever it updates the "
+"database.  The command to run depends on where you have installed Bugzilla, "
+"but it will typically look something like this, if you have Bugzilla "
+"installed in <filename class=\"directory\">/var/www/html/bugzilla</filename>:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:979
+msgid ""
+"The Bugzilla <literal>processmail</literal> program expects to be given a bug "
+"ID (the hook replaces <quote><literal>%s</literal></quote> with the bug ID)  "
+"and an email address.  It also expects to be able to write to some files in "
+"the directory that it runs in.  If Bugzilla and this hook are not installed "
+"on the same machine, you will need to find a way to run <literal>processmail</"
+"literal> on the server where Bugzilla is installed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:994
+msgid "Mapping committer names to Bugzilla user names"
+msgstr "提交者的名称与 Bugzilla 用户名称的映射"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:996
+msgid ""
+"By default, the <literal role=\"hg-ext\">bugzilla</literal> hook tries to use "
+"the email address of a changeset's committer as the Bugzilla user name with "
+"which to update a bug.  If this does not suit your needs, you can map "
+"committer email addresses to Bugzilla user names using a <literal role=\"rc-"
+"usermap\">usermap</literal> section."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1005
+msgid ""
+"Each item in the <literal role=\"rc-usermap\">usermap</literal> section "
+"contains an email address on the left, and a Bugzilla user name on the right."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1012
+msgid ""
+"You can either keep the <literal role=\"rc-usermap\">usermap</literal> data "
+"in a normal <filename role=\"special\">~/.hgrc</filename>, or tell the "
+"<literal role=\"hg-ext\">bugzilla</literal> hook to read the information from "
+"an external <filename>usermap</filename> file.  In the latter case, you can "
+"store <filename>usermap</filename> data by itself in (for example)  a user-"
+"modifiable repository.  This makes it possible to let your users maintain "
+"their own <envar role=\"rc-item-bugzilla\">usermap</envar> entries.  The main "
+"<filename role=\"special\">~/.hgrc</filename> file might look like this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1028
+msgid ""
+"While the <filename>usermap</filename> file that it refers to might look like "
+"this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:1036
+msgid "Configuring the text that gets added to a bug"
+msgstr "配置增加到问题中的正文"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1038
+msgid ""
+"You can configure the text that this hook adds as a comment; you specify it "
+"in the form of a Mercurial template.  Several <filename role=\"special\">~/."
+"hgrc</filename> entries (still in the <literal role=\"rc-bugzilla\">bugzilla</"
+"literal> section) control this behaviour."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1045
+msgid ""
+"<literal>strip</literal>: The number of leading path elements to strip from a "
+"repository's path name to construct a partial path for a URL. For example, if "
+"the repositories on your server live under <filename class=\"directory\">/"
+"home/hg/repos</filename>, and you have a repository whose path is <filename "
+"class=\"directory\">/home/hg/repos/app/tests</filename>, then setting "
+"<literal>strip</literal> to <literal>4</literal> will give a partial path of "
+"<filename class=\"directory\">app/tests</filename>.  The hook will make this "
+"partial path available when expanding a template, as <literal>webroot</"
+"literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1059
+msgid ""
+"<literal>template</literal>: The text of the template to use.  In addition to "
+"the usual changeset-related variables, this template can use <literal>hgweb</"
+"literal> (the value of the <literal>hgweb</literal> configuration item above) "
+"and <literal>webroot</literal> (the path constructed using <literal>strip</"
+"literal> above)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1069
+msgid ""
+"In addition, you can add a <envar role=\"rc-item-web\">baseurl</envar> item "
+"to the <literal role=\"rc-web\">web</literal> section of your <filename role="
+"\"special\">~/.hgrc</filename>.  The <literal role=\"hg-ext\">bugzilla</"
+"literal> hook will make this available when expanding a template, as the base "
+"string to use when constructing a URL that will let users browse from a "
+"Bugzilla comment to view a changeset.  Example:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1081
+msgid ""
+"Here is an example set of <literal role=\"hg-ext\">bugzilla</literal> hook "
+"config information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1091
+msgid ""
+"The most common problems with configuring the <literal role=\"hg-ext"
+"\">bugzilla</literal> hook relate to running Bugzilla's "
+"<filename>processmail</filename> script and mapping committer names to user "
+"names."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1097
+msgid ""
+"Recall from <xref linkend=\"sec:hook:bugzilla:config\"/> above that the user "
+"that runs the Mercurial process on the server is also the one that will run "
+"the <filename>processmail</filename> script.  The <filename>processmail</"
+"filename> script sometimes causes Bugzilla to write to files in its "
+"configuration directory, and Bugzilla's configuration files are usually owned "
+"by the user that your web server runs under."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1108
+msgid ""
+"You can cause <filename>processmail</filename> to be run with the suitable "
+"user's identity using the <command>sudo</command> command.  Here is an "
+"example entry for a <filename>sudoers</filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1115
+msgid ""
+"This allows the <literal>hg_user</literal> user to run a "
+"<filename>processmail-wrapper</filename> program under the identity of "
+"<literal>httpd_user</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1120
+msgid ""
+"This indirection through a wrapper script is necessary, because "
+"<filename>processmail</filename> expects to be run with its current directory "
+"set to wherever you installed Bugzilla; you can't specify that kind of "
+"constraint in a <filename>sudoers</filename> file.  The contents of the "
+"wrapper script are simple:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1129
+msgid ""
+"It doesn't seem to matter what email address you pass to "
+"<filename>processmail</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1133
+msgid ""
+"If your <literal role=\"rc-usermap\">usermap</literal> is not set up "
+"correctly, users will see an error message from the <literal role=\"hg-ext"
+"\">bugzilla</literal> hook when they push changes to the server.  The error "
+"message will look like this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1140
+msgid ""
+"What this means is that the committer's address, <literal>john.q."
+"public@example.com</literal>, is not a valid Bugzilla user name, nor does it "
+"have an entry in your <literal role=\"rc-usermap\">usermap</literal> that "
+"maps it to a valid Bugzilla user name."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1150
+msgid ""
+"<literal role=\"hg-ext\">notify</literal>&emdash;send email notifications"
+msgstr "<literal role=\"hg-ext\">notify</literal>—邮件通知"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1153
+msgid ""
+"Although Mercurial's built-in web server provides RSS feeds of changes in "
+"every repository, many people prefer to receive change notifications via "
+"email.  The <literal role=\"hg-ext\">notify</literal> hook lets you send out "
+"notifications to a set of email addresses whenever changesets arrive that "
+"those subscribers are interested in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1161
+msgid ""
+"As with the <literal role=\"hg-ext\">bugzilla</literal> hook, the <literal "
+"role=\"hg-ext\">notify</literal> hook is template-driven, so you can "
+"customise the contents of the notification messages that it sends."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1167
+msgid ""
+"By default, the <literal role=\"hg-ext\">notify</literal> hook includes a "
+"diff of every changeset that it sends out; you can limit the size of the "
+"diff, or turn this feature off entirely.  It is useful for letting "
+"subscribers review changes immediately, rather than clicking to follow a URL."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:1175
+msgid "Configuring the <literal role=\"hg-ext\">notify</literal> hook"
+msgstr "配置 <literal role=\"hg-ext\">notify</literal> 钩子"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1178
+msgid ""
+"You can set up the <literal role=\"hg-ext\">notify</literal> hook to send one "
+"email message per incoming changeset, or one per incoming group of changesets "
+"(all those that arrived in a single pull or push)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1190
+msgid ""
+"Configuration information for this hook lives in the <literal role=\"rc-notify"
+"\">notify</literal> section of a <filename role=\"special\">~/.hgrc</"
+"filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1195
+msgid ""
+"<envar role=\"rc-item-notify\">test</envar>: By default, this hook does not "
+"send out email at all; instead, it prints the message that it "
+"<emphasis>would</emphasis> send.  Set this item to <literal>false</literal> "
+"to allow email to be sent. The reason that sending of email is turned off by "
+"default is that it takes several tries to configure this extension exactly as "
+"you would like, and it would be bad form to spam subscribers with a number of "
+"<quote>broken</quote> notifications while you debug your configuration."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1207
+msgid ""
+"<envar role=\"rc-item-notify\">config</envar>: The path to a configuration "
+"file that contains subscription information.  This is kept separate from the "
+"main <filename role=\"special\">~/.hgrc</filename> so that you can maintain "
+"it in a repository of its own.  People can then clone that repository, update "
+"their subscriptions, and push the changes back to your server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1216
+msgid ""
+"<envar role=\"rc-item-notify\">strip</envar>: The number of leading path "
+"separator characters to strip from a repository's path, when deciding whether "
+"a repository has subscribers.  For example, if the repositories on your "
+"server live in <filename class=\"directory\">/home/hg/repos</filename>, and "
+"<literal role=\"hg-ext\">notify</literal> is considering a repository named "
+"<filename class=\"directory\">/home/hg/repos/shared/test</filename>, setting "
+"<envar role=\"rc-item-notify\">strip</envar> to <literal>4</literal> will "
+"cause <literal role=\"hg-ext\">notify</literal> to trim the path it considers "
+"down to <filename class=\"directory\">shared/test</filename>, and it will "
+"match subscribers against that."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1233
+msgid ""
+"<envar role=\"rc-item-notify\">template</envar>: The template text to use "
+"when sending messages.  This specifies both the contents of the message "
+"header and its body."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1239
+msgid ""
+"<envar role=\"rc-item-notify\">maxdiff</envar>: The maximum number of lines "
+"of diff data to append to the end of a message.  If a diff is longer than "
+"this, it is truncated.  By default, this is set to 300.  Set this to "
+"<literal>0</literal> to omit diffs from notification emails."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1248
+msgid ""
+"<envar role=\"rc-item-notify\">sources</envar>: A list of sources of "
+"changesets to consider.  This lets you limit <literal role=\"hg-ext\">notify</"
+"literal> to only sending out email about changes that remote users pushed "
+"into this repository via a server, for example.  See <xref linkend=\"sec:hook:"
+"sources\"/> for the sources you can specify here."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1259
+msgid ""
+"If you set the <envar role=\"rc-item-web\">baseurl</envar> item in the "
+"<literal role=\"rc-web\">web</literal> section, you can use it in a template; "
+"it will be available as <literal>webroot</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1265
+msgid ""
+"Here is an example set of <literal role=\"hg-ext\">notify</literal> "
+"configuration information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1271
+msgid "This will produce a message that looks like the following:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1281
+msgid ""
+"Do not forget that by default, the <literal role=\"hg-ext\">notify</literal> "
+"extension <emphasis>will not send any mail</emphasis> until you explicitly "
+"configure it to do so, by setting <envar role=\"rc-item-notify\">test</envar> "
+"to <literal>false</literal>.  Until you do that, it simply prints the message "
+"it <emphasis>would</emphasis> send."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:1293
+msgid "Information for writers of hooks"
+msgstr "编写钩子的信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1296
+msgid "In-process hook execution"
+msgstr "进程内钩子的执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1298
+msgid "An in-process hook is called with arguments of the following form:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1302
+msgid ""
+"The <literal>ui</literal> parameter is a <literal role=\"py-mod-mercurial.ui"
+"\">ui</literal> object. The <literal>repo</literal> parameter is a <literal "
+"role=\"py-mod-mercurial.localrepo\">localrepository</literal> object.  The "
+"names and values of the <literal>**kwargs</literal> parameters depend on the "
+"hook being invoked, with the following common features:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1311
+msgid ""
+"If a parameter is named <literal>node</literal> or <literal>parentN</"
+"literal>, it will contain a hexadecimal changeset ID. The empty string is "
+"used to represent <quote>null changeset ID</quote> instead of a string of "
+"zeroes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1318
+msgid ""
+"If a parameter is named <literal>url</literal>, it will contain the URL of a "
+"remote repository, if that can be determined."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1323
+msgid ""
+"Boolean-valued parameters are represented as Python <literal>bool</literal> "
+"objects."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1328
+msgid ""
+"An in-process hook is called without a change to the process's working "
+"directory (unlike external hooks, which are run in the root of the "
+"repository).  It must not change the process's working directory, or it will "
+"cause any calls it makes into the Mercurial API to fail."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1335
+msgid ""
+"If a hook returns a boolean <quote>false</quote> value, it is considered to "
+"have succeeded.  If it returns a boolean <quote>true</quote> value or raises "
+"an exception, it is considered to have failed.  A useful way to think of the "
+"calling convention is <quote>tell me if you fail</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1342
+msgid ""
+"Note that changeset IDs are passed into Python hooks as hexadecimal strings, "
+"not the binary hashes that Mercurial's APIs normally use.  To convert a hash "
+"from hex to binary, use the <literal>bin</literal> function."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1350
+msgid "External hook execution"
+msgstr "外部钩子的执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1352
+msgid ""
+"An external hook is passed to the shell of the user running Mercurial. "
+"Features of that shell, such as variable substitution and command "
+"redirection, are available.  The hook is run in the root directory of the "
+"repository (unlike in-process hooks, which are run in the same directory that "
+"Mercurial was run in)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1360
+msgid ""
+"Hook parameters are passed to the hook as environment variables.  Each "
+"environment variable's name is converted in upper case and prefixed with the "
+"string <quote><literal>HG_</literal></quote>.  For example, if the name of a "
+"parameter is <quote><literal>node</literal></quote>, the name of the "
+"environment variable representing that parameter will be "
+"<quote><literal>HG_NODE</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1369
+msgid ""
+"A boolean parameter is represented as the string <quote><literal>1</literal></"
+"quote> for <quote>true</quote>, <quote><literal>0</literal></quote> for "
+"<quote>false</quote>.  If an environment variable is named <envar>HG_NODE</"
+"envar>, <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it contains a "
+"changeset ID represented as a hexadecimal string.  The empty string is used "
+"to represent <quote>null changeset ID</quote> instead of a string of zeroes.  "
+"If an environment variable is named <envar>HG_URL</envar>, it will contain "
+"the URL of a remote repository, if that can be determined."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1381
+msgid ""
+"If a hook exits with a status of zero, it is considered to have succeeded.  "
+"If it exits with a non-zero status, it is considered to have failed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1388
+msgid "Finding out where changesets come from"
+msgstr "检查修改集来自何处"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1390
+msgid ""
+"A hook that involves the transfer of changesets between a local repository "
+"and another may be able to find out information about the <quote>far side</"
+"quote>.  Mercurial knows <emphasis>how</emphasis> changes are being "
+"transferred, and in many cases <emphasis>where</emphasis> they are being "
+"transferred to or from."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:1399
+msgid "Sources of changesets"
+msgstr "修改集的来源"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1401
+msgid ""
+"Mercurial will tell a hook what means are, or were, used to transfer "
+"changesets between repositories.  This is provided by Mercurial in a Python "
+"parameter named <literal>source</literal>, or an environment variable named "
+"<envar>HG_SOURCE</envar>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1409
+msgid ""
+"<literal>serve</literal>: Changesets are transferred to or from a remote "
+"repository over http or ssh."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1414
+msgid ""
+"<literal>pull</literal>: Changesets are being transferred via a pull from one "
+"repository into another."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1419
+msgid ""
+"<literal>push</literal>: Changesets are being transferred via a push from one "
+"repository into another."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1424
+msgid ""
+"<literal>bundle</literal>: Changesets are being transferred to or from a "
+"bundle."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><title>
+#: ../en/ch09-hook.xml:1431
+msgid "Where changes are going&emdash;remote repository URLs"
+msgstr "修改集要到哪里—远程版本库的地址"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1434
+msgid ""
+"When possible, Mercurial will tell a hook the location of the <quote>far "
+"side</quote> of an activity that transfers changeset data between "
+"repositories.  This is provided by Mercurial in a Python parameter named "
+"<literal>url</literal>, or an environment variable named <envar>HG_URL</"
+"envar>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1442
+msgid ""
+"This information is not always known.  If a hook is invoked in a repository "
+"that is being served via http or ssh, Mercurial cannot tell where the remote "
+"repository is, but it may know where the client is connecting from.  In such "
+"cases, the URL will take one of the following forms:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1449
+msgid ""
+"<literal>remote:ssh:1.2.3.4</literal>&emdash;remote ssh client, at the IP "
+"address <literal>1.2.3.4</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1454
+msgid ""
+"<literal>remote:http:1.2.3.4</literal>&emdash;remote http client, at the IP "
+"address <literal>1.2.3.4</literal>.  If the client is using SSL, this will be "
+"of the form <literal>remote:https:1.2.3.4</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1461
+msgid "Empty&emdash;no information could be discovered about the remote client."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:1470
+msgid "Hook reference"
+msgstr "钩子参考"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1473
+msgid ""
+"<literal role=\"hook\">changegroup</literal>&emdash;after remote changesets "
+"added"
+msgstr "<literal role=\"hook\">changegroup</literal>—增加远程修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1476
+msgid ""
+"This hook is run after a group of pre-existing changesets has been added to "
+"the repository, for example via a <command role=\"hg-cmd\">hg pull</command> "
+"or <command role=\"hg-cmd\">hg unbundle</command>.  This hook is run once per "
+"operation that added one or more changesets.  This is in contrast to the "
+"<literal role=\"hook\">incoming</literal> hook, which is run once per "
+"changeset, regardless of whether the changesets arrive in a group."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1486
+msgid ""
+"Some possible uses for this hook include kicking off an automated build or "
+"test of the added changesets, updating a bug database, or notifying "
+"subscribers that a repository contains new changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1492 ../en/ch09-hook.xml:1532 ../en/ch09-hook.xml:1576
+#: ../en/ch09-hook.xml:1618 ../en/ch09-hook.xml:1673 ../en/ch09-hook.xml:1713
+#: ../en/ch09-hook.xml:1749 ../en/ch09-hook.xml:1783 ../en/ch09-hook.xml:1846
+#: ../en/ch09-hook.xml:1904 ../en/ch09-hook.xml:1940 ../en/ch09-hook.xml:1967
+msgid "Parameters to this hook:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1495 ../en/ch09-hook.xml:1849
+msgid ""
+"<literal>node</literal>: A changeset ID.  The changeset ID of the first "
+"changeset in the group that was added.  All changesets between this and "
+"<literal role=\"tag\">tip</literal>, inclusive, were added by a single "
+"<command role=\"hg-cmd\">hg pull</command>, <command role=\"hg-cmd\">hg push</"
+"command> or <command role=\"hg-cmd\">hg unbundle</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1504 ../en/ch09-hook.xml:1583 ../en/ch09-hook.xml:1676
+#: ../en/ch09-hook.xml:1859
+msgid ""
+"<literal>source</literal>: A string.  The source of these changes.  See <xref "
+"linkend=\"sec:hook:sources\"/> for details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1509 ../en/ch09-hook.xml:1588 ../en/ch09-hook.xml:1639
+#: ../en/ch09-hook.xml:1681 ../en/ch09-hook.xml:1762 ../en/ch09-hook.xml:1864
+msgid ""
+"<literal>url</literal>: A URL.  The location of the remote repository, if "
+"known.  See <xref linkend=\"sec:hook:url\"/> for more information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1515
+msgid ""
+"See also: <literal role=\"hook\">incoming</literal> (<xref linkend=\"sec:hook:"
+"incoming\"/>), <literal role=\"hook\">prechangegroup</literal> (<xref linkend="
+"\"sec:hook:prechangegroup\"/>), <literal role=\"hook\">pretxnchangegroup</"
+"literal> (<xref linkend=\"sec:hook:pretxnchangegroup\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1526
+msgid ""
+"<literal role=\"hook\">commit</literal>&emdash;after a new changeset is "
+"created"
+msgstr "<literal role=\"hook\">commit</literal>—创建新修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1529
+msgid "This hook is run after a new changeset has been created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1535 ../en/ch09-hook.xml:1907
+msgid ""
+"<literal>node</literal>: A changeset ID.  The changeset ID of the newly "
+"committed changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1539 ../en/ch09-hook.xml:1911
+msgid ""
+"<literal>parent1</literal>: A changeset ID.  The changeset ID of the first "
+"parent of the newly committed changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1544 ../en/ch09-hook.xml:1916
+msgid ""
+"<literal>parent2</literal>: A changeset ID.  The changeset ID of the second "
+"parent of the newly committed changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1550
+msgid ""
+"See also: <literal role=\"hook\">precommit</literal> (<xref linkend=\"sec:"
+"hook:precommit\"/>), <literal role=\"hook\">pretxncommit</literal> (<xref "
+"linkend=\"sec:hook:pretxncommit\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1559
+msgid ""
+"<literal role=\"hook\">incoming</literal>&emdash;after one remote changeset "
+"is added"
+msgstr "<literal role=\"hook\">incoming</literal>—增加远程修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1562
+msgid ""
+"This hook is run after a pre-existing changeset has been added to the "
+"repository, for example via a <command role=\"hg-cmd\">hg push</command>.  If "
+"a group of changesets was added in a single operation, this hook is called "
+"once for each added changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1569
+msgid ""
+"You can use this hook for the same purposes as the <literal role=\"hook"
+"\">changegroup</literal> hook (<xref linkend=\"sec:hook:changegroup\"/>); "
+"it's simply more convenient sometimes to run a hook once per group of "
+"changesets, while other times it's handier once per changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1579
+msgid ""
+"<literal>node</literal>: A changeset ID.  The ID of the newly added changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1594
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (<xref linkend=\"sec:"
+"hook:changegroup\"/>) <literal role=\"hook\">prechangegroup</literal> (<xref "
+"linkend=\"sec:hook:prechangegroup\"/>), <literal role=\"hook"
+"\">pretxnchangegroup</literal> (<xref linkend=\"sec:hook:pretxnchangegroup\"/"
+">)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1605
+msgid ""
+"<literal role=\"hook\">outgoing</literal>&emdash;after changesets are "
+"propagated"
+msgstr "<literal role=\"hook\">outgoing</literal>—传播修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1608
+msgid ""
+"This hook is run after a group of changesets has been propagated out of this "
+"repository, for example by a <command role=\"hg-cmd\">hg push</command> or "
+"<command role=\"hg-cmd\">hg bundle</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1614
+msgid ""
+"One possible use for this hook is to notify administrators that changes have "
+"been pulled."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1621
+msgid ""
+"<literal>node</literal>: A changeset ID.  The changeset ID of the first "
+"changeset of the group that was sent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1626
+msgid ""
+"<literal>source</literal>: A string.  The source of the of the operation (see "
+"<xref linkend=\"sec:hook:sources\"/>).  If a remote client pulled changes "
+"from this repository, <literal>source</literal> will be <literal>serve</"
+"literal>.  If the client that obtained changes from this repository was "
+"local, <literal>source</literal> will be <literal>bundle</literal>, "
+"<literal>pull</literal>, or <literal>push</literal>, depending on the "
+"operation the client performed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1645
+msgid ""
+"See also: <literal role=\"hook\">preoutgoing</literal> (<xref linkend=\"sec:"
+"hook:preoutgoing\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1652
+msgid ""
+"<literal role=\"hook\">prechangegroup</literal>&emdash;before starting to add "
+"remote changesets"
+msgstr "<literal role=\"hook\">prechangegroup</literal>—增加远程修改集之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1656
+msgid ""
+"This controlling hook is run before Mercurial begins to add a group of "
+"changesets from another repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1660
+msgid ""
+"This hook does not have any information about the changesets to be added, "
+"because it is run before transmission of those changesets is allowed to "
+"begin.  If this hook fails, the changesets will not be transmitted."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1666
+msgid ""
+"One use for this hook is to prevent external changes from being added to a "
+"repository.  For example, you could use this to <quote>freeze</quote> a "
+"server-hosted branch temporarily or permanently so that users cannot push to "
+"it, while still allowing a local administrator to modify the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1687
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (<xref linkend=\"sec:"
+"hook:changegroup\"/>), <literal role=\"hook\">incoming</literal> (<xref "
+"linkend=\"sec:hook:incoming\"/>), <literal role=\"hook\">pretxnchangegroup</"
+"literal> (<xref linkend=\"sec:hook:pretxnchangegroup\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1698
+msgid ""
+"<literal role=\"hook\">precommit</literal>&emdash;before starting to commit a "
+"changeset"
+msgstr "<literal role=\"hook\">precommit</literal>—提交修改集之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1701
+msgid ""
+"This hook is run before Mercurial begins to commit a new changeset. It is run "
+"before Mercurial has any of the metadata for the commit, such as the files to "
+"be committed, the commit message, or the commit date."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1707
+msgid ""
+"One use for this hook is to disable the ability to commit new changesets, "
+"while still allowing incoming changesets.  Another is to run a build or test, "
+"and only allow the commit to begin if the build or test succeeds."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1716
+msgid ""
+"<literal>parent1</literal>: A changeset ID.  The changeset ID of the first "
+"parent of the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1721
+msgid ""
+"<literal>parent2</literal>: A changeset ID.  The changeset ID of the second "
+"parent of the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1726
+msgid ""
+"If the commit proceeds, the parents of the working directory will become the "
+"parents of the new changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1730
+msgid ""
+"See also: <literal role=\"hook\">commit</literal> (<xref linkend=\"sec:hook:"
+"commit\"/>), <literal role=\"hook\">pretxncommit</literal> (<xref linkend="
+"\"sec:hook:pretxncommit\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1738
+msgid ""
+"<literal role=\"hook\">preoutgoing</literal>&emdash;before starting to "
+"propagate changesets"
+msgstr "<literal role=\"hook\">preoutgoing</literal>—传播修改集之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1741
+msgid ""
+"This hook is invoked before Mercurial knows the identities of the changesets "
+"to be transmitted."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1745
+msgid ""
+"One use for this hook is to prevent changes from being transmitted to another "
+"repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1752
+msgid ""
+"<literal>source</literal>: A string.  The source of the operation that is "
+"attempting to obtain changes from this repository (see <xref linkend=\"sec:"
+"hook:sources\"/>).  See the documentation for the <literal>source</literal> "
+"parameter to the <literal role=\"hook\">outgoing</literal> hook, in <xref "
+"linkend=\"sec:hook:outgoing\"/>, for possible values of this parameter."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1768
+msgid ""
+"See also: <literal role=\"hook\">outgoing</literal> (<xref linkend=\"sec:hook:"
+"outgoing\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1775
+msgid ""
+"<literal role=\"hook\">pretag</literal>&emdash;before tagging a changeset"
+msgstr "<literal role=\"hook\">pretag</literal>—创建标签之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1778
+msgid ""
+"This controlling hook is run before a tag is created.  If the hook succeeds, "
+"creation of the tag proceeds.  If the hook fails, the tag is not created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1786
+msgid ""
+"<literal>local</literal>: A boolean.  Whether the tag is local to this "
+"repository instance (i.e. stored in <filename role=\"special\">.hg/localtags</"
+"filename>) or managed by Mercurial (stored in <filename role=\"special\">."
+"hgtags</filename>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1793
+msgid ""
+"<literal>node</literal>: A changeset ID.  The ID of the changeset to be "
+"tagged."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1797
+msgid "<literal>tag</literal>: A string.  The name of the tag to be created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1802
+msgid ""
+"If the tag to be created is revision-controlled, the <literal role=\"hook"
+"\">precommit</literal> and <literal role=\"hook\">pretxncommit</literal> "
+"hooks (<xref linkend=\"sec:hook:commit\"/> and <xref linkend=\"sec:hook:"
+"pretxncommit\"/>) will also be run."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1810
+msgid ""
+"See also: <literal role=\"hook\">tag</literal> (<xref linkend=\"sec:hook:tag"
+"\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1815
+msgid ""
+"<literal role=\"hook\">pretxnchangegroup</literal>&emdash;before completing "
+"addition of remote changesets"
+msgstr ""
+"<literal role=\"hook\">pretxnchangegroup</literal>—完成增加远程修改集之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1819
+msgid ""
+"This controlling hook is run before a transaction&emdash;that manages the "
+"addition of a group of new changesets from outside the repository&emdash;"
+"completes.  If the hook succeeds, the transaction completes, and all of the "
+"changesets become permanent within this repository.  If the hook fails, the "
+"transaction is rolled back, and the data for the changesets is erased."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1828
+msgid ""
+"This hook can access the metadata associated with the almost-added "
+"changesets, but it should not do anything permanent with this data. It must "
+"also not modify the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1834
+msgid ""
+"While this hook is running, if other Mercurial processes access this "
+"repository, they will be able to see the almost-added changesets as if they "
+"are permanent.  This may lead to race conditions if you do not take steps to "
+"avoid them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1841
+msgid ""
+"This hook can be used to automatically vet a group of changesets.  If the "
+"hook fails, all of the changesets are <quote>rejected</quote> when the "
+"transaction rolls back."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1870
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (<xref linkend=\"sec:"
+"hook:changegroup\"/>), <literal role=\"hook\">incoming</literal> (<xref "
+"linkend=\"sec:hook:incoming\"/>), <literal role=\"hook\">prechangegroup</"
+"literal> (<xref linkend=\"sec:hook:prechangegroup\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1881
+msgid ""
+"<literal role=\"hook\">pretxncommit</literal>&emdash;before completing commit "
+"of new changeset"
+msgstr "<literal role=\"hook\">pretxncommit</literal>—完成提交之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1884
+msgid ""
+"This controlling hook is run before a transaction&emdash;that manages a new "
+"commit&emdash;completes.  If the hook succeeds, the transaction completes and "
+"the changeset becomes permanent within this repository.  If the hook fails, "
+"the transaction is rolled back, and the commit data is erased."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1892
+msgid ""
+"This hook can access the metadata associated with the almost-new changeset, "
+"but it should not do anything permanent with this data.  It must also not "
+"modify the working directory."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1898
+msgid ""
+"While this hook is running, if other Mercurial processes access this "
+"repository, they will be able to see the almost-new changeset as if it is "
+"permanent.  This may lead to race conditions if you do not take steps to "
+"avoid them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1922
+msgid ""
+"See also: <literal role=\"hook\">precommit</literal> (<xref linkend=\"sec:"
+"hook:precommit\"/>)"
+msgstr ""
+"参见: <literal role=\"hook\">precommit</literal> (<xref linkend=\"sec:hook:"
+"precommit\"/>)"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1929
+msgid ""
+"<literal role=\"hook\">preupdate</literal>&emdash;before updating or merging "
+"working directory"
+msgstr "<literal role=\"hook\">preupdate</literal>—更新或合并工作目录之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1932
+msgid ""
+"This controlling hook is run before an update or merge of the working "
+"directory begins.  It is run only if Mercurial's normal pre-update checks "
+"determine that the update or merge can proceed.  If the hook succeeds, the "
+"update or merge may proceed; if it fails, the update or merge does not start."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1943
+msgid ""
+"<literal>parent1</literal>: A changeset ID. The ID of the parent that the "
+"working directory is to be updated to.  If the working directory is being "
+"merged, it will not change this parent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1949
+msgid ""
+"<literal>parent2</literal>: A changeset ID. Only set if the working directory "
+"is being merged.  The ID of the revision that the working directory is being "
+"merged with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1956
+msgid ""
+"See also: <literal role=\"hook\">update</literal> (<xref linkend=\"sec:hook:"
+"update\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1961
+msgid "<literal role=\"hook\">tag</literal>&emdash;after tagging a changeset"
+msgstr "<literal role=\"hook\">tag</literal>—创建标签之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1964
+msgid "This hook is run after a tag has been created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1970
+msgid ""
+"<literal>local</literal>: A boolean.  Whether the new tag is local to this "
+"repository instance (i.e.  stored in <filename role=\"special\">.hg/"
+"localtags</filename>) or managed by Mercurial (stored in <filename role="
+"\"special\">.hgtags</filename>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1978
+msgid ""
+"<literal>node</literal>: A changeset ID.  The ID of the changeset that was "
+"tagged."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1982
+msgid "<literal>tag</literal>: A string.  The name of the tag that was created."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1987
+msgid ""
+"If the created tag is revision-controlled, the <literal role=\"hook\">commit</"
+"literal> hook (section <xref linkend=\"sec:hook:commit\"/>) is run before "
+"this hook."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1992
+msgid ""
+"See also: <literal role=\"hook\">pretag</literal> (<xref linkend=\"sec:hook:"
+"pretag\"/>)"
+msgstr ""
+"参见: <literal role=\"hook\">pretag</literal> (<xref linkend=\"sec:hook:pretag"
+"\"/>)"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1998
+msgid ""
+"<literal role=\"hook\">update</literal>&emdash;after updating or merging "
+"working directory"
+msgstr "<literal role=\"hook\">update</literal>—更新或合并工作目录之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:2001
+msgid ""
+"This hook is run after an update or merge of the working directory "
+"completes.  Since a merge can fail (if the external <command>hgmerge</"
+"command> command fails to resolve conflicts in a file), this hook "
+"communicates whether the update or merge completed cleanly."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:2009
+msgid ""
+"<literal>error</literal>: A boolean.  Indicates whether the update or merge "
+"completed successfully."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:2014
+msgid ""
+"<literal>parent1</literal>: A changeset ID.  The ID of the parent that the "
+"working directory was updated to.  If the working directory was merged, it "
+"will not have changed this parent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:2020
+msgid ""
+"<literal>parent2</literal>: A changeset ID.  Only set if the working "
+"directory was merged.  The ID of the revision that the working directory was "
+"merged with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:2026
+msgid ""
+"See also: <literal role=\"hook\">preupdate</literal> (<xref linkend=\"sec:"
+"hook:preupdate\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch10-template.xml:5
+msgid "Customising the output of Mercurial"
+msgstr "定制 Mercurial 的输出"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch10-template.xml:7
+msgid ""
+"Mercurial provides a powerful mechanism to let you control how it displays "
+"information.  The mechanism is based on templates.  You can use templates to "
+"generate specific output for a single command, or to customise the entire "
+"appearance of the built-in web interface."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:14
+msgid "Using precanned output styles"
+msgstr "使用预定义的输出样式"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:16
+msgid ""
+"Packaged with Mercurial are some output styles that you can use immediately.  "
+"A style is simply a precanned template that someone wrote and installed "
+"somewhere that Mercurial can find."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:21
+msgid ""
+"Before we take a look at Mercurial's bundled styles, let's review its normal "
+"output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:26
+msgid ""
+"This is somewhat informative, but it takes up a lot of space&emdash;five "
+"lines of output per changeset.  The <literal>compact</literal> style reduces "
+"this to three lines, presented in a sparse manner."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:33
+msgid ""
+"The <literal>changelog</literal> style hints at the expressive power of "
+"Mercurial's templating engine.  This style attempts to follow the GNU "
+"Project's changelog guidelines<citation>web:changelog</citation>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:40
+msgid ""
+"You will not be shocked to learn that Mercurial's default output style is "
+"named <literal>default</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:44
+msgid "Setting a default style"
+msgstr "设置默认样式"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:46
+msgid ""
+"You can modify the output style that Mercurial will use for every command by "
+"editing your <filename role=\"special\">~/.hgrc</filename> file, naming the "
+"style you would prefer to use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:54
+msgid ""
+"If you write a style of your own, you can use it by either providing the path "
+"to your style file, or copying your style file into a location where "
+"Mercurial can find it (typically the <literal>templates</literal> "
+"subdirectory of your Mercurial install directory)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:63
+msgid "Commands that support styles and templates"
+msgstr "支持样式和模版的命令"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:65
+msgid ""
+"All of Mercurial's <quote><literal>log</literal>-like</quote> commands let "
+"you use styles and templates: <command role=\"hg-cmd\">hg incoming</command>, "
+"<command role=\"hg-cmd\">hg log</command>, <command role=\"hg-cmd\">hg "
+"outgoing</command>, and <command role=\"hg-cmd\">hg tip</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:72
+msgid ""
+"As I write this manual, these are so far the only commands that support "
+"styles and templates.  Since these are the most important commands that need "
+"customisable output, there has been little pressure from the Mercurial user "
+"community to add style and template support to other commands."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:80
+msgid "The basics of templating"
+msgstr "模版基础"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:82
+msgid ""
+"At its simplest, a Mercurial template is a piece of text.  Some of the text "
+"never changes, while other parts are <emphasis>expanded</emphasis>, or "
+"replaced with new text, when necessary."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:87
+msgid ""
+"Before we continue, let's look again at a simple example of Mercurial's "
+"normal output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:92
+msgid ""
+"Now, let's run the same command, but using a template to change its output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:97
+msgid ""
+"The example above illustrates the simplest possible template; it's just a "
+"piece of static text, printed once for each changeset.  The <option role=\"hg-"
+"opt-log\">--template</option> option to the <command role=\"hg-cmd\">hg log</"
+"command> command tells Mercurial to use the given text as the template when "
+"printing each changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:105
+msgid ""
+"Notice that the template string above ends with the text <quote><literal>\\n</"
+"literal></quote>.  This is an <emphasis>escape sequence</emphasis>, telling "
+"Mercurial to print a newline at the end of each template item.  If you omit "
+"this newline, Mercurial will run each piece of output together.  See <xref "
+"linkend=\"sec:template:escape\"/> for more details of escape sequences."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:113
+msgid ""
+"A template that prints a fixed string of text all the time isn't very useful; "
+"let's try something a bit more complex."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:119
+msgid ""
+"As you can see, the string <quote><literal>{desc}</literal></quote> in the "
+"template has been replaced in the output with the description of each "
+"changeset.  Every time Mercurial finds text enclosed in curly braces "
+"(<quote><literal>{</literal></quote> and <quote><literal>}</literal></"
+"quote>), it will try to replace the braces and text with the expansion of "
+"whatever is inside.  To print a literal curly brace, you must escape it, as "
+"described in <xref linkend=\"sec:template:escape\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:131
+msgid "Common template keywords"
+msgstr "模版关键字"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:133
+msgid ""
+"You can start writing simple templates immediately using the keywords below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:137
+msgid ""
+"<literal role=\"template-keyword\">author</literal>: String.  The unmodified "
+"author of the changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:141
+msgid ""
+"<literal role=\"template-keyword\">branches</literal>: String.  The name of "
+"the branch on which the changeset was committed.  Will be empty if the branch "
+"name was <literal>default</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:147
+msgid ""
+"<literal role=\"template-keyword\">date</literal>: Date information.  The "
+"date when the changeset was committed.  This is <emphasis>not</emphasis> "
+"human-readable; you must pass it through a filter that will render it "
+"appropriately.  See <xref linkend=\"sec:template:filter\"/> for more "
+"information on filters. The date is expressed as a pair of numbers.  The "
+"first number is a Unix UTC timestamp (seconds since January 1, 1970); the "
+"second is the offset of the committer's timezone from UTC, in seconds."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:158
+msgid ""
+"<literal role=\"template-keyword\">desc</literal>: String.  The text of the "
+"changeset description."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:161
+msgid ""
+"<literal role=\"template-keyword\">files</literal>: List of strings.  All "
+"files modified, added, or removed by this changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:166
+msgid ""
+"<literal role=\"template-keyword\">file_adds</literal>: List of strings.  "
+"Files added by this changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:170
+msgid ""
+"<literal role=\"template-keyword\">file_dels</literal>: List of strings.  "
+"Files removed by this changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:174
+msgid ""
+"<literal role=\"template-keyword\">node</literal>: String.  The changeset "
+"identification hash, as a 40-character hexadecimal string."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:178
+msgid ""
+"<literal role=\"template-keyword\">parents</literal>: List of strings.  The "
+"parents of the changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:182
+msgid ""
+"<literal role=\"template-keyword\">rev</literal>: Integer.  The repository-"
+"local changeset revision number."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:186
+msgid ""
+"<literal role=\"template-keyword\">tags</literal>: List of strings.  Any tags "
+"associated with the changeset."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:191
+msgid ""
+"A few simple experiments will show us what to expect when we use these "
+"keywords; you can see the results below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:196
+msgid ""
+"As we noted above, the date keyword does not produce human-readable output, "
+"so we must treat it specially.  This involves using a <emphasis>filter</"
+"emphasis>, about which more in <xref linkend=\"sec:template:filter\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:205
+msgid "Escape sequences"
+msgstr "转义序列"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:207
+msgid ""
+"Mercurial's templating engine recognises the most commonly used escape "
+"sequences in strings.  When it sees a backslash (<quote><literal>\\</"
+"literal></quote>) character, it looks at the following character and "
+"substitutes the two characters with a single replacement, as described below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:214
+msgid ""
+"<literal>\\</literal>: Backslash, <quote><literal>\\</literal></quote>, ASCII "
+"134."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:218
+msgid "<literal>\\n</literal>: Newline, ASCII 12."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:221
+msgid "<literal>\\r</literal>: Carriage return, ASCII 15."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:224
+msgid "<literal>\\t</literal>: Tab, ASCII 11."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:227
+msgid "<literal>\\v</literal>: Vertical tab, ASCII 13."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:230
+msgid ""
+"<literal>{</literal>: Open curly brace, <quote><literal>{</literal></quote>, "
+"ASCII 173."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:234
+msgid ""
+"<literal>}</literal>: Close curly brace, <quote><literal>}</literal></quote>, "
+"ASCII 175."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:239
+msgid ""
+"As indicated above, if you want the expansion of a template to contain a "
+"literal <quote><literal>\\</literal></quote>, <quote><literal>{</literal></"
+"quote>, or <quote><literal>{</literal></quote> character, you must escape it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:247
+msgid "Filtering keywords to change their results"
+msgstr "通过过滤关键字来修改输出结果"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:249
+msgid ""
+"Some of the results of template expansion are not immediately easy to use.  "
+"Mercurial lets you specify an optional chain of <emphasis>filters</emphasis> "
+"to modify the result of expanding a keyword.  You have already seen a common "
+"filter, <literal role=\"template-kw-filt-date\">isodate</literal>, in action "
+"above, to make a date readable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:256
+msgid ""
+"Below is a list of the most commonly used filters that Mercurial supports.  "
+"While some filters can be applied to any text, others can only be used in "
+"specific circumstances.  The name of each filter is followed first by an "
+"indication of where it can be used, then a description of its effect."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:263
+msgid ""
+"<literal role=\"template-filter\">addbreaks</literal>: Any text. Add an XHTML "
+"<quote><literal>&lt;br/&gt;</literal></quote> tag before the end of every "
+"line except the last.  For example, <quote><literal>foo\\nbar</literal></"
+"quote> becomes <quote><literal>foo&lt;br/&gt;\\nbar</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:270
+msgid ""
+"<literal role=\"template-kw-filt-date\">age</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render the age of the date, "
+"relative to the current time.  Yields a string like <quote><literal>10 "
+"minutes</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:277
+msgid ""
+"<literal role=\"template-filter\">basename</literal>: Any text, but most "
+"useful for the <literal role=\"template-keyword\">files</literal> keyword and "
+"its relatives.  Treat the text as a path, and return the basename. For "
+"example, <quote><literal>foo/bar/baz</literal></quote> becomes "
+"<quote><literal>baz</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:286
+msgid ""
+"<literal role=\"template-kw-filt-date\">date</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render a date in a similar "
+"format to the Unix <literal role=\"template-keyword\">date</literal> command, "
+"but with timezone included.  Yields a string like <quote><literal>Mon Sep 04 "
+"15:13:13 2006 -0700</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:294
+msgid ""
+"<literal role=\"template-kw-filt-author\">domain</literal>: Any text, but "
+"most useful for the <literal role=\"template-keyword\">author</literal> "
+"keyword.  Finds the first string that looks like an email address, and "
+"extract just the domain component.  For example, <quote><literal>Bryan "
+"O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes "
+"<quote><literal>serpentine.com</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:304
+msgid ""
+"<literal role=\"template-kw-filt-author\">email</literal>: Any text, but most "
+"useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
+"Extract the first string that looks like an email address.  For example, "
+"<quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> "
+"becomes <quote><literal>bos@serpentine.com</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:313
+msgid ""
+"<literal role=\"template-filter\">escape</literal>: Any text.  Replace the "
+"special XML/XHTML characters <quote><literal>&amp;</literal></quote>, "
+"<quote><literal>&lt;</literal></quote> and <quote><literal>&gt;</literal></"
+"quote> with XML entities."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:321
+msgid ""
+"<literal role=\"template-filter\">fill68</literal>: Any text.  Wrap the text "
+"to fit in 68 columns.  This is useful before you pass text through the "
+"<literal role=\"template-filter\">tabindent</literal> filter, and still want "
+"it to fit in an 80-column fixed-font window."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:329
+msgid ""
+"<literal role=\"template-filter\">fill76</literal>: Any text.  Wrap the text "
+"to fit in 76 columns."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:333
+msgid ""
+"<literal role=\"template-filter\">firstline</literal>: Any text.  Yield the "
+"first line of text, without any trailing newlines."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:338
+msgid ""
+"<literal role=\"template-kw-filt-date\">hgdate</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render the date as a pair of "
+"readable numbers.  Yields a string like <quote><literal>1157407993 25200</"
+"literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:345
+msgid ""
+"<literal role=\"template-kw-filt-date\">isodate</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render the date as a text "
+"string in ISO 8601 format.  Yields a string like <quote><literal>2006-09-04 "
+"15:13:13 -0700</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:352
+msgid ""
+"<literal role=\"template-filter\">obfuscate</literal>: Any text, but most "
+"useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
+"Yield the input text rendered as a sequence of XML entities.  This helps to "
+"defeat some particularly stupid screen-scraping email harvesting spambots."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:360
+msgid ""
+"<literal role=\"template-kw-filt-author\">person</literal>: Any text, but "
+"most useful for the <literal role=\"template-keyword\">author</literal> "
+"keyword.  Yield the text before an email address. For example, "
+"<quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> "
+"becomes <quote><literal>Bryan O'Sullivan</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:369
+msgid ""
+"<literal role=\"template-kw-filt-date\">rfc822date</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render a date using the same "
+"format used in email headers.  Yields a string like <quote><literal>Mon, 04 "
+"Sep 2006 15:13:13 -0700</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:376
+msgid ""
+"<literal role=\"template-kw-filt-node\">short</literal>: Changeset hash.  "
+"Yield the short form of a changeset hash, i.e. a 12-character hexadecimal "
+"string."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:381
+msgid ""
+"<literal role=\"template-kw-filt-date\">shortdate</literal>: <literal role="
+"\"template-keyword\">date</literal> keyword.  Render the year, month, and day "
+"of the date.  Yields a string like <quote><literal>2006-09-04</literal></"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:387
+msgid ""
+"<literal role=\"template-filter\">strip</literal>: Any text.  Strip all "
+"leading and trailing whitespace from the string."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:391
+msgid ""
+"<literal role=\"template-filter\">tabindent</literal>: Any text.  Yield the "
+"text, with every line except the first starting with a tab character."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:396
+msgid ""
+"<literal role=\"template-filter\">urlescape</literal>: Any text.  Escape all "
+"characters that are considered <quote>special</quote> by URL parsers.  For "
+"example, <literal>foo bar</literal> becomes <literal>foo%20bar</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:403
+msgid ""
+"<literal role=\"template-kw-filt-author\">user</literal>: Any text, but most "
+"useful for the <literal role=\"template-keyword\">author</literal> keyword.  "
+"Return the <quote>user</quote> portion of an email address.  For example, "
+"<quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> "
+"becomes <quote><literal>bos</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch10-template.xml:416
+msgid ""
+"If you try to apply a filter to a piece of data that it cannot process, "
+"Mercurial will fail and print a Python exception.  For example, trying to run "
+"the output of the <literal role=\"template-keyword\">desc</literal> keyword "
+"into the <literal role=\"template-kw-filt-date\">isodate</literal> filter is "
+"not a good idea."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:425
+msgid "Combining filters"
+msgstr "组合过滤器"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:427
+msgid ""
+"It is easy to combine filters to yield output in the form you would like.  "
+"The following chain of filters tidies up a description, then makes sure that "
+"it fits cleanly into 68 columns, then indents it by a further 8 characters "
+"(at least on Unix-like systems, where a tab is conventionally 8 characters "
+"wide)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:436
+msgid ""
+"Note the use of <quote><literal>\\t</literal></quote> (a tab character) in "
+"the template to force the first line to be indented; this is necessary since "
+"<literal role=\"template-keyword\">tabindent</literal> indents all lines "
+"<emphasis>except</emphasis> the first."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:442
+msgid ""
+"Keep in mind that the order of filters in a chain is significant.  The first "
+"filter is applied to the result of the keyword; the second to the result of "
+"the first filter; and so on.  For example, using <literal>fill68|tabindent</"
+"literal> gives very different results from <literal>tabindent|fill68</"
+"literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:453
+msgid "From templates to styles"
+msgstr "从模版到样式"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:455
+msgid ""
+"A command line template provides a quick and simple way to format some "
+"output.  Templates can become verbose, though, and it's useful to be able to "
+"give a template a name.  A style file is a template with a name, stored in a "
+"file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:460
+msgid ""
+"More than that, using a style file unlocks the power of Mercurial's "
+"templating engine in ways that are not possible using the command line "
+"<option role=\"hg-opt-log\">--template</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:466
+msgid "The simplest of style files"
+msgstr "最简单的样式文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:468
+msgid "Our simple style file contains just one line:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:472
+msgid ""
+"This tells Mercurial, <quote>if you're printing a changeset, use the text on "
+"the right as the template</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:478
+msgid "Style file syntax"
+msgstr "样式文件语法"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:480
+msgid "The syntax rules for a style file are simple."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:483
+msgid "The file is processed one line at a time."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:486
+msgid "Leading and trailing white space are ignored."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:489
+msgid "Empty lines are skipped."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:491
+msgid ""
+"If a line starts with either of the characters <quote><literal>#</literal></"
+"quote> or <quote><literal>;</literal></quote>, the entire line is treated as "
+"a comment, and skipped as if empty."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:496
+msgid ""
+"A line starts with a keyword.  This must start with an alphabetic character "
+"or underscore, and can subsequently contain any alphanumeric character or "
+"underscore.  (In regexp notation, a keyword must match <literal>[A-Za-z_][A-"
+"Za-z0-9_]*</literal>.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:502
+msgid ""
+"The next element must be an <quote><literal>=</literal></quote> character, "
+"which can be preceded or followed by an arbitrary amount of white space."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:507
+msgid ""
+"If the rest of the line starts and ends with matching quote characters "
+"(either single or double quote), it is treated as a template body."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:511
+msgid ""
+"If the rest of the line <emphasis>does not</emphasis> start with a quote "
+"character, it is treated as the name of a file; the contents of this file "
+"will be read and used as a template body."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:520
+msgid "Style files by example"
+msgstr "样式文件例子"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:522
+msgid ""
+"To illustrate how to write a style file, we will construct a few by example.  "
+"Rather than provide a complete style file and walk through it, we'll mirror "
+"the usual process of developing a style file by starting with something very "
+"simple, and walking through a series of successively more complete examples."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:529
+msgid "Identifying mistakes in style files"
+msgstr "在样式文件中定位错误"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:531
+msgid ""
+"If Mercurial encounters a problem in a style file you are working on, it "
+"prints a terse error message that, once you figure out what it means, is "
+"actually quite useful."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:537
+msgid ""
+"Notice that <filename>broken.style</filename> attempts to define a "
+"<literal>changeset</literal> keyword, but forgets to give any content for it. "
+"When instructed to use this style file, Mercurial promptly complains."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:544
+msgid "This error message looks intimidating, but it is not too hard to follow."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:548
+msgid ""
+"The first component is simply Mercurial's way of saying <quote>I am giving "
+"up</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:552
+msgid "Next comes the name of the style file that contains the error."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:556
+msgid ""
+"Following the file name is the line number where the error was encountered."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:560
+msgid "Finally, a description of what went wrong."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:564
+msgid ""
+"The description of the problem is not always clear (as in this case), but "
+"even when it is cryptic, it is almost always trivial to visually inspect the "
+"offending line in the style file and see what is wrong."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:572
+msgid "Uniquely identifying a repository"
+msgstr "版本库的唯一标识"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:574
+msgid ""
+"If you would like to be able to identify a Mercurial repository <quote>fairly "
+"uniquely</quote> using a short string as an identifier, you can use the first "
+"revision in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:581
+msgid ""
+"This is not guaranteed to be unique, but it is nevertheless useful in many "
+"cases."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:584
+msgid ""
+"It will not work in a completely empty repository, because such a repository "
+"does not have a revision zero."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:588
+msgid ""
+"Neither will it work in the (extremely rare)  case where a repository is a "
+"merge of two or more formerly independent repositories, and you still have "
+"those repositories around."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:593
+msgid "Here are some uses to which you could put this identifier:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:596
+msgid ""
+"As a key into a table for a database that manages repositories on a server."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:599
+msgid ""
+"As half of a {<emphasis>repository ID</emphasis>, <emphasis>revision ID</"
+"emphasis>} tuple.  Save this information away when you run an automated build "
+"or other activity, so that you can <quote>replay</quote> the build later if "
+"necessary."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch10-template.xml:608
+msgid "Mimicking Subversion's output"
+msgstr "模仿 Subversion 的输出"
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:610
+msgid ""
+"Let's try to emulate the default output format used by another revision "
+"control tool, Subversion."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:615
+msgid ""
+"Since Subversion's output style is fairly simple, it is easy to copy-and-"
+"paste a hunk of its output into a file, and replace the text produced above "
+"by Subversion with the template values we'd like to see expanded."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:622
+msgid ""
+"There are a few small ways in which this template deviates from the output "
+"produced by Subversion."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:625
+msgid ""
+"Subversion prints a <quote>readable</quote> date (the <quote><literal>Wed, 27 "
+"Sep 2006</literal></quote> in the example output above) in parentheses.  "
+"Mercurial's templating engine does not provide a way to display a date in "
+"this format without also printing the time and time zone."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:632
+msgid ""
+"We emulate Subversion's printing of <quote>separator</quote> lines full of "
+"<quote><literal>-</literal></quote> characters by ending the template with "
+"such a line. We use the templating engine's <literal role=\"template-keyword"
+"\">header</literal> keyword to print a separator line as the first line of "
+"output (see below), thus achieving similar output to Subversion."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:641
+msgid ""
+"Subversion's output includes a count in the header of the number of lines in "
+"the commit message.  We cannot replicate this in Mercurial; the templating "
+"engine does not currently provide a filter that counts the number of lines "
+"the template generates."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:647
+msgid ""
+"It took me no more than a minute or two of work to replace literal text from "
+"an example of Subversion's output with some keywords and filters to give the "
+"template above.  The style file simply refers to the template."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:654
+msgid ""
+"We could have included the text of the template file directly in the style "
+"file by enclosing it in quotes and replacing the newlines with "
+"<quote><literal>\\n</literal></quote> sequences, but it would have made the "
+"style file too difficult to read.  Readability is a good guide when you're "
+"trying to decide whether some text belongs in a style file, or in a template "
+"file that the style file points to.  If the style file will look too big or "
+"cluttered if you insert a literal piece of text, drop it into a template "
+"instead."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch11-mq.xml:5
+msgid "Managing change with Mercurial Queues"
+msgstr "使用 MQ 管理修改"
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:8
+msgid "The patch management problem"
+msgstr "补丁的管理问题"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:10
+msgid ""
+"Here is a common scenario: you need to install a software package from "
+"source, but you find a bug that you must fix in the source before you can "
+"start using the package.  You make your changes, forget about the package for "
+"a while, and a few months later you need to upgrade to a newer version of the "
+"package.  If the newer version of the package still has the bug, you must "
+"extract your fix from the older source tree and apply it against the newer "
+"version.  This is a tedious task, and it's easy to make mistakes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:20
+msgid ""
+"This is a simple case of the <quote>patch management</quote> problem.  You "
+"have an <quote>upstream</quote> source tree that you can't change; you need "
+"to make some local changes on top of the upstream tree; and you'd like to be "
+"able to keep those changes separate, so that you can apply them to newer "
+"versions of the upstream source."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:27
+msgid ""
+"The patch management problem arises in many situations.  Probably the most "
+"visible is that a user of an open source software project will contribute a "
+"bug fix or new feature to the project's maintainers in the form of a patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:32
+msgid ""
+"Distributors of operating systems that include open source software often "
+"need to make changes to the packages they distribute so that they will build "
+"properly in their environments."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:37
+msgid ""
+"When you have few changes to maintain, it is easy to manage a single patch "
+"using the standard <command>diff</command> and <command>patch</command> "
+"programs (see <xref linkend=\"sec:mq:patch\"/> for a discussion of these "
+"tools). Once the number of changes grows, it starts to make sense to maintain "
+"patches as discrete <quote>chunks of work,</quote> so that for example a "
+"single patch will contain only one bug fix (the patch might modify several "
+"files, but it's doing <quote>only one thing</quote>), and you may have a "
+"number of such patches for different bugs you need fixed and local changes "
+"you require.  In this situation, if you submit a bug fix patch to the "
+"upstream maintainers of a package and they include your fix in a subsequent "
+"release, you can simply drop that single patch when you're updating to the "
+"newer release."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:52
+msgid ""
+"Maintaining a single patch against an upstream tree is a little tedious and "
+"error-prone, but not difficult.  However, the complexity of the problem grows "
+"rapidly as the number of patches you have to maintain increases.  With more "
+"than a tiny number of patches in hand, understanding which ones you have "
+"applied and maintaining them moves from messy to overwhelming."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:59
+msgid ""
+"Fortunately, Mercurial includes a powerful extension, Mercurial Queues (or "
+"simply <quote>MQ</quote>), that massively simplifies the patch management "
+"problem."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:65
+msgid "The prehistory of Mercurial Queues"
+msgstr "MQ 的历史"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:67
+msgid ""
+"During the late 1990s, several Linux kernel developers started to maintain "
+"<quote>patch series</quote> that modified the behaviour of the Linux kernel.  "
+"Some of these series were focused on stability, some on feature coverage, and "
+"others were more speculative."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:73
+msgid ""
+"The sizes of these patch series grew rapidly.  In 2002, Andrew Morton "
+"published some shell scripts he had been using to automate the task of "
+"managing his patch queues.  Andrew was successfully using these scripts to "
+"manage hundreds (sometimes thousands) of patches on top of the Linux kernel."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:80
+msgid "A patchwork quilt"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:82
+msgid ""
+"In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the approach "
+"of Andrew's scripts and published a tool called <quote>patchwork quilt</"
+"quote> <citation>web:quilt</citation>, or simply <quote>quilt</quote> (see "
+"<citation>gruenbacher:2005</citation> for a paper describing it).  Because "
+"quilt substantially automated patch management, it rapidly gained a large "
+"following among open source software developers."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:91
+msgid ""
+"Quilt manages a <emphasis>stack of patches</emphasis> on top of a directory "
+"tree. To begin, you tell quilt to manage a directory tree, and tell it which "
+"files you want to manage; it stores away the names and contents of those "
+"files.  To fix a bug, you create a new patch (using a single command), edit "
+"the files you need to fix, then <quote>refresh</quote> the patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:99
+msgid ""
+"The refresh step causes quilt to scan the directory tree; it updates the "
+"patch with all of the changes you have made.  You can create another patch on "
+"top of the first, which will track the changes required to modify the tree "
+"from <quote>tree with one patch applied</quote> to <quote>tree with two "
+"patches applied</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:106
+msgid ""
+"You can <emphasis>change</emphasis> which patches are applied to the tree.  "
+"If you <quote>pop</quote> a patch, the changes made by that patch will vanish "
+"from the directory tree.  Quilt remembers which patches you have popped, "
+"though, so you can <quote>push</quote> a popped patch again, and the "
+"directory tree will be restored to contain the modifications in the patch.  "
+"Most importantly, you can run the <quote>refresh</quote> command at any time, "
+"and the topmost applied patch will be updated.  This means that you can, at "
+"any time, change both which patches are applied and what modifications those "
+"patches make."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:118
+msgid ""
+"Quilt knows nothing about revision control tools, so it works equally well on "
+"top of an unpacked tarball or a Subversion working copy."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:124
+msgid "From patchwork quilt to Mercurial Queues"
+msgstr "从 patchwork quilt 到 MQ"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:126
+msgid ""
+"In mid-2005, Chris Mason took the features of quilt and wrote an extension "
+"that he called Mercurial Queues, which added quilt-like behaviour to "
+"Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:130
+msgid ""
+"The key difference between quilt and MQ is that quilt knows nothing about "
+"revision control systems, while MQ is <emphasis>integrated</emphasis> into "
+"Mercurial.  Each patch that you push is represented as a Mercurial "
+"changeset.  Pop a patch, and the changeset goes away."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:136
+msgid ""
+"Because quilt does not care about revision control tools, it is still a "
+"tremendously useful piece of software to know about for situations where you "
+"cannot use Mercurial and MQ."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:144
+msgid "The huge advantage of MQ"
+msgstr "MQ 的巨大优势"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:146
+msgid ""
+"I cannot overstate the value that MQ offers through the unification of "
+"patches and revision control."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:149
+msgid ""
+"A major reason that patches have persisted in the free software and open "
+"source world&emdash;in spite of the availability of increasingly capable "
+"revision control tools over the years&emdash;is the <emphasis>agility</"
+"emphasis> they offer."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:155
+msgid ""
+"Traditional revision control tools make a permanent, irreversible record of "
+"everything that you do.  While this has great value, it's also somewhat "
+"stifling.  If you want to perform a wild-eyed experiment, you have to be "
+"careful in how you go about it, or you risk leaving unneeded&emdash;or worse, "
+"misleading or destabilising&emdash;traces of your missteps and errors in the "
+"permanent revision record."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:163
+msgid ""
+"By contrast, MQ's marriage of distributed revision control with patches makes "
+"it much easier to isolate your work.  Your patches live on top of normal "
+"revision history, and you can make them disappear or reappear at will.  If "
+"you don't like a patch, you can drop it.  If a patch isn't quite as you want "
+"it to be, simply fix it&emdash;as many times as you need to, until you have "
+"refined it into the form you desire."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:171
+msgid ""
+"As an example, the integration of patches with revision control makes "
+"understanding patches and debugging their effects&emdash;and their interplay "
+"with the code they're based on&emdash;<emphasis>enormously</emphasis> easier. "
+"Since every applied patch has an associated changeset, you can give <command "
+"role=\"hg-cmd\">hg log</command> a file name to see which changesets and "
+"patches affected the file.  You can use the <command role=\"hg-cmd\">hg "
+"bisect</command> command to binary-search through all changesets and applied "
+"patches to see where a bug got introduced or fixed.  You can use the <command "
+"role=\"hg-cmd\">hg annotate</command> command to see which changeset or patch "
+"modified a particular line of a source file.  And so on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:189
+msgid ""
+"Because MQ doesn't hide its patch-oriented nature, it is helpful to "
+"understand what patches are, and a little about the tools that work with them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:193
+msgid ""
+"The traditional Unix <command>diff</command> command compares two files, and "
+"prints a list of differences between them. The <command>patch</command> "
+"command understands these differences as <emphasis>modifications</emphasis> "
+"to make to a file.  Take a look below for a simple example of these commands "
+"in action."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:202
+msgid ""
+"The type of file that <command>diff</command> generates (and <command>patch</"
+"command> takes as input) is called a <quote>patch</quote> or a <quote>diff</"
+"quote>; there is no difference between a patch and a diff.  (We'll use the "
+"term <quote>patch</quote>, since it's more commonly used.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:208
+msgid ""
+"A patch file can start with arbitrary text; the <command>patch</command> "
+"command ignores this text, but MQ uses it as the commit message when creating "
+"changesets.  To find the beginning of the patch content, <command>patch</"
+"command> searches for the first line that starts with the string "
+"<quote><literal>diff -</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:215
+msgid ""
+"MQ works with <emphasis>unified</emphasis> diffs (<command>patch</command> "
+"can accept several other diff formats, but MQ doesn't).  A unified diff "
+"contains two kinds of header.  The <emphasis>file header</emphasis> describes "
+"the file being modified; it contains the name of the file to modify.  When "
+"<command>patch</command> sees a new file header, it looks for a file with "
+"that name to start modifying."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:223
+msgid ""
+"After the file header comes a series of <emphasis>hunks</emphasis>.  Each "
+"hunk starts with a header; this identifies the range of line numbers within "
+"the file that the hunk should modify.  Following the header, a hunk starts "
+"and ends with a few (usually three) lines of text from the unmodified file; "
+"these are called the <emphasis>context</emphasis> for the hunk.  If there's "
+"only a small amount of context between successive hunks, <command>diff</"
+"command> doesn't print a new hunk header; it just runs the hunks together, "
+"with a few lines of context between modifications."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:235
+msgid ""
+"Each line of context begins with a space character.  Within the hunk, a line "
+"that begins with <quote><literal>-</literal></quote> means <quote>remove this "
+"line,</quote> while a line that begins with <quote><literal>+</literal></"
+"quote> means <quote>insert this line.</quote> For example, a line that is "
+"modified is represented by one deletion and one insertion."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:243
+msgid ""
+"We will return to some of the more subtle aspects of patches later (in <xref "
+"linkend=\"sec:mq:adv-patch\"/>), but you should have enough information now "
+"to use MQ."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:250
+msgid "Getting started with Mercurial Queues"
+msgstr "开始使用 MQ"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:252
+msgid ""
+"Because MQ is implemented as an extension, you must explicitly enable before "
+"you can use it.  (You don't need to download anything; MQ ships with the "
+"standard Mercurial distribution.)  To enable MQ, edit your <filename role="
+"\"home\">~/.hgrc</filename> file, and add the lines below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:262
+msgid ""
+"Once the extension is enabled, it will make a number of new commands "
+"available.  To verify that the extension is working, you can use <command "
+"role=\"hg-cmd\">hg help</command> to see if the <command role=\"hg-ext-mq"
+"\">qinit</command> command is now available."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:270
+msgid ""
+"You can use MQ with <emphasis>any</emphasis> Mercurial repository, and its "
+"commands only operate within that repository.  To get started, simply prepare "
+"the repository using the <command role=\"hg-ext-mq\">qinit</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:277
+msgid ""
+"This command creates an empty directory called <filename role=\"special\" "
+"class=\"directory\">.hg/patches</filename>, where MQ will keep its metadata.  "
+"As with many Mercurial commands, the <command role=\"hg-ext-mq\">qinit</"
+"command> command prints nothing if it succeeds."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:284
+msgid "Creating a new patch"
+msgstr "创建新补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:286
+msgid ""
+"To begin work on a new patch, use the <command role=\"hg-ext-mq\">qnew</"
+"command> command.  This command takes one argument, the name of the patch to "
+"create."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:290
+msgid ""
+"MQ will use this as the name of an actual file in the <filename role=\"special"
+"\" class=\"directory\">.hg/patches</filename> directory, as you can see below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:297
+msgid ""
+"Also newly present in the <filename role=\"special\" class=\"directory\">.hg/"
+"patches</filename> directory are two other files, <filename role=\"special"
+"\">series</filename> and <filename role=\"special\">status</filename>.  The "
+"<filename role=\"special\">series</filename> file lists all of the patches "
+"that MQ knows about for this repository, with one patch per line.  Mercurial "
+"uses the <filename role=\"special\">status</filename> file for internal book-"
+"keeping; it tracks all of the patches that MQ has <emphasis>applied</"
+"emphasis> in this repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch11-mq.xml:309
+msgid ""
+"You may sometimes want to edit the <filename role=\"special\">series</"
+"filename> file by hand; for example, to change the sequence in which some "
+"patches are applied.  However, manually editing the <filename role=\"special"
+"\">status</filename> file is almost always a bad idea, as it's easy to "
+"corrupt MQ's idea of what is happening."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:318
+msgid ""
+"Once you have created your new patch, you can edit files in the working "
+"directory as you usually would.  All of the normal Mercurial commands, such "
+"as <command role=\"hg-cmd\">hg diff</command> and <command role=\"hg-cmd\">hg "
+"annotate</command>, work exactly as they did before."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:326
+msgid "Refreshing a patch"
+msgstr "刷新补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:328
+msgid ""
+"When you reach a point where you want to save your work, use the <command "
+"role=\"hg-ext-mq\">qrefresh</command> command to update the patch you are "
+"working on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:334
+msgid ""
+"This command folds the changes you have made in the working directory into "
+"your patch, and updates its corresponding changeset to contain those changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:338
+msgid ""
+"You can run <command role=\"hg-ext-mq\">qrefresh</command> as often as you "
+"like, so it's a good way to <quote>checkpoint</quote> your work.  Refresh "
+"your patch at an opportune time; try an experiment; and if the experiment "
+"doesn't work out, <command role=\"hg-cmd\">hg revert</command> your "
+"modifications back to the last time you refreshed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:349
+msgid "Stacking and tracking patches"
+msgstr "堆叠和跟踪补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:351
+msgid ""
+"Once you have finished working on a patch, or need to work on another, you "
+"can use the <command role=\"hg-ext-mq\">qnew</command> command again to "
+"create a new patch. Mercurial will apply this patch on top of your existing "
+"patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:358
+msgid ""
+"Notice that the patch contains the changes in our prior patch as part of its "
+"context (you can see this more clearly in the output of <command role=\"hg-cmd"
+"\">hg annotate</command>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:363
+msgid ""
+"So far, with the exception of <command role=\"hg-ext-mq\">qnew</command> and "
+"<command role=\"hg-ext-mq\">qrefresh</command>, we've been careful to only "
+"use regular Mercurial commands.  However, MQ provides many commands that are "
+"easier to use when you are thinking about patches, as illustrated below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:373
+msgid ""
+"The <command role=\"hg-ext-mq\">qseries</command> command lists every patch "
+"that MQ knows about in this repository, from oldest to newest (most recently "
+"<emphasis>created</emphasis>)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:379
+msgid ""
+"The <command role=\"hg-ext-mq\">qapplied</command> command lists every patch "
+"that MQ has <emphasis>applied</emphasis> in this repository, again from "
+"oldest to newest (most recently applied)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:388
+msgid "Manipulating the patch stack"
+msgstr "操作补丁堆栈"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:390
+msgid ""
+"The previous discussion implied that there must be a difference between "
+"<quote>known</quote> and <quote>applied</quote> patches, and there is.  MQ "
+"can manage a patch without it being applied in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:395
+msgid ""
+"An <emphasis>applied</emphasis> patch has a corresponding changeset in the "
+"repository, and the effects of the patch and changeset are visible in the "
+"working directory.  You can undo the application of a patch using the "
+"<command role=\"hg-ext-mq\">qpop</command> command.  MQ still <emphasis>knows "
+"about</emphasis>, or manages, a popped patch, but the patch no longer has a "
+"corresponding changeset in the repository, and the working directory does not "
+"contain the changes made by the patch.  <xref linkend=\"fig:mq:stack\"/> "
+"illustrates the difference between applied and tracked patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><title>
+#: ../en/ch11-mq.xml:408
+msgid "Applied and unapplied patches in the MQ patch stack"
+msgstr "在 MQ 补丁堆栈中应用和撤销补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><figure><mediaobject>
+#: ../en/ch11-mq.xml:411
+msgid "<imageobject><imagedata fileref=\"figs/mq-stack.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:416
+msgid ""
+"You can reapply an unapplied, or popped, patch using the <command role=\"hg-"
+"ext-mq\">qpush</command> command.  This creates a new changeset to correspond "
+"to the patch, and the patch's changes once again become present in the "
+"working directory.  See below for examples of <command role=\"hg-ext-mq"
+"\">qpop</command> and <command role=\"hg-ext-mq\">qpush</command> in action."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:425
+msgid ""
+"Notice that once we have popped a patch or two patches, the output of "
+"<command role=\"hg-ext-mq\">qseries</command> remains the same, while that of "
+"<command role=\"hg-ext-mq\">qapplied</command> has changed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:433
+msgid "Pushing and popping many patches"
+msgstr "压入或弹出多个补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:435
+msgid ""
+"While <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-"
+"mq\">qpop</command> each operate on a single patch at a time by default, you "
+"can push and pop many patches in one go.  The <option role=\"hg-ext-mq-cmd-"
+"qpush-opt\">hg -a</option> option to <command role=\"hg-ext-mq\">qpush</"
+"command> causes it to push all unapplied patches, while the <option role=\"hg-"
+"ext-mq-cmd-qpop-opt\">-a</option> option to <command role=\"hg-ext-mq\">qpop</"
+"command> causes it to pop all applied patches.  (For some more ways to push "
+"and pop many patches, see <xref linkend=\"sec:mq:perf\"/> below.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:451
+msgid "Safety checks, and overriding them"
+msgstr "安全的检查,然后覆盖它们"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:453
+msgid ""
+"Several MQ commands check the working directory before they do anything, and "
+"fail if they find any modifications.  They do this to ensure that you won't "
+"lose any changes that you have made, but not yet incorporated into a patch.  "
+"The example below illustrates this; the <command role=\"hg-ext-mq\">qnew</"
+"command> command will not create a new patch if there are outstanding "
+"changes, caused in this case by the <command role=\"hg-cmd\">hg add</command> "
+"of <filename>file3</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:465
+msgid ""
+"Commands that check the working directory all take an <quote>I know what I'm "
+"doing</quote> option, which is always named <option>-f</option>.  The exact "
+"meaning of <option>-f</option> depends on the command.  For example, <command "
+"role=\"hg-cmd\">hg qnew <option role=\"hg-ext-mq-cmd-qnew-opt\">hg -f</"
+"option></command> will incorporate any outstanding changes into the new patch "
+"it creates, but <command role=\"hg-cmd\">hg qpop <option role=\"hg-ext-mq-cmd-"
+"qpop-opt\">hg -f</option></command> will revert modifications to any files "
+"affected by the patch that it is popping.  Be sure to read the documentation "
+"for a command's <option>-f</option> option before you use it!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:480
+msgid "Working on several patches at once"
+msgstr "同时处理多个补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:482
+msgid ""
+"The <command role=\"hg-ext-mq\">qrefresh</command> command always refreshes "
+"the <emphasis>topmost</emphasis> applied patch.  This means that you can "
+"suspend work on one patch (by refreshing it), pop or push to make a different "
+"patch the top, and work on <emphasis>that</emphasis> patch for a while."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:489
+msgid ""
+"Here's an example that illustrates how you can use this ability. Let's say "
+"you're developing a new feature as two patches.  The first is a change to the "
+"core of your software, and the second&emdash;layered on top of the "
+"first&emdash;changes the user interface to use the code you just added to the "
+"core.  If you notice a bug in the core while you're working on the UI patch, "
+"it's easy to fix the core.  Simply <command role=\"hg-ext-mq\">qrefresh</"
+"command> the UI patch to save your in-progress changes, and <command role="
+"\"hg-ext-mq\">qpop</command> down to the core patch.  Fix the core bug, "
+"<command role=\"hg-ext-mq\">qrefresh</command> the core patch, and <command "
+"role=\"hg-ext-mq\">qpush</command> back to the UI patch to continue where you "
+"left off."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:506
+msgid "More about patches"
+msgstr "关于补丁的更多信息"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:508
+msgid ""
+"MQ uses the GNU <command>patch</command> command to apply patches, so it's "
+"helpful to know a few more detailed aspects of how <command>patch</command> "
+"works, and about patches themselves."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:514
+msgid "The strip count"
+msgstr "修剪计数"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:516
+msgid ""
+"If you look at the file headers in a patch, you will notice that the "
+"pathnames usually have an extra component on the front that isn't present in "
+"the actual path name.  This is a holdover from the way that people used to "
+"generate patches (people still do this, but it's somewhat rare with modern "
+"revision control tools)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:523
+msgid ""
+"Alice would unpack a tarball, edit her files, then decide that she wanted to "
+"create a patch.  So she'd rename her working directory, unpack the tarball "
+"again (hence the need for the rename), and use the <option role=\"cmd-opt-diff"
+"\">-r</option> and <option role=\"cmd-opt-diff\">-N</option> options to "
+"<command>diff</command> to recursively generate a patch between the "
+"unmodified directory and the modified one.  The result would be that the name "
+"of the unmodified directory would be at the front of the left-hand path in "
+"every file header, and the name of the modified directory would be at the "
+"front of the right-hand path."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:536
+msgid ""
+"Since someone receiving a patch from the Alices of the net would be unlikely "
+"to have unmodified and modified directories with exactly the same names, the "
+"<command>patch</command> command has a <option role=\"cmd-opt-patch\">-p</"
+"option> option that indicates the number of leading path name components to "
+"strip when trying to apply a patch.  This number is called the "
+"<emphasis>strip count</emphasis>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:544
+msgid ""
+"An option of <quote><literal>-p1</literal></quote> means <quote>use a strip "
+"count of one</quote>.  If <command>patch</command> sees a file name "
+"<filename>foo/bar/baz</filename> in a file header, it will strip "
+"<filename>foo</filename> and try to patch a file named <filename>bar/baz</"
+"filename>.  (Strictly speaking, the strip count refers to the number of "
+"<emphasis>path separators</emphasis> (and the components that go with them ) "
+"to strip.  A strip count of one will turn <filename>foo/bar</filename> into "
+"<filename>bar</filename>, but <filename>/foo/bar</filename> (notice the extra "
+"leading slash) into <filename>foo/bar</filename>.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:557
+msgid ""
+"The <quote>standard</quote> strip count for patches is one; almost all "
+"patches contain one leading path name component that needs to be stripped. "
+"Mercurial's <command role=\"hg-cmd\">hg diff</command> command generates path "
+"names in this form, and the <command role=\"hg-cmd\">hg import</command> "
+"command and MQ expect patches to have a strip count of one."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:565
+msgid ""
+"If you receive a patch from someone that you want to add to your patch queue, "
+"and the patch needs a strip count other than one, you cannot just <command "
+"role=\"hg-ext-mq\">qimport</command> the patch, because <command role=\"hg-"
+"ext-mq\">qimport</command> does not yet have a <literal>-p</literal> option "
+"(see <ulink role=\"hg-bug\" url=\"http://www.selenic.com/mercurial/bts/"
+"issue311\">issue 311</ulink>).  Your best bet is to <command role=\"hg-ext-mq"
+"\">qnew</command> a patch of your own, then use <command>patch -pN</command> "
+"to apply their patch, followed by <command role=\"hg-cmd\">hg addremove</"
+"command> to pick up any files added or removed by the patch, followed by "
+"<command role=\"hg-ext-mq\">hg qrefresh</command>. This complexity may become "
+"unnecessary; see <ulink role=\"hg-bug\" url=\"http://www.selenic.com/"
+"mercurial/bts/issue311\">issue 311</ulink> for details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:584
+msgid "Strategies for applying a patch"
+msgstr "应用补丁的策略"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:586
+msgid ""
+"When <command>patch</command> applies a hunk, it tries a handful of "
+"successively less accurate strategies to try to make the hunk apply. This "
+"falling-back technique often makes it possible to take a patch that was "
+"generated against an old version of a file, and apply it against a newer "
+"version of that file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:593
+msgid ""
+"First, <command>patch</command> tries an exact match, where the line numbers, "
+"the context, and the text to be modified must apply exactly.  If it cannot "
+"make an exact match, it tries to find an exact match for the context, without "
+"honouring the line numbering information.  If this succeeds, it prints a line "
+"of output saying that the hunk was applied, but at some <emphasis>offset</"
+"emphasis> from the original line number."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:602
+msgid ""
+"If a context-only match fails, <command>patch</command> removes the first and "
+"last lines of the context, and tries a <emphasis>reduced</emphasis> context-"
+"only match.  If the hunk with reduced context succeeds, it prints a message "
+"saying that it applied the hunk with a <emphasis>fuzz factor</emphasis> (the "
+"number after the fuzz factor indicates how many lines of context "
+"<command>patch</command> had to trim before the patch applied)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:611
+msgid ""
+"When neither of these techniques works, <command>patch</command> prints a "
+"message saying that the hunk in question was rejected.  It saves rejected "
+"hunks (also simply called <quote>rejects</quote>) to a file with the same "
+"name, and an added <filename role=\"special\">.rej</filename> extension.  It "
+"also saves an unmodified copy of the file with a <filename role=\"special\">."
+"orig</filename> extension; the copy of the file without any extensions will "
+"contain any changes made by hunks that <emphasis>did</emphasis> apply "
+"cleanly.  If you have a patch that modifies <filename>foo</filename> with six "
+"hunks, and one of them fails to apply, you will have: an unmodified "
+"<filename>foo.orig</filename>, a <filename>foo.rej</filename> containing one "
+"hunk, and <filename>foo</filename>, containing the changes made by the five "
+"successful hunks."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:629
+msgid "Some quirks of patch representation"
+msgstr "补丁的一些特性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:631
+msgid ""
+"There are a few useful things to know about how <command>patch</command> "
+"works with files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:634
+msgid ""
+"This should already be obvious, but <command>patch</command> cannot handle "
+"binary files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:638
+msgid ""
+"Neither does it care about the executable bit; it creates new files as "
+"readable, but not executable."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:642
+msgid ""
+"<command>patch</command> treats the removal of a file as a diff between the "
+"file to be removed and the empty file.  So your idea of <quote>I deleted this "
+"file</quote> looks like <quote>every line of this file was deleted</quote> in "
+"a patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:648
+msgid ""
+"It treats the addition of a file as a diff between the empty file and the "
+"file to be added.  So in a patch, your idea of <quote>I added this file</"
+"quote> looks like <quote>every line of this file was added</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:654
+msgid ""
+"It treats a renamed file as the removal of the old name, and the addition of "
+"the new name.  This means that renamed files have a big footprint in "
+"patches.  (Note also that Mercurial does not currently try to infer when "
+"files have been renamed or copied in a patch.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:660
+msgid ""
+"<command>patch</command> cannot represent empty files, so you cannot use a "
+"patch to represent the notion <quote>I added this empty file to the tree</"
+"quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:667
+msgid "Beware the fuzz"
+msgstr "当心毛刺"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:669
+msgid ""
+"While applying a hunk at an offset, or with a fuzz factor, will often be "
+"completely successful, these inexact techniques naturally leave open the "
+"possibility of corrupting the patched file.  The most common cases typically "
+"involve applying a patch twice, or at an incorrect location in the file.  If "
+"<command>patch</command> or <command role=\"hg-ext-mq\">qpush</command> ever "
+"mentions an offset or fuzz factor, you should make sure that the modified "
+"files are correct afterwards."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:679
+msgid ""
+"It's often a good idea to refresh a patch that has applied with an offset or "
+"fuzz factor; refreshing the patch generates new context information that will "
+"make it apply cleanly.  I say <quote>often,</quote> not <quote>always,</"
+"quote> because sometimes refreshing a patch will make it fail to apply "
+"against a different revision of the underlying files.  In some cases, such as "
+"when you're maintaining a patch that must sit on top of multiple versions of "
+"a source tree, it's acceptable to have a patch apply with some fuzz, provided "
+"you've verified the results of the patching process in such cases."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:692
+msgid "Handling rejection"
+msgstr "处理拒绝"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:694
+msgid ""
+"If <command role=\"hg-ext-mq\">qpush</command> fails to apply a patch, it "
+"will print an error message and exit.  If it has left <filename role=\"special"
+"\">.rej</filename> files behind, it is usually best to fix up the rejected "
+"hunks before you push more patches or do any further work."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:700
+msgid ""
+"If your patch <emphasis>used to</emphasis> apply cleanly, and no longer does "
+"because you've changed the underlying code that your patches are based on, "
+"Mercurial Queues can help; see <xref linkend=\"sec:mq:merge\"/> for details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:705
+msgid ""
+"Unfortunately, there aren't any great techniques for dealing with rejected "
+"hunks.  Most often, you'll need to view the <filename role=\"special\">.rej</"
+"filename> file and edit the target file, applying the rejected hunks by hand."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:710
+msgid ""
+"If you're feeling adventurous, Neil Brown, a Linux kernel hacker, wrote a "
+"tool called <command>wiggle</command> <citation>web:wiggle</citation>, which "
+"is more vigorous than <command>patch</command> in its attempts to make a "
+"patch apply."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:716
+msgid ""
+"Another Linux kernel hacker, Chris Mason (the author of Mercurial Queues), "
+"wrote a similar tool called <command>mpatch</command> <citation>web:mpatch</"
+"citation>, which takes a simple approach to automating the application of "
+"hunks rejected by <command>patch</command>.  The <command>mpatch</command> "
+"command can help with four common reasons that a hunk may be rejected:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:725
+msgid "The context in the middle of a hunk has changed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:728
+msgid "A hunk is missing some context at the beginning or end."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:731
+msgid ""
+"A large hunk might apply better&emdash;either entirely or in part&emdash;if "
+"it was broken up into smaller hunks."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:735
+msgid ""
+"A hunk removes lines with slightly different content than those currently "
+"present in the file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:739
+msgid ""
+"If you use <command>wiggle</command> or <command>mpatch</command>, you should "
+"be doubly careful to check your results when you're done.  In fact, "
+"<command>mpatch</command> enforces this method of double-checking the tool's "
+"output, by automatically dropping you into a merge program when it has done "
+"its job, so that you can verify its work and finish off any remaining merges."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:751
+msgid "Getting the best performance out of MQ"
+msgstr "MQ 的性能"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:753
+msgid ""
+"MQ is very efficient at handling a large number of patches.  I ran some "
+"performance experiments in mid-2006 for a talk that I gave at the 2006 "
+"EuroPython conference <citation>web:europython</citation>.  I used as my data "
+"set the Linux 2.6.17-mm1 patch series, which consists of 1,738 patches.  I "
+"applied these on top of a Linux kernel repository containing all 27,472 "
+"revisions between Linux 2.6.12-rc2 and Linux 2.6.17."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:762
+msgid ""
+"On my old, slow laptop, I was able to <command role=\"hg-cmd\">hg qpush "
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</option></command> all 1,738 "
+"patches in 3.5 minutes, and <command role=\"hg-cmd\">hg qpop <option role="
+"\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> them all in 30 seconds.  "
+"(On a newer laptop, the time to push all patches dropped to two minutes.)  I "
+"could <command role=\"hg-ext-mq\">qrefresh</command> one of the biggest "
+"patches (which made 22,779 lines of changes to 287 files) in 6.6 seconds."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:773
+msgid ""
+"Clearly, MQ is well suited to working in large trees, but there are a few "
+"tricks you can use to get the best performance of it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:777
+msgid ""
+"First of all, try to <quote>batch</quote> operations together.  Every time "
+"you run <command role=\"hg-ext-mq\">qpush</command> or <command role=\"hg-ext-"
+"mq\">qpop</command>, these commands scan the working directory once to make "
+"sure you haven't made some changes and then forgotten to run <command role="
+"\"hg-ext-mq\">qrefresh</command>.  On a small tree, the time that this scan "
+"takes is unnoticeable.  However, on a medium-sized tree (containing tens of "
+"thousands of files), it can take a second or more."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:788
+msgid ""
+"The <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-mq"
+"\">qpop</command> commands allow you to push and pop multiple patches at a "
+"time.  You can identify the <quote>destination patch</quote> that you want to "
+"end up at.  When you <command role=\"hg-ext-mq\">qpush</command> with a "
+"destination specified, it will push patches until that patch is at the top of "
+"the applied stack.  When you <command role=\"hg-ext-mq\">qpop</command> to a "
+"destination, MQ will pop patches until the destination patch is at the top."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:798
+msgid ""
+"You can identify a destination patch using either the name of the patch, or "
+"by number.  If you use numeric addressing, patches are counted from zero; "
+"this means that the first patch is zero, the second is one, and so on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:805
+msgid "Updating your patches when the underlying code changes"
+msgstr "当基础代码改变时,更新补丁的方法"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:808
+msgid ""
+"It's common to have a stack of patches on top of an underlying repository "
+"that you don't modify directly.  If you're working on changes to third-party "
+"code, or on a feature that is taking longer to develop than the rate of "
+"change of the code beneath, you will often need to sync up with the "
+"underlying code, and fix up any hunks in your patches that no longer apply.  "
+"This is called <emphasis>rebasing</emphasis> your patch series."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:817
+msgid ""
+"The simplest way to do this is to <command role=\"hg-cmd\">hg qpop <option "
+"role=\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> your patches, then "
+"<command role=\"hg-cmd\">hg pull</command> changes into the underlying "
+"repository, and finally <command role=\"hg-cmd\">hg qpush <option role=\"hg-"
+"ext-mq-cmd-qpop-opt\">hg -a</option></command> your patches again.  MQ will "
+"stop pushing any time it runs across a patch that fails to apply during "
+"conflicts, allowing you to fix your conflicts, <command role=\"hg-ext-mq"
+"\">qrefresh</command> the affected patch, and continue pushing until you have "
+"fixed your entire stack."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:829
+msgid ""
+"This approach is easy to use and works well if you don't expect changes to "
+"the underlying code to affect how well your patches apply. If your patch "
+"stack touches code that is modified frequently or invasively in the "
+"underlying repository, however, fixing up rejected hunks by hand quickly "
+"becomes tiresome."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:836
+msgid ""
+"It's possible to partially automate the rebasing process.  If your patches "
+"apply cleanly against some revision of the underlying repo, MQ can use this "
+"information to help you to resolve conflicts between your patches and a "
+"different revision."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:842
+msgid "The process is a little involved."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:844
+msgid ""
+"To begin, <command role=\"hg-cmd\">hg qpush -a</command> all of your patches "
+"on top of the revision where you know that they apply cleanly."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:848
+msgid ""
+"Save a backup copy of your patch directory using <command role=\"hg-cmd\">hg "
+"qsave <option role=\"hg-ext-mq-cmd-qsave-opt\">hg -e</option> <option role="
+"\"hg-ext-mq-cmd-qsave-opt\">hg -c</option></command>.  This prints the name "
+"of the directory that it has saved the patches in.  It will save the patches "
+"to a directory called <filename role=\"special\" class=\"directory\">.hg/"
+"patches.N</filename>, where <literal>N</literal> is a small integer.  It also "
+"commits a <quote>save changeset</quote> on top of your applied patches; this "
+"is for internal book-keeping, and records the states of the <filename role="
+"\"special\">series</filename> and <filename role=\"special\">status</"
+"filename> files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:862
+msgid ""
+"Use <command role=\"hg-cmd\">hg pull</command> to bring new changes into the "
+"underlying repository.  (Don't run <command role=\"hg-cmd\">hg pull -u</"
+"command>; see below for why.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:867
+msgid ""
+"Update to the new tip revision, using <command role=\"hg-cmd\">hg update "
+"<option role=\"hg-opt-update\">-C</option></command> to override the patches "
+"you have pushed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:872
+msgid ""
+"Merge all patches using <command>hg qpush -m -a</command>.  The <option role="
+"\"hg-ext-mq-cmd-qpush-opt\">-m</option> option to <command role=\"hg-ext-mq"
+"\">qpush</command> tells MQ to perform a three-way merge if the patch fails "
+"to apply."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:880
+msgid ""
+"During the <command role=\"hg-cmd\">hg qpush <option role=\"hg-ext-mq-cmd-"
+"qpush-opt\">hg -m</option></command>, each patch in the <filename role="
+"\"special\">series</filename> file is applied normally.  If a patch applies "
+"with fuzz or rejects, MQ looks at the queue you <command role=\"hg-ext-mq"
+"\">qsave</command>d, and performs a three-way merge with the corresponding "
+"changeset.  This merge uses Mercurial's normal merge machinery, so it may pop "
+"up a GUI merge tool to help you to resolve problems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:890
+msgid ""
+"When you finish resolving the effects of a patch, MQ refreshes your patch "
+"based on the result of the merge."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:893
+msgid ""
+"At the end of this process, your repository will have one extra head from the "
+"old patch queue, and a copy of the old patch queue will be in <filename role="
+"\"special\" class=\"directory\">.hg/patches.N</filename>. You can remove the "
+"extra head using <command role=\"hg-cmd\">hg qpop -a -n patches.N</command> "
+"or <command role=\"hg-cmd\">hg strip</command>.  You can delete <filename "
+"role=\"special\" class=\"directory\">.hg/patches.N</filename> once you are "
+"sure that you no longer need it as a backup."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:905
+msgid "Identifying patches"
+msgstr "标识补丁"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:907
+msgid ""
+"MQ commands that work with patches let you refer to a patch either by using "
+"its name or by a number.  By name is obvious enough; pass the name "
+"<filename>foo.patch</filename> to <command role=\"hg-ext-mq\">qpush</"
+"command>, for example, and it will push patches until <filename>foo.patch</"
+"filename> is applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:914
+msgid ""
+"As a shortcut, you can refer to a patch using both a name and a numeric "
+"offset; <literal>foo.patch-2</literal> means <quote>two patches before "
+"<literal>foo.patch</literal></quote>, while <literal>bar.patch+4</literal> "
+"means <quote>four patches after <literal>bar.patch</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:920
+msgid ""
+"Referring to a patch by index isn't much different.  The first patch printed "
+"in the output of <command role=\"hg-ext-mq\">qseries</command> is patch zero "
+"(yes, it's one of those start-at-zero counting systems); the second is patch "
+"one; and so on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:926
+msgid ""
+"MQ also makes it easy to work with patches when you are using normal "
+"Mercurial commands.  Every command that accepts a changeset ID will also "
+"accept the name of an applied patch.  MQ augments the tags normally in the "
+"repository with an eponymous one for each applied patch.  In addition, the "
+"special tags <literal role=\"tag\">qbase</literal> and <literal role=\"tag"
+"\">qtip</literal> identify the <quote>bottom-most</quote> and topmost applied "
+"patches, respectively."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:936
+msgid ""
+"These additions to Mercurial's normal tagging capabilities make dealing with "
+"patches even more of a breeze."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:939
+msgid "Want to patchbomb a mailing list with your latest series of changes?"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:942
+msgid ""
+"(Don't know what <quote>patchbombing</quote> is? See <xref linkend=\"sec:"
+"hgext:patchbomb\"/>.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:945
+msgid ""
+"Need to see all of the patches since <literal>foo.patch</literal> that have "
+"touched files in a subdirectory of your tree?"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:952
+msgid ""
+"Because MQ makes the names of patches available to the rest of Mercurial "
+"through its normal internal tag machinery, you don't need to type in the "
+"entire name of a patch when you want to identify it by name."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:957
+msgid ""
+"Another nice consequence of representing patch names as tags is that when you "
+"run the <command role=\"hg-cmd\">hg log</command> command, it will display a "
+"patch's name as a tag, simply as part of its normal output.  This makes it "
+"easy to visually distinguish applied patches from underlying <quote>normal</"
+"quote> revisions.  The following example shows a few normal Mercurial "
+"commands in use with applied patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:970
+msgid "Useful things to know about"
+msgstr "其它需要了解的东西"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:972
+msgid ""
+"There are a number of aspects of MQ usage that don't fit tidily into sections "
+"of their own, but that are good to know.  Here they are, in one place."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:977
+msgid ""
+"Normally, when you <command role=\"hg-ext-mq\">qpop</command> a patch and "
+"<command role=\"hg-ext-mq\">qpush</command> it again, the changeset that "
+"represents the patch after the pop/push will have a <emphasis>different "
+"identity</emphasis> than the changeset that represented the hash beforehand.  "
+"See <xref linkend=\"sec:mqref:cmd:qpush\"/> for information as to why this is."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:986
+msgid ""
+"It's not a good idea to <command role=\"hg-cmd\">hg merge</command> changes "
+"from another branch with a patch changeset, at least if you want to maintain "
+"the <quote>patchiness</quote> of that changeset and changesets below it on "
+"the patch stack.  If you try to do this, it will appear to succeed, but MQ "
+"will become confused."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:997
+msgid "Managing patches in a repository"
+msgstr "在版本库管理补丁"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:999
+msgid ""
+"Because MQ's <filename role=\"special\" class=\"directory\">.hg/patches</"
+"filename> directory resides outside a Mercurial repository's working "
+"directory, the <quote>underlying</quote> Mercurial repository knows nothing "
+"about the management or presence of patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1005
+msgid ""
+"This presents the interesting possibility of managing the contents of the "
+"patch directory as a Mercurial repository in its own right.  This can be a "
+"useful way to work.  For example, you can work on a patch for a while, "
+"<command role=\"hg-ext-mq\">qrefresh</command> it, then <command role=\"hg-cmd"
+"\">hg commit</command> the current state of the patch.  This lets you "
+"<quote>roll back</quote> to that version of the patch later on."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1014
+msgid ""
+"You can then share different versions of the same patch stack among multiple "
+"underlying repositories.  I use this when I am developing a Linux kernel "
+"feature.  I have a pristine copy of my kernel sources for each of several CPU "
+"architectures, and a cloned repository under each that contains the patches I "
+"am working on.  When I want to test a change on a different architecture, I "
+"push my current patches to the patch repository associated with that kernel "
+"tree, pop and push all of my patches, and build and test that kernel."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1024
+msgid ""
+"Managing patches in a repository makes it possible for multiple developers to "
+"work on the same patch series without colliding with each other, all on top "
+"of an underlying source base that they may or may not control."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1030
+msgid "MQ support for patch repositories"
+msgstr "MQ 支持补丁版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1032
+msgid ""
+"MQ helps you to work with the <filename role=\"special\" class=\"directory\">."
+"hg/patches</filename> directory as a repository; when you prepare a "
+"repository for working with patches using <command role=\"hg-ext-mq\">qinit</"
+"command>, you can pass the <option role=\"hg-ext-mq-cmd-qinit-opt\">hg -c</"
+"option> option to create the <filename role=\"special\" class=\"directory\">."
+"hg/patches</filename> directory as a Mercurial repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch11-mq.xml:1042
+msgid ""
+"If you forget to use the <option role=\"hg-ext-mq-cmd-qinit-opt\">hg -c</"
+"option> option, you can simply go into the <filename role=\"special\" class="
+"\"directory\">.hg/patches</filename> directory at any time and run <command "
+"role=\"hg-cmd\">hg init</command>.  Don't forget to add an entry for the "
+"<filename role=\"special\">status</filename> file to the <filename role="
+"\"special\">.hgignore</filename> file, though"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch11-mq.xml:1051
+msgid ""
+"(<command role=\"hg-cmd\">hg qinit <option role=\"hg-ext-mq-cmd-qinit-opt"
+"\">hg -c</option></command> does this for you automatically); you "
+"<emphasis>really</emphasis> don't want to manage the <filename role=\"special"
+"\">status</filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1058
+msgid ""
+"As a convenience, if MQ notices that the <filename class=\"directory\">.hg/"
+"patches</filename> directory is a repository, it will automatically <command "
+"role=\"hg-cmd\">hg add</command> every patch that you create and import."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1063
+msgid ""
+"MQ provides a shortcut command, <command role=\"hg-ext-mq\">qcommit</"
+"command>, that runs <command role=\"hg-cmd\">hg commit</command> in the "
+"<filename role=\"special\" class=\"directory\">.hg/patches</filename> "
+"directory.  This saves some bothersome typing."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1069
+msgid ""
+"Finally, as a convenience to manage the patch directory, you can define the "
+"alias <command>mq</command> on Unix systems. For example, on Linux systems "
+"using the <command>bash</command> shell, you can include the following "
+"snippet in your <filename role=\"home\">~/.bashrc</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1078
+msgid ""
+"You can then issue commands of the form <command>mq pull</command> from the "
+"main repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1083
+msgid "A few things to watch out for"
+msgstr "需要注意的事情"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1085
+msgid ""
+"MQ's support for working with a repository full of patches is limited in a "
+"few small respects."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1088
+msgid ""
+"MQ cannot automatically detect changes that you make to the patch directory.  "
+"If you <command role=\"hg-cmd\">hg pull</command>, manually edit, or <command "
+"role=\"hg-cmd\">hg update</command> changes to patches or the <filename role="
+"\"special\">series</filename> file, you will have to <command role=\"hg-cmd"
+"\">hg qpop <option role=\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> "
+"and then <command role=\"hg-cmd\">hg qpush <option role=\"hg-ext-mq-cmd-qpush-"
+"opt\">hg -a</option></command> in the underlying repository to see those "
+"changes show up there.  If you forget to do this, you can confuse MQ's idea "
+"of which patches are applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1104
+msgid "Third party tools for working with patches"
+msgstr "操作补丁的第三方工具"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1106
+msgid ""
+"Once you've been working with patches for a while, you'll find yourself "
+"hungry for tools that will help you to understand and manipulate the patches "
+"you're dealing with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1110
+msgid ""
+"The <command>diffstat</command> command <citation>web:diffstat</citation> "
+"generates a histogram of the modifications made to each file in a patch.  It "
+"provides a good way to <quote>get a sense of</quote> a patch&emdash;which "
+"files it affects, and how much change it introduces to each file and as a "
+"whole.  (I find that it's a good idea to use <command>diffstat</command>'s "
+"<option role=\"cmd-opt-diffstat\">-p</option> option as a matter of course, "
+"as otherwise it will try to do clever things with prefixes of file names that "
+"inevitably confuse at least me.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1124
+msgid ""
+"The <literal role=\"package\">patchutils</literal> package <citation>web:"
+"patchutils</citation> is invaluable. It provides a set of small utilities "
+"that follow the <quote>Unix philosophy;</quote> each does one useful thing "
+"with a patch.  The <literal role=\"package\">patchutils</literal> command I "
+"use most is <command>filterdiff</command>, which extracts subsets from a "
+"patch file.  For example, given a patch that modifies hundreds of files "
+"across dozens of directories, a single invocation of <command>filterdiff</"
+"command> can generate a smaller patch that only touches files whose names "
+"match a particular glob pattern.  See <xref linkend=\"mq-collab:tips:interdiff"
+"\"/> for another example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1140
+msgid "Good ways to work with patches"
+msgstr "操作补丁的好习惯"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1142
+msgid ""
+"Whether you are working on a patch series to submit to a free software or "
+"open source project, or a series that you intend to treat as a sequence of "
+"regular changesets when you're done, you can use some simple techniques to "
+"keep your work well organised."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1148
+msgid ""
+"Give your patches descriptive names.  A good name for a patch might be "
+"<filename>rework-device-alloc.patch</filename>, because it will immediately "
+"give you a hint what the purpose of the patch is.  Long names shouldn't be a "
+"problem; you won't be typing the names often, but you <emphasis>will</"
+"emphasis> be running commands like <command role=\"hg-ext-mq\">qapplied</"
+"command> and <command role=\"hg-ext-mq\">qtop</command> over and over. Good "
+"naming becomes especially important when you have a number of patches to work "
+"with, or if you are juggling a number of different tasks and your patches "
+"only get a fraction of your attention."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1160
+msgid ""
+"Be aware of what patch you're working on.  Use the <command role=\"hg-ext-mq"
+"\">qtop</command> command and skim over the text of your patches "
+"frequently&emdash;for example, using <command role=\"hg-cmd\">hg tip <option "
+"role=\"hg-opt-tip\">-p</option></command>)&emdash;to be sure of where you "
+"stand.  I have several times worked on and <command role=\"hg-ext-mq"
+"\">qrefresh</command>ed a patch other than the one I intended, and it's often "
+"tricky to migrate changes into the right patch after making them in the wrong "
+"one."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1170
+msgid ""
+"For this reason, it is very much worth investing a little time to learn how "
+"to use some of the third-party tools I described in <xref linkend=\"sec:mq:"
+"tools\"/>, particularly <command>diffstat</command> and <command>filterdiff</"
+"command>.  The former will give you a quick idea of what changes your patch "
+"is making, while the latter makes it easy to splice hunks selectively out of "
+"one patch and into another."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1181
+msgid "MQ cookbook"
+msgstr "MQ 手册"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1184
+msgid "Manage <quote>trivial</quote> patches"
+msgstr "管理<quote>琐碎的</quote>补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1186
+msgid ""
+"Because the overhead of dropping files into a new Mercurial repository is so "
+"low, it makes a lot of sense to manage patches this way even if you simply "
+"want to make a few changes to a source tarball that you downloaded."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1191
+msgid ""
+"Begin by downloading and unpacking the source tarball, and turning it into a "
+"Mercurial repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1196
+msgid "Continue by creating a patch stack and making your changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1201
+msgid ""
+"Let's say a few weeks or months pass, and your package author releases a new "
+"version.  First, bring their changes into the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1207
+msgid ""
+"The pipeline starting with <command role=\"hg-cmd\">hg locate</command> above "
+"deletes all files in the working directory, so that <command role=\"hg-cmd"
+"\">hg commit</command>'s <option role=\"hg-opt-commit\">--addremove</option> "
+"option can actually tell which files have really been removed in the newer "
+"version of the source."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1215
+msgid "Finally, you can apply your patches on top of the new tree."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1222
+msgid "Combining entire patches"
+msgstr "组合全部的补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1224
+msgid ""
+"MQ provides a command, <command role=\"hg-ext-mq\">qfold</command> that lets "
+"you combine entire patches.  This <quote>folds</quote> the patches you name, "
+"in the order you name them, into the topmost applied patch, and concatenates "
+"their descriptions onto the end of its description.  The patches that you "
+"fold must be unapplied before you fold them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1232
+msgid ""
+"The order in which you fold patches matters.  If your topmost applied patch "
+"is <literal>foo</literal>, and you <command role=\"hg-ext-mq\">qfold</"
+"command> <literal>bar</literal> and <literal>quux</literal> into it, you will "
+"end up with a patch that has the same effect as if you applied first "
+"<literal>foo</literal>, then <literal>bar</literal>, followed by "
+"<literal>quux</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1243
+msgid "Merging part of one patch into another"
+msgstr "合并补丁的部分内容到其它补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1245
+msgid ""
+"Merging <emphasis>part</emphasis> of one patch into another is more difficult "
+"than combining entire patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1249
+msgid ""
+"If you want to move changes to entire files, you can use <command>filterdiff</"
+"command>'s <option role=\"cmd-opt-filterdiff\">-i</option> and <option role="
+"\"cmd-opt-filterdiff\">-x</option> options to choose the modifications to "
+"snip out of one patch, concatenating its output onto the end of the patch you "
+"want to merge into.  You usually won't need to modify the patch you've merged "
+"the changes from.  Instead, MQ will report some rejected hunks when you "
+"<command role=\"hg-ext-mq\">qpush</command> it (from the hunks you moved into "
+"the other patch), and you can simply <command role=\"hg-ext-mq\">qrefresh</"
+"command> the patch to drop the duplicate hunks."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1262
+msgid ""
+"If you have a patch that has multiple hunks modifying a file, and you only "
+"want to move a few of those hunks, the job becomes more messy, but you can "
+"still partly automate it.  Use <command>lsdiff -nvv</command> to print some "
+"metadata about the patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1270
+msgid "This command prints three different kinds of number:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:1273
+msgid ""
+"(in the first column) a <emphasis>file number</emphasis> to identify each "
+"file modified in the patch;"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:1277
+msgid ""
+"(on the next line, indented) the line number within a modified file where a "
+"hunk starts; and"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:1280
+msgid ""
+"(on the same line) a <emphasis>hunk number</emphasis> to identify that hunk."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1284
+msgid ""
+"You'll have to use some visual inspection, and reading of the patch, to "
+"identify the file and hunk numbers you'll want, but you can then pass them to "
+"to <command>filterdiff</command>'s <option role=\"cmd-opt-filterdiff\">--"
+"files</option> and <option role=\"cmd-opt-filterdiff\">--hunks</option> "
+"options, to select exactly the file and hunk you want to extract."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1292
+msgid ""
+"Once you have this hunk, you can concatenate it onto the end of your "
+"destination patch and continue with the remainder of <xref linkend=\"sec:mq:"
+"combine\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1299
+msgid "Differences between quilt and MQ"
+msgstr "MQ 与 quilt 的区别"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1301
+msgid ""
+"If you are already familiar with quilt, MQ provides a similar command set.  "
+"There are a few differences in the way that it works."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1305
+msgid ""
+"You will already have noticed that most quilt commands have MQ counterparts "
+"that simply begin with a <quote><literal>q</literal></quote>.  The exceptions "
+"are quilt's <literal>add</literal> and <literal>remove</literal> commands, "
+"the counterparts for which are the normal Mercurial <command role=\"hg-cmd"
+"\">hg add</command> and <command role=\"hg-cmd\">hg remove</command> "
+"commands.  There is no MQ equivalent of the quilt <literal>edit</literal> "
+"command."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch12-mq-collab.xml:5
+msgid "Advanced uses of Mercurial Queues"
+msgstr "MQ 的高级用法"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch12-mq-collab.xml:7
+msgid ""
+"While it's easy to pick up straightforward uses of Mercurial Queues, use of a "
+"little discipline and some of MQ's less frequently used capabilities makes it "
+"possible to work in complicated development environments."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch12-mq-collab.xml:12
+msgid ""
+"In this chapter, I will use as an example a technique I have used to manage "
+"the development of an Infiniband device driver for the Linux kernel.  The "
+"driver in question is large (at least as drivers go), with 25,000 lines of "
+"code spread across 35 source files.  It is maintained by a small team of "
+"developers."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch12-mq-collab.xml:18
+msgid ""
+"While much of the material in this chapter is specific to Linux, the same "
+"principles apply to any code base for which you're not the primary owner, and "
+"upon which you need to do a lot of development."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:24
+msgid "The problem of many targets"
+msgstr "多个目标的问题"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:26
+msgid ""
+"The Linux kernel changes rapidly, and has never been internally stable; "
+"developers frequently make drastic changes between releases. This means that "
+"a version of the driver that works well with a particular released version of "
+"the kernel will not even <emphasis>compile</emphasis> correctly against, "
+"typically, any other version."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:33
+msgid ""
+"To maintain a driver, we have to keep a number of distinct versions of Linux "
+"in mind."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:36
+msgid ""
+"One target is the main Linux kernel development tree. Maintenance of the code "
+"is in this case partly shared by other developers in the kernel community, "
+"who make <quote>drive-by</quote> modifications to the driver as they develop "
+"and refine kernel subsystems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:42
+msgid ""
+"We also maintain a number of <quote>backports</quote> to older versions of "
+"the Linux kernel, to support the needs of customers who are running older "
+"Linux distributions that do not incorporate our drivers.  (To "
+"<emphasis>backport</emphasis> a piece of code is to modify it to work in an "
+"older version of its target environment than the version it was developed "
+"for.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:50
+msgid ""
+"Finally, we make software releases on a schedule that is necessarily not "
+"aligned with those used by Linux distributors and kernel developers, so that "
+"we can deliver new features to customers without forcing them to upgrade "
+"their entire kernels or distributions."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch12-mq-collab.xml:58
+msgid "Tempting approaches that don't work well"
+msgstr "工作不好的诱人方法"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:60
+msgid ""
+"There are two <quote>standard</quote> ways to maintain a piece of software "
+"that has to target many different environments."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:64
+msgid ""
+"The first is to maintain a number of branches, each intended for a single "
+"target.  The trouble with this approach is that you must maintain iron "
+"discipline in the flow of changes between repositories. A new feature or bug "
+"fix must start life in a <quote>pristine</quote> repository, then percolate "
+"out to every backport repository.  Backport changes are more limited in the "
+"branches they should propagate to; a backport change that is applied to a "
+"branch where it doesn't belong will probably stop the driver from compiling."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:74
+msgid ""
+"The second is to maintain a single source tree filled with conditional "
+"statements that turn chunks of code on or off depending on the intended "
+"target.  Because these <quote>ifdefs</quote> are not allowed in the Linux "
+"kernel tree, a manual or automatic process must be followed to strip them out "
+"and yield a clean tree.  A code base maintained in this fashion rapidly "
+"becomes a rat's nest of conditional blocks that are difficult to understand "
+"and maintain."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:83
+msgid ""
+"Neither of these approaches is well suited to a situation where you don't "
+"<quote>own</quote> the canonical copy of a source tree.  In the case of a "
+"Linux driver that is distributed with the standard kernel, Linus's tree "
+"contains the copy of the code that will be treated by the world as "
+"canonical.  The upstream version of <quote>my</quote> driver can be modified "
+"by people I don't know, without me even finding out about it until after the "
+"changes show up in Linus's tree."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:93
+msgid ""
+"These approaches have the added weakness of making it difficult to generate "
+"well-formed patches to submit upstream."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:97
+msgid ""
+"In principle, Mercurial Queues seems like a good candidate to manage a "
+"development scenario such as the above.  While this is indeed the case, MQ "
+"contains a few added features that make the job more pleasant."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:105
+msgid "Conditionally applying patches with guards"
+msgstr "有条件的应用补丁"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:107
+msgid ""
+"Perhaps the best way to maintain sanity with so many targets is to be able to "
+"choose specific patches to apply for a given situation.  MQ provides a "
+"feature called <quote>guards</quote> (which originates with quilt's "
+"<literal>guards</literal> command) that does just this.  To start off, let's "
+"create a simple repository for experimenting in."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:116
+msgid ""
+"This gives us a tiny repository that contains two patches that don't have any "
+"dependencies on each other, because they touch different files."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:120
+msgid ""
+"The idea behind conditional application is that you can <quote>tag</quote> a "
+"patch with a <emphasis>guard</emphasis>, which is simply a text string of "
+"your choosing, then tell MQ to select specific guards to use when applying "
+"patches.  MQ will then either apply, or skip over, a guarded patch, depending "
+"on the guards that you have selected."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:127
+msgid ""
+"A patch can have an arbitrary number of guards; each one is "
+"<emphasis>positive</emphasis> (<quote>apply this patch if this guard is "
+"selected</quote>) or <emphasis>negative</emphasis> (<quote>skip this patch if "
+"this guard is selected</quote>).  A patch with no guards is always applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:135
+msgid "Controlling the guards on a patch"
+msgstr "控制补丁的应用条件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:137
+msgid ""
+"The <command role=\"hg-ext-mq\">qguard</command> command lets you determine "
+"which guards should apply to a patch, or display the guards that are already "
+"in effect. Without any arguments, it displays the guards on the current "
+"topmost patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:144
+msgid ""
+"To set a positive guard on a patch, prefix the name of the guard with a "
+"<quote><literal>+</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:149
+msgid ""
+"To set a negative guard on a patch, prefix the name of the guard with a "
+"<quote><literal>-</literal></quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch12-mq-collab.xml:156
+msgid ""
+"The <command role=\"hg-ext-mq\">qguard</command> command <emphasis>sets</"
+"emphasis> the guards on a patch; it doesn't <emphasis>modify</emphasis> "
+"them.  What this means is that if you run <command role=\"hg-cmd\">hg qguard "
+"+a +b</command> on a patch, then <command role=\"hg-cmd\">hg qguard +c</"
+"command> on the same patch, the <emphasis>only</emphasis> guard that will be "
+"set on it afterwards is <literal>+c</literal>."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:165
+msgid ""
+"Mercurial stores guards in the <filename role=\"special\">series</filename> "
+"file; the form in which they are stored is easy both to understand and to "
+"edit by hand. (In other words, you don't have to use the <command role=\"hg-"
+"ext-mq\">qguard</command> command if you don't want to; it's okay to simply "
+"edit the <filename role=\"special\">series</filename> file.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:177
+msgid "Selecting the guards to use"
+msgstr "选择使用的条件"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:179
+msgid ""
+"The <command role=\"hg-ext-mq\">qselect</command> command determines which "
+"guards are active at a given time.  The effect of this is to determine which "
+"patches MQ will apply the next time you run <command role=\"hg-ext-mq"
+"\">qpush</command>.  It has no other effect; in particular, it doesn't do "
+"anything to patches that are already applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:186
+msgid ""
+"With no arguments, the <command role=\"hg-ext-mq\">qselect</command> command "
+"lists the guards currently in effect, one per line of output.  Each argument "
+"is treated as the name of a guard to apply."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:193
+msgid ""
+"In case you're interested, the currently selected guards are stored in the "
+"<filename role=\"special\">guards</filename> file."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:198
+msgid ""
+"We can see the effect the selected guards have when we run <command role=\"hg-"
+"ext-mq\">qpush</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:203
+msgid ""
+"A guard cannot start with a <quote><literal>+</literal></quote> or "
+"<quote><literal>-</literal></quote> character.  The name of a guard must not "
+"contain white space, but most other characters are acceptable.  If you try to "
+"use a guard with an invalid name, MQ will complain:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:212
+msgid "Changing the selected guards changes the patches that are applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:217
+msgid ""
+"You can see in the example below that negative guards take precedence over "
+"positive guards."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:224
+msgid "MQ's rules for applying patches"
+msgstr "MQ 应用补丁的规则"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:226
+msgid ""
+"The rules that MQ uses when deciding whether to apply a patch are as follows."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:229
+msgid "A patch that has no guards is always applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:232
+msgid ""
+"If the patch has any negative guard that matches any currently selected "
+"guard, the patch is skipped."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:235
+msgid ""
+"If the patch has any positive guard that matches any currently selected "
+"guard, the patch is applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:238
+msgid ""
+"If the patch has positive or negative guards, but none matches any currently "
+"selected guard, the patch is skipped."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:245
+msgid "Trimming the work environment"
+msgstr "修剪工作环境"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:247
+msgid ""
+"In working on the device driver I mentioned earlier, I don't apply the "
+"patches to a normal Linux kernel tree.  Instead, I use a repository that "
+"contains only a snapshot of the source files and headers that are relevant to "
+"Infiniband development.  This repository is 1% the size of a kernel "
+"repository, so it's easier to work with."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:254
+msgid ""
+"I then choose a <quote>base</quote> version on top of which the patches are "
+"applied.  This is a snapshot of the Linux kernel tree as of a revision of my "
+"choosing.  When I take the snapshot, I record the changeset ID from the "
+"kernel repository in the commit message.  Since the snapshot preserves the "
+"<quote>shape</quote> and content of the relevant parts of the kernel tree, I "
+"can apply my patches on top of either my tiny repository or a normal kernel "
+"tree."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:263
+msgid ""
+"Normally, the base tree atop which the patches apply should be a snapshot of "
+"a very recent upstream tree.  This best facilitates the development of "
+"patches that can easily be submitted upstream with few or no modifications."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:270
+msgid "Dividing up the <filename role=\"special\">series</filename> file"
+msgstr "分类补丁<filename role=\"special\">系列</filename>"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:273
+msgid ""
+"I categorise the patches in the <filename role=\"special\">series</filename> "
+"file into a number of logical groups.  Each section of like patches begins "
+"with a block of comments that describes the purpose of the patches that "
+"follow."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:279
+msgid ""
+"The sequence of patch groups that I maintain follows.  The ordering of these "
+"groups is important; I'll describe why after I introduce the groups."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:283
+msgid ""
+"The <quote>accepted</quote> group.  Patches that the development team has "
+"submitted to the maintainer of the Infiniband subsystem, and which he has "
+"accepted, but which are not present in the snapshot that the tiny repository "
+"is based on.  These are <quote>read only</quote> patches, present only to "
+"transform the tree into a similar state as it is in the upstream maintainer's "
+"repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:291
+msgid ""
+"The <quote>rework</quote> group.  Patches that I have submitted, but that the "
+"upstream maintainer has requested modifications to before he will accept them."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:296
+msgid ""
+"The <quote>pending</quote> group.  Patches that I have not yet submitted to "
+"the upstream maintainer, but which we have finished working on. These will be "
+"<quote>read only</quote> for a while.  If the upstream maintainer accepts "
+"them upon submission, I'll move them to the end of the <quote>accepted</"
+"quote> group.  If he requests that I modify any, I'll move them to the "
+"beginning of the <quote>rework</quote> group."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:305
+msgid ""
+"The <quote>in progress</quote> group.  Patches that are actively being "
+"developed, and should not be submitted anywhere yet."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:309
+msgid ""
+"The <quote>backport</quote> group.  Patches that adapt the source tree to "
+"older versions of the kernel tree."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:313
+msgid ""
+"The <quote>do not ship</quote> group.  Patches that for some reason should "
+"never be submitted upstream.  For example, one such patch might change "
+"embedded driver identification strings to make it easier to distinguish, in "
+"the field, between an out-of-tree version of the driver and a version shipped "
+"by a distribution vendor."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:321
+msgid ""
+"Now to return to the reasons for ordering groups of patches in this way.  We "
+"would like the lowest patches in the stack to be as stable as possible, so "
+"that we will not need to rework higher patches due to changes in context.  "
+"Putting patches that will never be changed first in the <filename role="
+"\"special\">series</filename> file serves this purpose."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:329
+msgid ""
+"We would also like the patches that we know we'll need to modify to be "
+"applied on top of a source tree that resembles the upstream tree as closely "
+"as possible.  This is why we keep accepted patches around for a while."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:334
+msgid ""
+"The <quote>backport</quote> and <quote>do not ship</quote> patches float at "
+"the end of the <filename role=\"special\">series</filename> file.  The "
+"backport patches must be applied on top of all other patches, and the "
+"<quote>do not ship</quote> patches might as well stay out of harm's way."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:343
+msgid "Maintaining the patch series"
+msgstr "维护补丁系列"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:345
+msgid ""
+"In my work, I use a number of guards to control which patches are to be "
+"applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:349
+msgid ""
+"<quote>Accepted</quote> patches are guarded with <literal>accepted</"
+"literal>.  I enable this guard most of the time.  When I'm applying the "
+"patches on top of a tree where the patches are already present, I can turn "
+"this patch off, and the patches that follow it will apply cleanly."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:356
+msgid ""
+"Patches that are <quote>finished</quote>, but not yet submitted, have no "
+"guards.  If I'm applying the patch stack to a copy of the upstream tree, I "
+"don't need to enable any guards in order to get a reasonably safe source tree."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:362
+msgid ""
+"Those patches that need reworking before being resubmitted are guarded with "
+"<literal>rework</literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:366
+msgid ""
+"For those patches that are still under development, I use <literal>devel</"
+"literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch12-mq-collab.xml:369
+msgid ""
+"A backport patch may have several guards, one for each version of the kernel "
+"to which it applies.  For example, a patch that backports a piece of code to "
+"2.6.9 will have a <literal>2.6.9</literal> guard."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch12-mq-collab.xml:374
+msgid ""
+"This variety of guards gives me considerable flexibility in determining what "
+"kind of source tree I want to end up with.  For most situations, the "
+"selection of appropriate guards is automated during the build process, but I "
+"can manually tune the guards to use for less common circumstances."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch12-mq-collab.xml:381
+msgid "The art of writing backport patches"
+msgstr "编写向后移植补丁的艺术"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:383
+msgid ""
+"Using MQ, writing a backport patch is a simple process.  All such a patch has "
+"to do is modify a piece of code that uses a kernel feature not present in the "
+"older version of the kernel, so that the driver continues to work correctly "
+"under that older version."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:389
+msgid ""
+"A useful goal when writing a good backport patch is to make your code look as "
+"if it was written for the older version of the kernel you're targeting.  The "
+"less obtrusive the patch, the easier it will be to understand and maintain.  "
+"If you're writing a collection of backport patches to avoid the <quote>rat's "
+"nest</quote> effect of lots of <literal>#ifdef</literal>s (hunks of source "
+"code that are only used conditionally) in your code, don't introduce version-"
+"dependent <literal>#ifdef</literal>s into the patches.  Instead, write "
+"several patches, each of which makes unconditional changes, and control their "
+"application using guards."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:402
+msgid ""
+"There are two reasons to divide backport patches into a distinct group, away "
+"from the <quote>regular</quote> patches whose effects they modify. The first "
+"is that intermingling the two makes it more difficult to use a tool like the "
+"<literal role=\"hg-ext\">patchbomb</literal> extension to automate the "
+"process of submitting the patches to an upstream maintainer.  The second is "
+"that a backport patch could perturb the context in which a subsequent regular "
+"patch is applied, making it impossible to apply the regular patch cleanly "
+"<emphasis>without</emphasis> the earlier backport patch already being applied."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch12-mq-collab.xml:417
+msgid "Useful tips for developing with MQ"
+msgstr "使用 MQ 开发的技巧"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch12-mq-collab.xml:420
+msgid "Organising patches in directories"
+msgstr "将补丁放到几个目录中"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:422
+msgid ""
+"If you're working on a substantial project with MQ, it's not difficult to "
+"accumulate a large number of patches.  For example, I have one patch "
+"repository that contains over 250 patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:427
+msgid ""
+"If you can group these patches into separate logical categories, you can if "
+"you like store them in different directories; MQ has no problems with patch "
+"names that contain path separators."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch12-mq-collab.xml:434
+msgid "Viewing the history of a patch"
+msgstr "察看补丁的历史"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:436
+msgid ""
+"If you're developing a set of patches over a long time, it's a good idea to "
+"maintain them in a repository, as discussed in <xref linkend=\"sec:mq:repo\"/"
+">.  If you do so, you'll quickly discover that using the <command role=\"hg-"
+"cmd\">hg diff</command> command to look at the history of changes to a patch "
+"is unworkable.  This is in part because you're looking at the second "
+"derivative of the real code (a diff of a diff), but also because MQ adds "
+"noise to the process by modifying time stamps and directory names when it "
+"updates a patch."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:448
+msgid ""
+"However, you can use the <literal role=\"hg-ext\">extdiff</literal> "
+"extension, which is bundled with Mercurial, to turn a diff of two versions of "
+"a patch into something readable.  To do this, you will need a third-party "
+"package called <literal role=\"package\">patchutils</literal> <citation>web:"
+"patchutils</citation>.  This provides a command named <command>interdiff</"
+"command>, which shows the differences between two diffs as a diff.  Used on "
+"two versions of the same diff, it generates a diff that represents the diff "
+"from the first to the second version."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:459
+msgid ""
+"You can enable the <literal role=\"hg-ext\">extdiff</literal> extension in "
+"the usual way, by adding a line to the <literal role=\"rc-extensions"
+"\">extensions</literal> section of your <filename role=\"special\">~/.hgrc</"
+"filename>."
+msgstr ""
+
+#
+#. 	&example.hg-interdiff;
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:466
+msgid ""
+"The <command>interdiff</command> command expects to be passed the names of "
+"two files, but the <literal role=\"hg-ext\">extdiff</literal> extension "
+"passes the program it runs a pair of directories, each of which can contain "
+"an arbitrary number of files.  We thus need a small program that will run "
+"<command>interdiff</command> on each pair of files in these two directories.  "
+"This program is available as <filename role=\"special\">hg-interdiff</"
+"filename> in the <filename class=\"directory\">examples</filename> directory "
+"of the source code repository that accompanies this book."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:478
+msgid ""
+"With the <filename role=\"special\">hg-interdiff</filename> program in your "
+"shell's search path, you can run it as follows, from inside an MQ patch "
+"directory:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:482
+msgid ""
+"Since you'll probably want to use this long-winded command a lot, you can get "
+"<literal role=\"hg-ext\">hgext</literal> to make it available as a normal "
+"Mercurial command, again by editing your <filename role=\"special\">~/.hgrc</"
+"filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:489
+msgid ""
+"This directs <literal role=\"hg-ext\">hgext</literal> to make an "
+"<literal>interdiff</literal> command available, so you can now shorten the "
+"previous invocation of <command role=\"hg-ext-extdiff\">extdiff</command> to "
+"something a little more wieldy."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch12-mq-collab.xml:497
+msgid ""
+"The <command>interdiff</command> command works well only if the underlying "
+"files against which versions of a patch are generated remain the same.  If "
+"you create a patch, modify the underlying files, and then regenerate the "
+"patch, <command>interdiff</command> may not produce useful output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch12-mq-collab.xml:505
+msgid ""
+"The <literal role=\"hg-ext\">extdiff</literal> extension is useful for more "
+"than merely improving the presentation of MQ patches.  To read more about it, "
+"go to <xref linkend=\"sec:hgext:extdiff\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><title>
+#: ../en/ch13-hgext.xml:5
+msgid "Adding functionality with extensions"
+msgstr "使用扩展增加功能"
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch13-hgext.xml:7
+msgid ""
+"While the core of Mercurial is quite complete from a functionality "
+"standpoint, it's deliberately shorn of fancy features.  This approach of "
+"preserving simplicity keeps the software easy to deal with for both "
+"maintainers and users."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch13-hgext.xml:12
+msgid ""
+"However, Mercurial doesn't box you in with an inflexible command set: you can "
+"add features to it as <emphasis>extensions</emphasis> (sometimes known as "
+"<emphasis>plugins</emphasis>).  We've already discussed a few of these "
+"extensions in earlier chapters."
+msgstr ""
+
+#. type: Content of: <book><chapter><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:18
+msgid ""
+"<xref linkend=\"sec:tour-merge:fetch\"/> covers the <literal role=\"hg-ext"
+"\">fetch</literal> extension; this combines pulling new changes and merging "
+"them with local changes into a single command, <command role=\"hg-ext-fetch"
+"\">fetch</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:24
+msgid ""
+"In <xref linkend=\"chap:hook\"/>, we covered several extensions that are "
+"useful for hook-related functionality: <literal role=\"hg-ext\">acl</literal> "
+"adds access control lists; <literal role=\"hg-ext\">bugzilla</literal> adds "
+"integration with the Bugzilla bug tracking system; and <literal role=\"hg-ext"
+"\">notify</literal> sends notification emails on new changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:33
+msgid ""
+"The Mercurial Queues patch management extension is so invaluable that it "
+"merits two chapters and an appendix all to itself. <xref linkend=\"chap:mq\"/"
+"> covers the basics; <xref linkend=\"chap:mq-collab\"/> discusses advanced "
+"topics; and <xref linkend=\"chap:mqref\"/> goes into detail on each command."
+msgstr ""
+
+#. type: Content of: <book><chapter><para>
+#: ../en/ch13-hgext.xml:43
+msgid ""
+"In this chapter, we'll cover some of the other extensions that are available "
+"for Mercurial, and briefly touch on some of the machinery you'll need to know "
+"about if you want to write an extension of your own."
+msgstr ""
+
+#. type: Content of: <book><chapter><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:48
+msgid ""
+"In <xref linkend=\"sec:hgext:inotify\"/>, we'll discuss the possibility of "
+"<emphasis>huge</emphasis> performance improvements using the <literal role="
+"\"hg-ext\">inotify</literal> extension."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch13-hgext.xml:55
+msgid ""
+"Improve performance with the <literal role=\"hg-ext\">inotify</literal> "
+"extension"
+msgstr "使用扩展 <literal role=\"hg-ext\">inotify</literal> 以提高性能"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:58
+msgid ""
+"Are you interested in having some of the most common Mercurial operations run "
+"as much as a hundred times faster? Read on!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:62
+msgid ""
+"Mercurial has great performance under normal circumstances.  For example, "
+"when you run the <command role=\"hg-cmd\">hg status</command> command, "
+"Mercurial has to scan almost every directory and file in your repository so "
+"that it can display file status.  Many other Mercurial commands need to do "
+"the same work behind the scenes; for example, the <command role=\"hg-cmd\">hg "
+"diff</command> command uses the status machinery to avoid doing an expensive "
+"comparison operation on files that obviously haven't changed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:72
+msgid ""
+"Because obtaining file status is crucial to good performance, the authors of "
+"Mercurial have optimised this code to within an inch of its life.  However, "
+"there's no avoiding the fact that when you run <command role=\"hg-cmd\">hg "
+"status</command>, Mercurial is going to have to perform at least one "
+"expensive system call for each managed file to determine whether it's changed "
+"since the last time Mercurial checked.  For a sufficiently large repository, "
+"this can take a long time."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:82
+msgid ""
+"To put a number on the magnitude of this effect, I created a repository "
+"containing 150,000 managed files.  I timed <command role=\"hg-cmd\">hg "
+"status</command> as taking ten seconds to run, even when <emphasis>none</"
+"emphasis> of those files had been modified."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:88
+msgid ""
+"Many modern operating systems contain a file notification facility. If a "
+"program signs up to an appropriate service, the operating system will notify "
+"it every time a file of interest is created, modified, or deleted.  On Linux "
+"systems, the kernel component that does this is called <literal>inotify</"
+"literal>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:95
+msgid ""
+"Mercurial's <literal role=\"hg-ext\">inotify</literal> extension talks to the "
+"kernel's <literal>inotify</literal> component to optimise <command role=\"hg-"
+"cmd\">hg status</command> commands.  The extension has two components.  A "
+"daemon sits in the background and receives notifications from the "
+"<literal>inotify</literal> subsystem.  It also listens for connections from a "
+"regular Mercurial command.  The extension modifies Mercurial's behaviour so "
+"that instead of scanning the filesystem, it queries the daemon.  Since the "
+"daemon has perfect information about the state of the repository, it can "
+"respond with a result instantaneously, avoiding the need to scan every "
+"directory and file in the repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:108
+msgid ""
+"Recall the ten seconds that I measured plain Mercurial as taking to run "
+"<command role=\"hg-cmd\">hg status</command> on a 150,000 file repository.  "
+"With the <literal role=\"hg-ext\">inotify</literal> extension enabled, the "
+"time dropped to 0.1 seconds, a factor of <emphasis>one hundred</emphasis> "
+"faster."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:115
+msgid "Before we continue, please pay attention to some caveats."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:118
+msgid ""
+"The <literal role=\"hg-ext\">inotify</literal> extension is Linux-specific.  "
+"Because it interfaces directly to the Linux kernel's <literal>inotify</"
+"literal> subsystem, it does not work on other operating systems."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:123
+msgid ""
+"It should work on any Linux distribution that was released after early 2005.  "
+"Older distributions are likely to have a kernel that lacks <literal>inotify</"
+"literal>, or a version of <literal>glibc</literal> that does not have the "
+"necessary interfacing support."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:130
+msgid ""
+"Not all filesystems are suitable for use with the <literal role=\"hg-ext"
+"\">inotify</literal> extension.  Network filesystems such as NFS are a non-"
+"starter, for example, particularly if you're running Mercurial on several "
+"systems, all mounting the same network filesystem.  The kernel's "
+"<literal>inotify</literal> system has no way of knowing about changes made on "
+"another system.  Most local filesystems (e.g. ext3, XFS, ReiserFS) should "
+"work fine."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:141
+msgid ""
+"The <literal role=\"hg-ext\">inotify</literal> extension is not yet shipped "
+"with Mercurial as of May 2007, so it's a little more involved to set up than "
+"other extensions.  But the performance improvement is worth it!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:146
+msgid ""
+"The extension currently comes in two parts: a set of patches to the Mercurial "
+"source code, and a library of Python bindings to the <literal>inotify</"
+"literal> subsystem."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch13-hgext.xml:150
+msgid ""
+"There are <emphasis>two</emphasis> Python <literal>inotify</literal> binding "
+"libraries.  One of them is called <literal>pyinotify</literal>, and is "
+"packaged by some Linux distributions as <literal>python-inotify</literal>.  "
+"This is <emphasis>not</emphasis> the one you'll need, as it is too buggy and "
+"inefficient to be practical."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:157
+msgid ""
+"To get going, it's best to already have a functioning copy of Mercurial "
+"installed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><note><para>
+#: ../en/ch13-hgext.xml:160
+msgid ""
+"If you follow the instructions below, you'll be <emphasis>replacing</"
+"emphasis> and overwriting any existing installation of Mercurial that you "
+"might already have, using the latest <quote>bleeding edge</quote> Mercurial "
+"code. Don't say you weren't warned!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:167
+msgid ""
+"Clone the Python <literal>inotify</literal> binding repository.  Build and "
+"install it."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:174
+msgid ""
+"Clone the <filename class=\"directory\">crew</filename> Mercurial "
+"repository.  Clone the <literal role=\"hg-ext\">inotify</literal> patch "
+"repository so that Mercurial Queues will be able to apply patches to your "
+"cope of the <filename class=\"directory\">crew</filename> repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:184
+msgid ""
+"Make sure that you have the Mercurial Queues extension, <literal role=\"hg-ext"
+"\">mq</literal>, enabled.  If you've never used MQ, read <xref linkend=\"sec:"
+"mq:start\"/> to get started quickly."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:190
+msgid ""
+"Go into the <filename class=\"directory\">inotify</filename> repo, and apply "
+"all of the <literal role=\"hg-ext\">inotify</literal> patches using the "
+"<option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</option> option to the "
+"<command role=\"hg-ext-mq\">qpush</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:199
+msgid ""
+"If you get an error message from <command role=\"hg-ext-mq\">qpush</command>, "
+"you should not continue.  Instead, ask for help."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch13-hgext.xml:203
+msgid "Build and install the patched version of Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:209
+msgid ""
+"Once you've build a suitably patched version of Mercurial, all you need to do "
+"to enable the <literal role=\"hg-ext\">inotify</literal> extension is add an "
+"entry to your <filename role=\"special\">~/.hgrc</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:214
+msgid ""
+"When the <literal role=\"hg-ext\">inotify</literal> extension is enabled, "
+"Mercurial will automatically and transparently start the status daemon the "
+"first time you run a command that needs status in a repository.  It runs one "
+"status daemon per repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:220
+msgid ""
+"The status daemon is started silently, and runs in the background.  If you "
+"look at a list of running processes after you've enabled the <literal role="
+"\"hg-ext\">inotify</literal> extension and run a few commands in different "
+"repositories, you'll thus see a few <literal>hg</literal> processes sitting "
+"around, waiting for updates from the kernel and queries from Mercurial."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:228
+msgid ""
+"The first time you run a Mercurial command in a repository when you have the "
+"<literal role=\"hg-ext\">inotify</literal> extension enabled, it will run "
+"with about the same performance as a normal Mercurial command.  This is "
+"because the status daemon needs to perform a normal status scan so that it "
+"has a baseline against which to apply later updates from the kernel.  "
+"However, <emphasis>every</emphasis> subsequent command that does any kind of "
+"status check should be noticeably faster on repositories of even fairly "
+"modest size.  Better yet, the bigger your repository is, the greater a "
+"performance advantage you'll see.  The <literal role=\"hg-ext\">inotify</"
+"literal> daemon makes status operations almost instantaneous on repositories "
+"of all sizes!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:242
+msgid ""
+"If you like, you can manually start a status daemon using the <command role="
+"\"hg-ext-inotify\">inserve</command> command.  This gives you slightly finer "
+"control over how the daemon ought to run.  This command will of course only "
+"be available when the <literal role=\"hg-ext\">inotify</literal> extension is "
+"enabled."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:249
+msgid ""
+"When you're using the <literal role=\"hg-ext\">inotify</literal> extension, "
+"you should notice <emphasis>no difference at all</emphasis> in Mercurial's "
+"behaviour, with the sole exception of status-related commands running a whole "
+"lot faster than they used to.  You should specifically expect that commands "
+"will not print different output; neither should they give different results. "
+"If either of these situations occurs, please report a bug."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch13-hgext.xml:260
+msgid ""
+"Flexible diff support with the <literal role=\"hg-ext\">extdiff</literal> "
+"extension"
+msgstr "使用扩展 <literal role=\"hg-ext\">extdiff</literal> 以扩展差异支持"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:263
+msgid ""
+"Mercurial's built-in <command role=\"hg-cmd\">hg diff</command> command "
+"outputs plaintext unified diffs."
+msgstr ""
+"Mercurial 内置命令 <command role=\"hg-cmd\">hg diff</command> 的输出与统一差异"
+"不同。"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:268
+msgid ""
+"If you would like to use an external tool to display modifications, you'll "
+"want to use the <literal role=\"hg-ext\">extdiff</literal> extension.  This "
+"will let you use, for example, a graphical diff tool."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:273
+msgid ""
+"The <literal role=\"hg-ext\">extdiff</literal> extension is bundled with "
+"Mercurial, so it's easy to set up.  In the <literal role=\"rc-extensions"
+"\">extensions</literal> section of your <filename role=\"special\">~/.hgrc</"
+"filename>, simply add a one-line entry to enable the extension."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:280
+msgid ""
+"This introduces a command named <command role=\"hg-ext-extdiff\">extdiff</"
+"command>, which by default uses your system's <command>diff</command> command "
+"to generate a unified diff in the same form as the built-in <command role="
+"\"hg-cmd\">hg diff</command> command."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:288
+msgid ""
+"The result won't be exactly the same as with the built-in <command role=\"hg-"
+"cmd\">hg diff</command> variations, because the output of <command>diff</"
+"command> varies from one system to another, even when passed the same options."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:293
+msgid ""
+"As the <quote><literal>making snapshot</literal></quote> lines of output "
+"above imply, the <command role=\"hg-ext-extdiff\">extdiff</command> command "
+"works by creating two snapshots of your source tree.  The first snapshot is "
+"of the source revision; the second, of the target revision or working "
+"directory.  The <command role=\"hg-ext-extdiff\">extdiff</command> command "
+"generates these snapshots in a temporary directory, passes the name of each "
+"directory to an external diff viewer, then deletes the temporary directory.  "
+"For efficiency, it only snapshots the directories and files that have changed "
+"between the two revisions."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:306
+msgid ""
+"Snapshot directory names have the same base name as your repository. If your "
+"repository path is <filename class=\"directory\">/quux/bar/foo</filename>, "
+"then <filename class=\"directory\">foo</filename> will be the name of each "
+"snapshot directory.  Each snapshot directory name has its changeset ID "
+"appended, if appropriate.  If a snapshot is of revision "
+"<literal>a631aca1083f</literal>, the directory will be named <filename class="
+"\"directory\">foo.a631aca1083f</filename>.  A snapshot of the working "
+"directory won't have a changeset ID appended, so it would just be <filename "
+"class=\"directory\">foo</filename> in this example.  To see what this looks "
+"like in practice, look again at the <command role=\"hg-ext-extdiff\">extdiff</"
+"command> example above.  Notice that the diff has the snapshot directory "
+"names embedded in its header."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:322
+msgid ""
+"The <command role=\"hg-ext-extdiff\">extdiff</command> command accepts two "
+"important options. The <option role=\"hg-ext-extdiff-cmd-extdiff-opt\">hg -p</"
+"option> option lets you choose a program to view differences with, instead of "
+"<command>diff</command>.  With the <option role=\"hg-ext-extdiff-cmd-extdiff-"
+"opt\">hg -o</option> option, you can change the options that <command role="
+"\"hg-ext-extdiff\">extdiff</command> passes to the program (by default, these "
+"options are <quote><literal>-Npru</literal></quote>, which only make sense if "
+"you're running <command>diff</command>).  In other respects, the <command "
+"role=\"hg-ext-extdiff\">extdiff</command> command acts similarly to the built-"
+"in <command role=\"hg-cmd\">hg diff</command> command: you use the same "
+"option names, syntax, and arguments to specify the revisions you want, the "
+"files you want, and so on."
+msgstr ""
+
+#
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:339
+msgid ""
+"As an example, here's how to run the normal system <command>diff</command> "
+"command, getting it to generate context diffs (using the <option role=\"cmd-"
+"opt-diff\">-c</option> option)  instead of unified diffs, and five lines of "
+"context instead of the default three (passing <literal>5</literal> as the "
+"argument to the <option role=\"cmd-opt-diff\">-C</option> option)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:348
+msgid ""
+"Launching a visual diff tool is just as easy.  Here's how to launch the "
+"<command>kdiff3</command> viewer."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:352
+msgid ""
+"If your diff viewing command can't deal with directories, you can easily work "
+"around this with a little scripting.  For an example of such scripting in "
+"action with the <literal role=\"hg-ext\">mq</literal> extension and the "
+"<command>interdiff</command> command, see <xref linkend=\"mq-collab:tips:"
+"interdiff\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch13-hgext.xml:360
+msgid "Defining command aliases"
+msgstr "定义命令的别名"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch13-hgext.xml:362
+msgid ""
+"It can be cumbersome to remember the options to both the <command role=\"hg-"
+"ext-extdiff\">extdiff</command> command and the diff viewer you want to use, "
+"so the <literal role=\"hg-ext\">extdiff</literal> extension lets you define "
+"<emphasis>new</emphasis> commands that will invoke your diff viewer with "
+"exactly the right options."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch13-hgext.xml:369
+msgid ""
+"All you need to do is edit your <filename role=\"special\">~/.hgrc</"
+"filename>, and add a section named <literal role=\"rc-extdiff\">extdiff</"
+"literal>.  Inside this section, you can define multiple commands.  Here's how "
+"to add a <literal>kdiff3</literal> command.  Once you've defined this, you "
+"can type <quote><literal>hg kdiff3</literal></quote> and the <literal role="
+"\"hg-ext\">extdiff</literal> extension will run <command>kdiff3</command> for "
+"you."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch13-hgext.xml:379
+msgid ""
+"If you leave the right hand side of the definition empty, as above, the "
+"<literal role=\"hg-ext\">extdiff</literal> extension uses the name of the "
+"command you defined as the name of the external program to run.  But these "
+"names don't have to be the same.  Here, we define a command named "
+"<quote><literal>hg wibble</literal></quote>, which runs <command>kdiff3</"
+"command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch13-hgext.xml:389
+msgid ""
+"You can also specify the default options that you want to invoke your diff "
+"viewing program with.  The prefix to use is <quote><literal>opts.</literal></"
+"quote>, followed by the name of the command to which the options apply.  This "
+"example defines a <quote><literal>hg vimdiff</literal></quote> command that "
+"runs the <command>vim</command> editor's <literal>DirDiff</literal> extension."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch13-hgext.xml:403
+msgid ""
+"Cherrypicking changes with the <literal role=\"hg-ext\">transplant</literal> "
+"extension"
+msgstr "使用扩展 <literal role=\"hg-ext\">transplant</literal> 以挑选修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:406
+msgid "Need to have a long chat with Brendan about this."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch13-hgext.xml:410
+msgid ""
+"Send changes via email with the <literal role=\"hg-ext\">patchbomb</literal> "
+"extension"
+msgstr ""
+"使用扩展 <literal role=\"hg-ext\">patchbomb</literal> 通过 email 发送修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:413
+msgid ""
+"Many projects have a culture of <quote>change review</quote>, in which people "
+"send their modifications to a mailing list for others to read and comment on "
+"before they commit the final version to a shared repository.  Some projects "
+"have people who act as gatekeepers; they apply changes from other people to a "
+"repository to which those others don't have access."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:421
+msgid ""
+"Mercurial makes it easy to send changes over email for review or application, "
+"via its <literal role=\"hg-ext\">patchbomb</literal> extension.  The "
+"extension is so named because changes are formatted as patches, and it's "
+"usual to send one changeset per email message.  Sending a long series of "
+"changes by email is thus much like <quote>bombing</quote> the recipient's "
+"inbox, hence <quote>patchbomb</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:429
+msgid ""
+"As usual, the basic configuration of the <literal role=\"hg-ext\">patchbomb</"
+"literal> extension takes just one or two lines in your <filename role="
+"\"special\"> /.hgrc</filename>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:435
+msgid ""
+"Once you've enabled the extension, you will have a new command available, "
+"named <command role=\"hg-ext-patchbomb\">email</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:439
+msgid ""
+"The safest and best way to invoke the <command role=\"hg-ext-patchbomb"
+"\">email</command> command is to <emphasis>always</emphasis> run it first "
+"with the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -n</option> "
+"option.  This will show you what the command <emphasis>would</emphasis> send, "
+"without actually sending anything.  Once you've had a quick glance over the "
+"changes and verified that you are sending the right ones, you can rerun the "
+"same command, with the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -n</"
+"option> option removed."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:450
+msgid ""
+"The <command role=\"hg-ext-patchbomb\">email</command> command accepts the "
+"same kind of revision syntax as every other Mercurial command.  For example, "
+"this command will send every revision between 7 and <literal>tip</literal>, "
+"inclusive."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:455
+msgid ""
+"You can also specify a <emphasis>repository</emphasis> to compare with.  If "
+"you provide a repository but no revisions, the <command role=\"hg-ext-"
+"patchbomb\">email</command> command will send all revisions in the local "
+"repository that are not present in the remote repository.  If you "
+"additionally specify revisions or a branch name (the latter using the <option "
+"role=\"hg-ext-patchbomb-cmd-email-opt\">hg -b</option> option), this will "
+"constrain the revisions sent."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:464
+msgid ""
+"It's perfectly safe to run the <command role=\"hg-ext-patchbomb\">email</"
+"command> command without the names of the people you want to send to: if you "
+"do this, it will just prompt you for those values interactively.  (If you're "
+"using a Linux or Unix-like system, you should have enhanced "
+"<literal>readline</literal>-style editing capabilities when entering those "
+"headers, too, which is useful.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:472
+msgid ""
+"When you are sending just one revision, the <command role=\"hg-ext-patchbomb"
+"\">email</command> command will by default use the first line of the "
+"changeset description as the subject of the single email message it sends."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch13-hgext.xml:477
+msgid ""
+"If you send multiple revisions, the <command role=\"hg-ext-patchbomb\">email</"
+"command> command will usually send one message per changeset.  It will "
+"preface the series with an introductory message, in which you should describe "
+"the purpose of the series of changes you're sending."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch13-hgext.xml:484
+msgid "Changing the behaviour of patchbombs"
+msgstr "修改 patchbomb 的行为"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch13-hgext.xml:486
+msgid ""
+"Not every project has exactly the same conventions for sending changes in "
+"email; the <literal role=\"hg-ext\">patchbomb</literal> extension tries to "
+"accommodate a number of variations through command line options."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:492
+msgid ""
+"You can write a subject for the introductory message on the command line "
+"using the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -s</option> "
+"option.  This takes one argument, the text of the subject to use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:498
+msgid ""
+"To change the email address from which the messages originate, use the "
+"<option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -f</option> option.  This "
+"takes one argument, the email address to use."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:504
+msgid ""
+"The default behaviour is to send unified diffs (see <xref linkend=\"sec:mq:"
+"patch\"/> for a description of the format), one per message.  You can send a "
+"binary bundle instead with the <option role=\"hg-ext-patchbomb-cmd-email-opt"
+"\">hg -b</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:512
+msgid ""
+"Unified diffs are normally prefaced with a metadata header.  You can omit "
+"this, and send unadorned diffs, with the <option role=\"hg-ext-patchbomb-cmd-"
+"email-opt\">hg --plain</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:518
+msgid ""
+"Diffs are normally sent <quote>inline</quote>, in the same body part as the "
+"description of a patch.  This makes it easiest for the largest number of "
+"readers to quote and respond to parts of a diff, as some mail clients will "
+"only quote the first MIME body part in a message. If you'd prefer to send the "
+"description and the diff in separate body parts, use the <option role=\"hg-"
+"ext-patchbomb-cmd-email-opt\">hg -a</option> option."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:528
+msgid ""
+"Instead of sending mail messages, you can write them to an <literal>mbox</"
+"literal>-format mail folder using the <option role=\"hg-ext-patchbomb-cmd-"
+"email-opt\">hg -m</option> option.  That option takes one argument, the name "
+"of the file to write to."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch13-hgext.xml:535
+msgid ""
+"If you would like to add a <command>diffstat</command>-format summary to each "
+"patch, and one to the introductory message, use the <option role=\"hg-ext-"
+"patchbomb-cmd-email-opt\">hg -d</option> option.  The <command>diffstat</"
+"command> command displays a table containing the name of each file patched, "
+"the number of lines affected, and a histogram showing how much each file is "
+"modified.  This gives readers a qualitative glance at how complex a patch is."
+msgstr ""
--- a/sillybench/sillybench.py	Mon Apr 20 23:50:34 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-#!/usr/bin/python
-#
-# Silly benchmarking program, to give a vague idea of how fast a few
-# tools are on a handful of common operations.
-#
-# Use a fairly big and real source tarball to test with: Firefox
-# 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto
-# 4KB-blocksize ext3).
-
-import csv
-import os
-import shutil
-import sys
-import tempfile
-import time
-import urllib2
-
-url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2'
-
-class CommandFailure(Exception):
-    pass
-
-class rcs(object):
-    def __init__(self):
-        self.logfp = open(self.__class__.__name__ + '.csv', 'w')
-        self.csv = csv.writer(self.logfp)
-
-    def download(self):
-        name = url[url.rfind('/')+1:]
-        path = os.path.join(os.environ['HOME'], name)
-        if not os.path.isfile(path):
-            ofp = open(path + '.part', 'wb')
-            try:
-                ifp = urllib2.urlopen(url)
-                nbytes = ifp.info()['content-length']
-                sys.stdout.write('%s: %s bytes ' % (name, nbytes))
-                sys.stdout.flush()
-                while True:
-                    data = ifp.read(131072)
-                    if not data: break
-                    sys.stdout.write('.')
-                    sys.stdout.flush()
-                    ofp.write(data)
-                del ofp
-                os.rename(path + '.part', path)
-            except:
-                if os.path.exists(path + '.part'):
-                    os.unlink(path + '.part')
-                if os.path.exists(path):
-                    os.unlink(path)
-                raise
-        return path
-
-    def run(self, args, mustsucceed=True):
-        ret = os.spawnvp(os.P_WAIT, args[0], args)
-        if ret < 0:
-            msg = 'killed by signal %d' % (-ret)
-        if ret > 0:
-            msg = 'exited with status %d' % (ret)
-        if ret:
-            if mustsucceed:
-                raise CommandFailure('%s: %s' % (msg, ' '.join(args)))
-            print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args))
-
-    def time(self, *args, **kwargs):
-        start = time.time()
-        self.run(*args, **kwargs)
-        end = time.time()
-        return end - start
-        
-    def logtime(self, name, elapsed, rest=[]):
-        self.log('time:' + name, '%.3f' % elapsed, rest)
-
-    def log(self, name, value, rest=[]):
-        item = (name, value, repr(rest))
-        print ' '.join(item)
-        self.csv.writerow(item)
-        self.logfp.flush()
-
-    def unpack(self):
-        tarball = self.download()
-        t = self.time(['tar', '-C', self.wdir, '-jxf', tarball])
-        self.logtime('internal:untar', t)
-        for name in os.listdir(os.path.join(self.wdir, 'mozilla')):
-            os.rename(os.path.join(self.wdir, 'mozilla', name),
-                      os.path.join(self.wdir, name))
-
-    def cleanup(self):
-        pass
-
-    def add(self, paths):
-        pass
-
-    def commit(self, msg, paths):
-        pass
-
-    def status(self, path):
-        pass
-
-    def remove(self, path):
-        pass
-
-
-class subversion(rcs):
-    def __init__(self, root):
-        rcs.__init__(self)
-        self.repo = os.path.join(root, 'repo')
-        self.wdir = os.path.join(root, 'wc')
-        create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo])
-        self.logtime('svn:create', create)
-        co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir])
-        self.logtime('svn:co', co)
-        self.logtime('init', create + co)
-        os.chdir(self.wdir)
-
-    def dropmeta(self, names):
-        return [n for n in names if os.path.basename(n) != '.svn']
-
-    def add(self, paths):
-        t = self.time(['svn', 'add', '-q'] + paths)
-        self.logtime('add %r' % paths, t)
-
-    def commit(self, msg, paths=[]):
-        if paths:
-            t = self.time(['svn', 'ci', '-q', '-m', msg] + paths)
-        else:
-            t = self.time(['svn', 'ci', '-q', '-m', msg])
-        self.logtime('commit %r' % paths, t)
-
-
-class mercurial(rcs):
-    def __init__(self, root):
-        rcs.__init__(self)
-        self.repo = os.path.join(root, 'repo')
-        self.wdir = self.repo
-        init = self.time(['hg', 'init', self.repo])
-        self.logtime('init', init)
-        os.chdir(self.wdir)
-
-    def dropmeta(self, names):
-        return [n for n in names if os.path.basename(n) != '.hg']
-
-    def add(self, paths):
-        t = self.time(['hg', 'add', '-q'] + paths)
-        self.logtime('add %r' % paths, t)
-
-    def commit(self, msg, paths=[]):
-        if paths:
-            t = self.time(['hg', 'ci', '-q', '-m', msg] + paths)
-        else:
-            t = self.time(['hg', 'ci', '-q', '-m', msg])
-        self.logtime('commit %r' % paths, t)
-
-def benchmark(cls):
-    oldcwd = os.getcwd()
-    root = tempfile.mkdtemp(prefix='sillybench.')
-    try:
-        print 'root', root
-        inst = cls(root)
-        inst.unpack()
-        names = inst.dropmeta(os.listdir('.'))
-        dirs = [n for n in names if os.path.isdir(n)]
-        nondirs = [n for n in names if not os.path.isdir(n)]
-        dirs.sort(key=hash)
-        names.sort(key=hash)
-        for d in dirs[:len(dirs)/2]:
-            inst.add([d])
-            inst.commit('Add %r' % d, [d])
-        inst.add(dirs[len(dirs)/2:] + names)
-        inst.commit('Add remaining dirs and files')
-    finally:
-        print >> sys.stderr, '[cleaning up...]'
-        shutil.rmtree(root)
-        os.chdir(oldcwd)
-
-benchmark(mercurial)
-#benchmark(subversion)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/all-ids.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Prepare an ASCII dump file of all IDs, and the pages in which
+     they live, for loading into a database. Assumes one-level chunked
+     HTML output, with each chunk containing either a chapter or
+     sect1. -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+
+  <xsl:output method="text"/>
+  <xsl:strip-space elements="title"/>
+
+  <xsl:template match="/">
+    <xsl:for-each select="//preface|//chapter|//appendix|//bibliography|//sect1">
+      <xsl:variable name="id">
+        <xsl:choose>
+          <xsl:when test="local-name(.)='sect1'">
+            <xsl:value-of select="../@id"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="@id"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="sectitle">
+        <xsl:value-of select="normalize-space(./title)"/>
+      </xsl:variable>
+      <xsl:for-each select=".//para[@id]|.//programlisting[@id]|.//screen[@id]">
+        <xsl:value-of select="@id"/>
+        <xsl:text>|</xsl:text>
+        <xsl:copy-of select="$id"/>
+        <xsl:text>|</xsl:text>
+        <xsl:copy-of select="$sectitle"/>
+        <xsl:text>&#x0a;</xsl:text>
+      </xsl:for-each>
+    </xsl:for-each>
+  </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/base-html-stylesheet.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,127 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:param name="html.stylesheet">/support/styles.css</xsl:param>
+  <xsl:param name="toc.section.depth">3</xsl:param>
+  <xsl:param name="annotate.toc">0</xsl:param>
+
+  <xsl:param name="generate.id.attributes" select="1"></xsl:param>
+  <xsl:param name="header.rule" select="0"></xsl:param>
+  <xsl:param name="footer.rule" select="0"></xsl:param>
+  <xsl:param name="html.cleanup" select="1"></xsl:param>
+  <xsl:param name="admon.style"><xsl:text></xsl:text></xsl:param>
+  <xsl:param name="admon.graphics" select="1"></xsl:param>
+  <xsl:param name="admon.graphics.path">/support/figs/</xsl:param>
+
+  <xsl:template match="sect1" mode="toc">
+    <xsl:param name="toc-context" select="."/>
+    <xsl:call-template name="subtoc">
+      <xsl:with-param name="toc-context" select="$toc-context"/>
+      <xsl:with-param name="nodes" 
+        select="sect2|refentry|bridgehead[$bridgehead.in.toc != 0]"/>
+    </xsl:call-template>
+  </xsl:template>
+
+  <xsl:template match="sect2" mode="toc">
+    <xsl:param name="toc-context" select="."/>
+
+    <xsl:call-template name="subtoc">
+      <xsl:with-param name="toc-context" select="$toc-context"/>
+      <xsl:with-param name="nodes" 
+        select="sect3|refentry|bridgehead[$bridgehead.in.toc != 0]"/>
+    </xsl:call-template>
+  </xsl:template>
+
+  <!-- Add id attributes to <p> tags. This is mostly a copy of the
+       base XSL. -->
+  <xsl:template name="paragraph">
+    <xsl:param name="class" select="''"/>
+    <xsl:param name="content"/>
+
+    <xsl:variable name="p">
+      <p>
+        <xsl:call-template name="dir"/>
+        <xsl:if test="$class != ''">
+          <xsl:apply-templates select="." mode="class.attribute">
+            <xsl:with-param name="class" select="$class"/>
+          </xsl:apply-templates>
+        </xsl:if>
+        <!-- Here we go. -->
+        <xsl:if test="$generate.id.attributes != 0">
+          <xsl:attribute name="id">
+            <xsl:call-template name="object.id"/>
+          </xsl:attribute>
+        </xsl:if>
+        <xsl:copy-of select="$content"/>
+      </p>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$html.cleanup != 0">
+        <xsl:call-template name="unwrap.p">
+          <xsl:with-param name="p" select="$p"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:copy-of select="$p"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Add id attributes to <programlisting> and <screen> tags. Once
+       again, this is mostly a copy of the base XSL, although rather
+       trimmed down. -->
+  <xsl:template match="programlisting|screen">
+    <xsl:param name="suppress-numbers" select="'0'"/>
+
+    <xsl:call-template name="anchor"/>
+
+    <pre>
+      <!-- Here we go. -->
+      <xsl:if test="$generate.id.attributes != 0">
+        <xsl:attribute name="id">
+          <xsl:call-template name="object.id"/>
+        </xsl:attribute>
+      </xsl:if>
+
+      <xsl:apply-templates select="." mode="class.attribute"/>
+      <xsl:call-template name="apply-highlighting"/>
+    </pre>
+  </xsl:template>
+
+  <!-- The default stylesheet generates a little TOC at the beginning
+       of each qandaset.  Uh, no thanks. -->
+  <xsl:template name="process.qanda.toc"/>
+
+  <xsl:template name="user.header.navigation">
+    <div class="navheader"><h2 class="booktitle"><a href="/">Mercurial: The Definitive Guide</a> <span class="authors">by Bryan O'Sullivan</span></h2></div>
+  </xsl:template>
+
+  <xsl:template name="user.head.content">
+    <link rel="alternate" type="application/atom+xml" title="Comments"
+      href="/feeds/comments/"/>
+    <link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/>
+    <script type="text/javascript" src="/support/jquery-min.js"></script>
+    <script type="text/javascript" src="/support/form.js"></script>
+    <script type="text/javascript" src="/support/hsbook.js"></script>
+  </xsl:template>
+
+  <xsl:template name="user.footer.content">
+    <div class="hgfooter">
+      <p><img src="/support/figs/rss.png"/> Want to stay up to date? Subscribe to the comment feed for <a id="chapterfeed" class="feed" href="/feeds/comments/">this chapter</a>, or the <a class="feed" href="/feeds/comments/">entire book</a>.</p>
+      <p>Copyright 2006, 2007, 2008, 2009 Bryan O'Sullivan.
+      Icons by <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a href="http://mattahan.deviantart.com/">Mattahan</a>.</p>
+    </div>
+  </xsl:template>
+
+  <xsl:template name="user.footer.navigation">
+    <script type="text/javascript">
+    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script>
+    <script type="text/javascript">
+    try {
+    var pageTracker = _gat._getTracker("UA-1805907-5");
+    pageTracker._trackPageview();
+    } catch(err) {}</script>
+  </xsl:template>
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/chunk-stylesheet.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,17 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="system-xsl/html/chunk.xsl"/>
+  <xsl:include href="base-html-stylesheet.xsl"/>
+
+  <!-- PARAMETER REFERENCE:                                         -->
+  <!-- http://docbook.sourceforge.net/release/xsl/current/doc/html/ -->
+
+  <!-- Uncomment this to enable auto-numbering of sections -->
+  <!-- xsl:param name="section.autolabel" select="1" / -->
+  <xsl:param name="chunker.output.encoding">UTF-8</xsl:param>
+  <xsl:param name="use.id.as.filename" select="1"/>
+  <xsl:param name="chunk.first.sections" select="0"/>
+  <xsl:param name="chunk.section.depth" select="0"/>
+  <xsl:param name="chunk.quietly" select="0"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/dtd-profile.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,15 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+  <xsl:import href="system-xsl/profiling/profile.xsl"></xsl:import>
+
+  <!-- For some reason, xsltproc omits the DTD from the file it
+       outputs. Add a sensible one back in, because otherwise xmllint
+       won't validate profiled documents. -->
+
+  <xsl:template match="/">
+    <xsl:text disable-output-escaping="yes"><![CDATA[
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+  ]]></xsl:text>
+    <xsl:apply-templates select="." mode="profile"/>
+  </xsl:template> 
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/en/fo.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+  <xsl:import href="../fo.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'en'"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/en/html-single.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="../html-single.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'en'"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/en/html.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="../html.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'en'"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/fo.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
+
+  <xsl:param name="draft.mode" select="no"/>
+
+  <!-- These extensions are required for table printing and other stuff -->
+  <xsl:param name="use.extensions">1</xsl:param>
+  <xsl:param name="callouts.extension">1</xsl:param>
+  <xsl:param name="linenumbering.extension">1</xsl:param>
+  <xsl:param name="tablecolumns.extension">1</xsl:param>
+  <xsl:param name="textinsert.extension">1</xsl:param>
+
+  <xsl:param name="admon.graphics" select="1" />
+  <xsl:param name="admon.graphics.extension">.png</xsl:param>
+  <xsl:param name="admon.graphics.path">figs/</xsl:param>
+  <xsl:param name="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</xsl:param>
+  <xsl:param name="callout.graphics.path">images/callouts/</xsl:param>
+
+  <xsl:param name="section.autolabel" select="1" />
+  <xsl:param name="section.label.includes.component.label">1</xsl:param>
+
+  <xsl:param name="variablelist.as.blocks" select="1" />        <!-- fo only -->
+  <xsl:param name="hyphenate">false</xsl:param>                 <!-- fo only -->
+  <xsl:param name="paper.type" select="'A4'"></xsl:param>       <!-- fo only -->
+
+  <!-- Default font settings -->
+  <!--
+  <xsl:param name="title.font.family">sans-serif</xsl:param>
+  <xsl:param name="body.font.family">serif</xsl:param>
+  <xsl:param name="sans.font.family">sans-serif</xsl:param>
+  <xsl:param name="dingbat.font.family">serif</xsl:param>
+  <xsl:param name="monospace.font.family">monospace</xsl:param>
+  <xsl:param name="symbol.font.family">Symbol,ZapfDingbats</xsl:param>
+  -->
+
+  <!-- Custom font settings - preferred truetype font -->
+  <xsl:param name="title.font.family">Calibri,sans-serif,SimHei</xsl:param>
+  <xsl:param name="body.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
+  <xsl:param name="sans.font.family">Calibri,sans-serif,SimHei</xsl:param>
+  <xsl:param name="dingbat.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
+  <xsl:param name="monospace.font.family">Courier New,monospace,FangSong</xsl:param>
+
+  <!-- Page related Settings -->
+  <xsl:param name="page.margin.inner">1.5cm</xsl:param>
+  <xsl:param name="page.margin.outer">1.5cm</xsl:param>
+  <xsl:param name="title.margin.left">0pt</xsl:param>
+  <xsl:param name="body.start.indent">24pt</xsl:param>
+  <xsl:param name="body.end.indent">0pt</xsl:param>
+
+  <!-- Breaking long lines -->
+  <xsl:param name="hyphenate.verbatim">0</xsl:param>
+  <xsl:attribute-set name="monospace.verbatim.properties"
+                     use-attribute-sets="verbatim.properties monospace.properties">
+    <xsl:attribute name="wrap-option">wrap</xsl:attribute>
+    <xsl:attribute name="hyphenation-character">&#x25BA;</xsl:attribute>
+  </xsl:attribute-set>
+
+  <!-- Prevent blank pages in output -->
+  <xsl:template name="book.titlepage.before.verso">
+  </xsl:template>
+  <xsl:template name="book.titlepage.verso">
+  </xsl:template>
+  <xsl:template name="book.titlepage.separator">
+  </xsl:template>
+
+  <!-- Colourize links in output -->
+  <xsl:attribute-set name="xref.properties">
+    <xsl:attribute name="color">
+      <xsl:choose>
+        <xsl:when test="self::ulink">blue</xsl:when>
+        <xsl:when test="self::xref">blue</xsl:when>
+        <xsl:when test="self::uri">blue</xsl:when>
+        <xsl:otherwise>red</xsl:otherwise>
+      </xsl:choose>
+    </xsl:attribute>
+  </xsl:attribute-set>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/hgbook.css	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,295 @@
+body
+{
+    background: white;
+    margin: 1in;
+    font-family: Georgia,SimSun,serif;
+}
+
+p, li, ul, ol, dd, dt
+{
+    font-style: normal;
+    font-weight: normal;
+    color: black;
+}
+
+tt, pre
+{
+    font-family: Consolas,KaiTi,FangSong,SimSun,monospace;
+}
+
+a
+{
+    color: blue;
+    text-decoration: underline;
+}    
+
+a:hover 
+{
+    background: rgb(75%,75%,100%);
+    color: blue;
+    text-decoration: underline;
+}
+
+a:visited 
+{
+    color: purple;
+    text-decoration: underline;
+}
+
+img
+{
+    border: none;
+}
+
+h1.title
+{
+    font-size: 250%;
+    font-style: normal;
+    font-weight: bold;
+    color: black;
+}
+
+h2.subtitle
+{
+    font-size: 150%;
+    font-style: italic;
+    color: black;
+}
+
+h2.title
+{
+    font-size: 150%;
+    font-style: normal;
+    font-weight: bold;
+    color: black;
+}
+
+h3.title
+{
+    font-size: 125%;
+    font-style: normal;
+    font-weight: bold;
+    color: black;
+}
+
+h4.title
+{
+    font-size: 100%;
+    font-style: normal;
+    font-weight: bold;
+    color: black;
+}
+
+strong
+{
+    font-weight: normal;
+}
+
+.toc b
+{
+    font-family: Verdana,SimHei,sans-serif;
+    font-size: 120%;
+    font-style: normal;
+    font-weight: bold;
+    color: black;
+}
+
+.title
+{
+    font-family: Verdana,SimHei,sans-serif;
+}
+
+.screen, .programlisting, .structname
+{
+    font-family: Consolas,KaiTi,FangSong,SimSun,monospace;
+    font-style: normal;
+    font-weight: normal;
+}
+
+.userinput
+{
+    font-weight: normal;
+}
+
+.command
+{
+    font-style: italic;
+}
+
+.filename
+{
+    font-family: Georgia,SimSun,serif;
+    font-style: italic;
+}
+
+.figure, .example, .table
+{
+    margin: 0.125in 0.25in;
+}
+
+.figure p.title b, .example p.title b, .table p.title b
+{
+    font-family: Georgia,SimSun,serif;
+    font-size: 80%;
+    font-style: italic;
+    font-weight: normal;
+}
+
+.table table
+{
+    border-width: 1px;
+    border-style: solid;
+    border-color: black;
+    border-spacing: 0;
+    background: rgb(240,240,240);
+}
+
+.table td
+{
+    border: none;
+    border-right: 1px black solid;
+    border-bottom: 1px black solid;
+    padding: 2px;
+}
+
+.table th
+{
+    background: rgb(180,180,180);
+    border: none;
+    border-right: 1px black solid;
+    border-bottom: 1px black solid;
+    padding: 2px;
+}
+
+.table p.title, .figure p.title, .example p.title
+{
+    text-align: left !important;
+    font-size: 100% !important;
+}
+
+.author, .pubdate
+{
+    margin: 0;
+    font-size: 100%;
+    font-style: italic;
+    font-weight: normal;
+    color: black;
+}
+
+.preface div.author, .preface .pubdate
+{
+    font-size: 80%;
+}
+
+.sidebar 
+{
+    border-top: dotted 1px black;
+    border-left: dotted 1px black;
+    border-right: solid 2px black;
+    border-bottom: solid 2px black;
+    background: rgb(240,220,170);
+    padding: 0 0.12in;
+    margin: 0.25in;
+}
+
+.note .programlisting, .note .screen, 
+.tip .programlisting, .tip .screen, 
+.warning .programlisting, .warning .screen, 
+.sidebar .programlisting, .sidebar .screen
+{
+    border: none;
+    background: none;
+}
+
+.sidebar p.title
+{
+    text-align: center;
+    font-size: 125%;
+}
+
+.note, .tip, .warning
+{
+    border: black solid 1px;
+    margin: 0.125in 0;
+    padding: 0 55px;
+    font-size: 90%;
+}
+
+/*
+.note
+{
+    background: url(./figs/note.png) no-repeat rgb(252,246,220);
+}
+
+.tip
+{
+    background: url(./figs/tip.png) no-repeat rgb(224,244,255);
+}
+
+.warning
+{
+    background: url(./figs/warning.png) no-repeat rgb(255,210,210);
+}
+*/
+
+.note .title, .tip .title, .warning .title
+{
+    display: none;
+}
+
+.programlisting, .screen
+{
+    font-size: 90%;
+    color: black;
+    margin: 1em 0.25in;
+    padding: 0.5em;
+    background: rgb(240,240,240);
+    border-top: black dotted 1px;
+    border-left: black dotted 1px;
+    border-right: black solid 2px;
+    border-bottom: black solid 2px;
+}
+
+.navheader, .navfooter
+{
+    border: black solid 1px;
+    background: rgb(180,180,200);
+}
+
+.navheader hr, .navfooter hr
+{
+    display: none;
+}
+
+#svn-footer
+{
+    font-size: 80%;
+    text-align: center;
+}
+
+#svn-footer hr
+{
+    display: none;
+}
+
+/* --------------------- */
+/* PRINT MEDIA OVERRIDES */
+/* --------------------- */
+
+@media print
+{
+    body 
+    {
+        margin: 0;
+    }
+
+    .navheader, .navfooter
+    {
+        display: none;
+    }
+
+    #svn-footer hr
+    {
+        display: block;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/html-single.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+
+  <xsl:param name="draft.mode" select="no"/>
+
+  <!-- xsltproc can't support these extensions
+  <xsl:param name="use.extensions">1</xsl:param>
+  <xsl:param name="callouts.extension">1</xsl:param>
+  <xsl:param name="linenumbering.extension">1</xsl:param>
+  <xsl:param name="tablecolumns.extension">1</xsl:param>
+  <xsl:param name="textinsert.extension">1</xsl:param>
+  -->
+
+  <xsl:param name="admon.graphics" select="1" />
+  <xsl:param name="admon.graphics.extension">.png</xsl:param>
+  <xsl:param name="admon.graphics.path">figs/</xsl:param>
+  <xsl:param name="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</xsl:param>
+  <xsl:param name="callout.graphics.path">images/callouts/</xsl:param>
+
+  <xsl:param name="section.autolabel" select="1" />
+  <xsl:param name="section.label.includes.component.label">1</xsl:param>
+
+  <xsl:output method="html" encoding="utf-8" indent="yes"/>     <!-- html only -->
+  <xsl:param name="use.id.as.filename">0</xsl:param>            <!-- html only -->
+  <xsl:param name="chunk.section.depth">0</xsl:param>           <!-- html only -->
+  <xsl:param name="chunker.output.indent">yes</xsl:param>       <!-- html only -->
+  <xsl:param name="html.stylesheet">hgbook.css</xsl:param>      <!-- html only -->
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/html.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
+
+  <xsl:param name="draft.mode" select="no"/>
+
+  <!-- xsltproc can't support these extensions
+  <xsl:param name="use.extensions">1</xsl:param>
+  <xsl:param name="callouts.extension">1</xsl:param>
+  <xsl:param name="linenumbering.extension">1</xsl:param>
+  <xsl:param name="tablecolumns.extension">1</xsl:param>
+  <xsl:param name="textinsert.extension">1</xsl:param>
+  -->
+
+  <xsl:param name="admon.graphics" select="1" />
+  <xsl:param name="admon.graphics.extension">.png</xsl:param>
+  <xsl:param name="admon.graphics.path">figs/</xsl:param>
+  <xsl:param name="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</xsl:param>
+  <xsl:param name="callout.graphics.path">images/callouts/</xsl:param>
+
+  <xsl:param name="section.autolabel" select="1" />
+  <xsl:param name="section.label.includes.component.label">1</xsl:param>
+
+  <xsl:output method="html" encoding="utf-8" indent="yes"/>     <!-- html only -->
+  <xsl:param name="chunker.output.encoding" select="'utf-8'"/>  <!-- html only -->
+  <xsl:param name="chunker.output.indent" select="'yes'"/>      <!-- html only -->
+  <xsl:param name="use.id.as.filename">0</xsl:param>            <!-- html only -->
+  <xsl:param name="chunk.section.depth">0</xsl:param>           <!-- html only -->
+  <xsl:param name="chunker.output.indent">yes</xsl:param>       <!-- html only -->
+  <xsl:param name="html.stylesheet">hgbook.css</xsl:param>      <!-- html only -->
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/zh/fo.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                version='1.0'>
+
+  <xsl:import href="../fo.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'zh'"/>
+
+  <!-- Chinese font related settings -->
+  <xsl:param name="body.font.master">12</xsl:param>
+
+  <xsl:attribute-set name="standard.para.spacing" use-attribute-sets="normal.para.spacing">
+    <xsl:attribute name="text-indent">24pt</xsl:attribute>
+  </xsl:attribute-set>
+
+  <xsl:template match="abstract/para|appendix/para|chapter/para|colophon/para|legalnotice/para|preface/para|section/para|sect1/para|sect2/para">
+    <fo:block xsl:use-attribute-sets="standard.para.spacing">
+      <xsl:call-template name="anchor"/>
+      <xsl:apply-templates/>
+    </fo:block>
+  </xsl:template>
+
+  <xsl:template match="section/para/*">
+    <fo:wrapper text-indent="0pt">
+      <xsl:apply-imports/>
+    </fo:wrapper>
+  </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/zh/html-single.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="../html-single.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'zh'"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/zh/html.xsl	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+
+  <xsl:import href="../html.xsl"/>
+
+  <xsl:param name="l10n.gentext.language" select="'zh'"/>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/README	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,5 @@
+This directory contains web-related files.  Surprise!
+
+javascript - files used by the comment system, based on jQuery
+hgbook     - Django app that acts as the comment back end
+styles.css - style file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/genindex.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+import glob, os, re
+
+chapter_re = re.compile(r'<(chapter|appendix|preface)\s+id="([^"]+)">')
+filename_re = re.compile(r'<\?dbhtml filename="([^"]+)"\?>')
+title_re = re.compile(r'<title>(.*)</title>')
+
+chapters = glob.glob('../en/ch*.xml') + glob.glob('../en/app*.xml')
+
+fp = open('index-read.html.in', 'w')
+
+print >> fp, '''<!-- -*- html -*- -->
+{% extends "boilerplate.html" %}
+{% block bodycontent %}
+<div class="navheader"><h1 class="booktitle">Mercurial: The Definitive Guide<div class="authors">by Bryan O'Sullivan</div></h1></div>
+<div class="book"><ul class="booktoc">'''
+
+ch = 0
+app = 0
+ab = 0
+for c in chapters:
+    filename = None
+    title = None
+    chapid = None
+    chaptype = None
+    for line in open(c):
+        m = chapter_re.search(line)
+        if m:
+            chaptype, chapid = m.groups()
+        m = filename_re.search(line)
+        if m:
+            filename = m.group(1)
+        m = title_re.search(line)
+        if m:
+            title = m.group(1)
+        if filename and title and chapid:
+            if chaptype == 'appendix':
+                num = chr(ord('A') + app)
+                app += 1
+            else:
+                num = ch
+                ch += 1
+            ab += 1
+            date = os.popen('hg log -l1 --template "{date|isodate}" ' + c).read().split(None, 1)[0]
+            args = {
+                'ab': "ab"[ab % 2],
+                'date': date,
+                'chapid': chapid,
+                'num': num,
+                'filename': filename,
+                'title': title,
+                }
+            print >> fp, '<li class="zebra_%(ab)s"><span class="chapinfo">%(date)s<a href="/feeds/comments/%(chapid)s/"><img src="/support/figs/rss.png"/></a></span>%(num)s. <a href="%(filename)s">%(title)s</a></li>' % args
+            break
+
+print >> fp, '''</ul></div>
+{% endblock %}'''
+
+fp.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook.conf	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,101 @@
+# -*- apache -*-
+
+<VirtualHost *:80>
+    ServerName hgbook.red-bean.com
+    ServerAdmin bos@serpentine.com
+    ErrorLog logs/hgbook-error_log
+    # Debian:
+    # CustomLog logs/hgbook-access_log full
+    # Fedora:
+    CustomLog logs/hgbook-access_log combined
+    Options +MultiViews
+    DirectoryIndex index.html.var index.html
+    DocumentRoot "/home/bos/hg/hgbook/en/html"
+
+    Redirect permanent /hgbook.html /index.html
+    Redirect permanent /hgbookch1.html /read/preface.html
+    Redirect permanent /hgbookch2.html /read/a-tour-of-mercurial-the-basics.html
+    Redirect permanent /hgbookch3.html /read/a-tour-of-mercurial-merging-work.html
+    Redirect permanent /hgbookch4.html /read/behind-the-scenes.html
+    Redirect permanent /hgbookch5.html /read/mercurial-in-daily-use.html
+    Redirect permanent /hgbookch6.html /read/file-names-and-pattern-matching.html
+    Redirect permanent /hgbookch6.html /read/managing-releases-and-branchy-development.html
+    Redirect permanent /hgbookch7.html /read/finding-and-fixing-mistakes.html
+    Redirect permanent /hgbookch8.html /read/handling-repository-events-with-hooks.html
+    Redirect permanent /hgbookch9.html /read/customizing-the-output-of-mercurial.html
+    Redirect permanent /hgbookch10.html /read/managing-change-with-mercurial-queues.html
+    Redirect permanent /hgbookch11.html /read/advanced-uses-of-mercurial-queues.html
+    Redirect permanent /hgbookch12.html /read/adding-functionality-with-extensions.html
+    Redirect permanent /hgbookap1.html /read/command-reference.html
+    Redirect permanent /hgbookap2.html /read/mercurial-queues-reference.html
+    Redirect permanent /hgbookap3.html /read/installing-mercurial-from-source.html
+    Redirect permanent /hgbookap4.html /read/open-publication-license.html
+    Redirect permanent /hgbookli1.html /read/index.html
+    Redirect permanent /hgbookli2.html /read/index.html
+    Redirect permanent /hgbookli3.html /read/index.html
+    Redirect permanent /hgbookli4.html /read/index.html
+
+    # Actively redirect requests via a ServerAlias to the canonical hostname.
+    RewriteEngine On
+    RewriteCond %{HTTP_HOST} !=hgbook.red-bean.com
+    RewriteRule ^(.*) http://hgbook.red-bean.com$1 [R]
+
+    <Location "/">
+        SetHandler python-program
+	# hg clone http://bitbucket.org/mirror/django-trunk/
+        PythonPath "['/home/bos/hg/django-trunk', '/home/bos/hg/hgbook/web'] + sys.path"
+        PythonHandler django.core.handlers.modpython
+        PythonAutoReload Off
+        SetEnv DJANGO_SETTINGS_MODULE hgbook.settings
+        PythonDebug Off
+    </Location>
+
+    <Location ~ "^/$">
+        SetHandler None
+        DirectoryIndex index.html
+    </Location>
+
+    <Location ~ "^/index.html">
+        SetHandler None
+    </Location>
+
+    <Location ~ "^/robots.txt">
+        SetHandler None
+    </Location>
+
+    <Location "/read">
+        SetHandler None
+    </Location>
+
+    <Location "/support">
+        SetHandler None
+    </Location>
+
+    <Location "/media">
+        SetHandler None
+    </Location>
+
+    Alias /media /home/bos/hg/django-trunk/django/contrib/admin/media
+
+    <Directory "/home/bos/hg/hgbook/en/html">
+        Options Indexes FollowSymlinks
+        AllowOverride None
+        Order allow,deny
+        Allow from all
+    </Directory>
+
+    <Directory "/home/bos/hg/hgbook/en/html">
+        AllowOverride AuthConfig
+    </Directory>
+
+    <Directory "/home/bos/hg/hgbook/en/html/support">
+        Options None
+    </Directory>
+</VirtualHost>
+
+<Directory "/home/bos/hg/django-trunk/django/contrib/admin/media">
+    Options None
+    AllowOverride None
+    Order allow,deny
+    Allow from all
+</Directory>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/admin.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,23 @@
+from django.contrib import admin
+from hgbook.comments.models import Comment, Element
+
+class CommentAdmin(admin.ModelAdmin):
+    list_display = ['element', 'submitter_name', 'comment', 'reviewed',
+                    'hidden', 'date']
+    search_fields = ['comment']
+    date_hierarchy = 'date'
+    list_filter = ['date', 'submitter_name']
+    search_fields = ['title', 'submitter_name', 'submitter_url']
+    fields = (
+        (None, {'fields': ('submitter_name', 'element', 'comment')}),
+        ('Review and presentation state',
+         {'fields': ('reviewed', 'hidden')}),
+        ('Other info', {'fields': ('date', 'submitter_url', 'ip')}),
+        )
+
+class ElementAdmin(admin.ModelAdmin):
+    search_fields = ['id', 'chapter']
+    list_filter = ['chapter', 'title']
+
+admin.site.register(Comment, CommentAdmin)
+admin.site.register(Element, ElementAdmin)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/feeds.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,35 @@
+from django.core.exceptions import ObjectDoesNotExist
+from django.utils.feedgenerator import Atom1Feed
+from django.contrib.syndication.feeds import Feed
+from hgbook.comments.models import Comment, Element
+
+class MyAtomFeed(Atom1Feed):
+    title_type = u'html'
+    
+class Comments(Feed):
+    feed_type = MyAtomFeed
+    title = 'Mercurial - The Definitive Guide: recent comments'
+    subtitle = ('Recent comments on the text of &#8220;Mercurial: The '
+                'Definitive Guide&#8221;, from our readers')
+    link = '/feeds/comments/'
+    author_name = 'Our readers'
+
+    def feedfilter(self, queryset):
+        return queryset.order_by('-date')[:20]
+
+    def items(self):
+        return self.feedfilter(Comment.objects)
+
+    def item_author_name(self, obj):
+        return obj.submitter_name
+
+    def item_pubdate(self, obj):
+        return obj.date
+
+    def get_object(self, bits):
+        if len(bits) == 0:
+            return self.items()
+        elif len(bits) > 1:
+            raise ObjectDoesNotExist
+        return self.feedfilter(Comment.objects.filter(element__chapter=bits[0],
+                                                      hidden=False))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/models.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,44 @@
+from django.db import models
+import sha
+
+mutable = True
+
+class Element(models.Model):
+    id = models.CharField('ID attribute', max_length=64, editable=False,
+                          primary_key=True)
+    chapter = models.CharField('Chapter ID', max_length=64, editable=False,
+                               db_index=True)
+    title = models.CharField('Section title', max_length=256, editable=False)
+
+    def __unicode__(self):
+        return self.id
+    
+class Comment(models.Model):
+    element = models.ForeignKey(Element,
+        help_text='ID of paragraph that was commented on')
+    comment = models.TextField(editable=mutable,
+        help_text='Text of submitted comment (please do not modify)')
+    submitter_name = models.CharField('Submitter', max_length=64,
+        help_text='Self-reported name of submitter (may be bogus)')
+    submitter_url = models.URLField('URL', blank=True, editable=mutable,
+        help_text='Self-reported URL of submitter (may be empty or bogus)')
+    ip = models.IPAddressField('IP address', editable=mutable,
+        help_text='IP address from which comment was submitted')
+    date = models.DateTimeField('date submitted', auto_now=True,
+                                auto_now_add=True)
+    reviewed = models.BooleanField(default=False, db_index=True,
+        help_text='Has this comment been reviewed by an author?')
+    hidden = models.BooleanField(default=False, db_index=True,
+        help_text='Has this comment been hidden from public display?')
+
+    def __unicode__(self):
+        return self.comment[:32]
+
+    def get_absolute_url(self):
+        s = sha.new()
+        s.update(repr(self.comment))
+        s.update(repr(self.submitter_name))
+        s.update(str(self.date))
+        return '/read/%s.html#%s?comment=%s&uuid=%s' % (
+            self.element.chapter, self.element.id, self.id, s.hexdigest()[:20]
+            )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/sql/comment.mysql.sql	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2 @@
+alter table comments_comment convert to character set utf8 collate utf8_bin;
+alter table comments_comment default character set utf8 collate utf8_bin;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/sql/element.mysql.sql	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2 @@
+alter table comments_element convert to character set utf8 collate utf8_bin;
+alter table comments_element default character set utf8 collate utf8_bin;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/urls.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+    (r'chapter/(?P<id>[^/]+)/?$', 'hgbook.comments.views.chapter'),
+    (r'chapter/(?P<id>[^/]+)/count/?$', 'hgbook.comments.views.chapter_count'),
+    (r'single/(?P<id>[^/]+)/?$', 'hgbook.comments.views.single'),
+    (r'submit/(?P<id>[^/]+)/?$', 'hgbook.comments.views.submit')
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/comments/views.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,101 @@
+import django.forms as forms
+from django.db import connection
+from django.http import HttpResponse
+from hgbook.comments.models import Comment, Element
+from django.shortcuts import get_object_or_404, render_to_response
+from django.template import Context
+from django.template.loader import get_template
+from django.utils.simplejson import dumps 
+
+def dump_queries():
+    # requires settings.DEBUG to be set to True in order to work
+    if len(connection.queries) == 1:
+        print connection.queries
+    else:
+        qs = {}
+        for q in connection.queries:
+            qs[q['sql']] = qs.setdefault(q['sql'], 0) + 1
+        for q in sorted(qs.items(), key=lambda x: x[1], reverse=True):
+            print q
+        print len(connection.queries)
+
+class CommentForm(forms.Form):
+    id = forms.CharField(widget=forms.HiddenInput)
+    name = forms.CharField(max_length=64)
+    url = forms.URLField(max_length=128, required=False)
+    comment = forms.CharField(widget=forms.Textarea(attrs={
+        'rows': 8, 'cols': 60
+        }))
+    remember = forms.BooleanField(initial=True, required=False)
+
+def comments_by_chapter(id):
+    objs = {}
+    for c in Comment.objects.filter(element__chapter=id, hidden=False).order_by('date'):
+        objs.setdefault(c.element_id, []).append(c)
+    return objs
+
+def chapter(request, id):
+    template = get_template('comment.html')
+    resp = {}
+    for elt, comments in comments_by_chapter(id).iteritems():
+        form = CommentForm(initial={
+            'id': elt,
+            'name': request.session.get('name', ''),
+            })
+        resp[elt] = template.render(Context({
+            'id': elt,
+            'form': form,
+            'length': len(comments),
+            'query': comments,
+            }))
+    return HttpResponse(dumps(resp), mimetype='application/json')
+
+def chapter_count(request, id):
+    resp = comments_by_chapter(id)
+    for elt, comments in resp.iteritems():
+        resp[elt] = len(comments)
+    return HttpResponse(dumps(resp), mimetype='application/json')
+    
+def single(request, id, form=None, newid=None):
+    queryset = Comment.objects.filter(element=id, hidden=False).order_by('date')
+    if form is None:
+        form = CommentForm(initial={
+            'id': id,
+            'name': request.session.get('name', ''),
+            })
+    try:
+        error = form.errors[0]
+    except:
+        error = ''
+    return render_to_response('comment.html', {
+        'id': id,
+        'form': form,
+        'length': len(queryset),
+        'query': queryset,
+        'newid': newid or True,
+        'error': error,
+        })
+
+def submit(request, id):
+    element = get_object_or_404(Element, id=id)
+    form = None
+    newid = None
+    if request.method == 'POST':
+        form = CommentForm(request.POST)
+        if form.is_valid():
+            data = form.cleaned_data
+            if data.get('remember'):
+                request.session['name'] = data['name']
+                request.session['url'] = data['url']
+            else:
+                request.session.pop('name', None)
+                request.session.pop('url', None)
+            c = Comment(element=element,
+                        comment=data['comment'],
+                        submitter_name=data['name'],
+                        submitter_url=data['url'],
+                        ip=request.META.get('REMOTE_ADDR'))
+            c.save()
+            newid = c.id
+            form = None
+    return single(request, id, form, newid)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/dbutil.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,32 @@
+import MySQLdb as mysql
+import sys
+
+def connect():
+    try:
+        import secrets
+    except ImportError:
+        print >> sys.stderr, 'Decrypt secrets.py.gpg or create a new copy!'
+        sys.exit(1)
+
+    if secrets.DATABASE_ENGINE != 'mysql':
+        print >> sys.stderr, ('You are using a %s database' %
+                              secrets.DATABASE_ENGINE)
+        sys.exit(1)
+
+    kwargs = {
+        'charset': 'utf8',
+        'use_unicode': True,
+        }
+    if secrets.DATABASE_USER:
+        kwargs['user'] = secrets.DATABASE_USER
+    if secrets.DATABASE_NAME:
+        kwargs['db'] = secrets.DATABASE_NAME
+    if secrets.DATABASE_PASSWORD:
+        kwargs['passwd'] = secrets.DATABASE_PASSWORD
+    if secrets.DATABASE_HOST.startswith('/'):
+        kwargs['unix_socket'] = secrets.DATABASE_HOST
+    elif secrets.DATABASE_HOST:
+        kwargs['host'] = secrets.DATABASE_HOST
+    if secrets.DATABASE_PORT:
+        kwargs['port'] = int(secrets.DATABASE_PORT)
+    return mysql.connect(**kwargs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/load_elements.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# This script updates the contents of the comments_element table.
+# It's fugly, but a lot less painful than trying to use Django's
+# fixtures system.
+
+import os, sys
+sys.path.append(os.path.dirname(__file__))
+import dbutil
+
+os.system('make -C ../../en all-ids.dat')
+
+conn = dbutil.connect()
+c = conn.cursor()
+c.execute('''load data local infile "../../en/all-ids.dat" replace
+             into table comments_element
+             fields terminated by "|"''')
+print 'Database updated'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/manage.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/reviewers.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os, sys
+sys.path.append(os.path.dirname(__file__))
+import dbutil
+
+conn = dbutil.connect()
+c = conn.cursor()
+
+c.execute('''select submitter_name from comments_comment''')
+
+reviewers = {}
+
+mappings = {
+    u'alejandro "tab-lover" dubrovsky': u'Alejandro Dubrovsky',
+    u'alex hirzel <ahirzel@mtu.edu>': u'Alex Hirzel',
+    u'anonymous coward': u'Anonymous',
+    u'arthur van leeuwen': u'Arthur van Leeuwen',
+    u'augustss': u'Lennart Augustsson',
+    u'ed t': u'Anonymous',
+    u'geogre moschovitis': u'George Moschovitis',
+    u'george m': u'George Moschovitis',
+    u'haskell newb': u'Anonymous',
+    u'j. pablo fernandez': u'J. Pablo Fernández',
+    u'kamal al-marhoobi': u'Kamal Al-Marhubi',
+    u'kevin w.': u'Kevin Watters',
+    u'max cantor (#haskell - mxc)': u'Max Cantor',
+    u'michael campbell': u'Michael Campbell',
+    u'mike btauwerman': u'Mike Brauwerman',
+    u'no credit necessary': u'Anonymous',
+    u'nykänen, matti': u'Matti Nykänen',
+    u'omar antolin camarena': u'Omar Antolín Camarena',
+    u'ryan t mulligan': u'Ryan T. Mulligan',
+    u'sengan baring-gould': u'Sengan Baring-Gould',
+    u'some guy': u'Anonymous',
+    u'tomas janousek': u'Tomáš Janoušek',
+    u'william halchin': u'William N. Halchin',
+    }
+
+def fixup(s):
+    try:
+        return s.encode('ascii')
+    except UnicodeEncodeError:
+        def f(c):
+            o = ord(c)
+            if o < 128:
+                return c
+            return '&#%d;' % o
+        return ''.join(map(f, s))
+
+total = 0
+for r in c.fetchall():
+    r = r[0].decode('utf-8')
+    if r in ("Bryan O'Sullivan",):
+        continue
+    total += 1
+    m = mappings.get(r.lower())
+    if m:
+        r = m
+    elif len(r) < 2 or ' ' not in r:
+        r = 'Anonymous'
+    reviewers.setdefault(r, 0)
+    reviewers[r] += 1
+
+reviewers = sorted(reviewers.iteritems(), key=lambda x: x[0])
+
+cohorts = [(.01,1),(.002,.01)]
+
+for (lo,hi) in cohorts:
+    lo = total * lo
+    hi = total * hi
+    for r in [n for n in reviewers if lo <= n[1] < hi]:
+        if r[1] > 3:
+            print '%s,' % fixup(r[0])
+    print
+
+lo = total * .002
+for n in reviewers:
+    if n[1] < lo:
+        print '%s,' % fixup(n[0])
Binary file web/hgbook/secrets.py.gpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/settings.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,87 @@
+# Django settings for hgbook project.
+
+import os, sys
+
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    ("Bryan O'Sullivan", 'bos@serpentine.com'),
+)
+
+MANAGERS = ADMINS
+
+ROOT = os.path.dirname(sys.modules[__name__].__file__)
+
+try:
+    from secrets import DATABASE_ENGINE, DATABASE_NAME, DATABASE_USER, \
+         DATABASE_PASSWORD, DATABASE_HOST, DATABASE_PORT, SECRET_KEY
+except ImportError:
+    print >> sys.stderr, 'Faking up some database configuration for you'
+    DATABASE_ENGINE = 'sqlite3'
+    DATABASE_NAME = os.path.join(ROOT, '.database.sqlite3')
+    DATABASE_USER = ''
+    DATABASE_PASSWORD = ''
+    DATABASE_HOST = ''
+    DATABASE_PORT = ''
+    SECRET_KEY = ''
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be avilable on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Los_Angeles'
+
+# Language code for this installation. All choices can be found here:
+# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+)
+
+ROOT_URLCONF = 'hgbook.urls'
+
+TEMPLATE_DIRS = (
+    os.path.join(ROOT, 'templates')
+)
+
+INSTALLED_APPS = (
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'hgbook.comments',
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/404.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,8 @@
+{% extends "simple.html" %}
+
+{% block title %}Page Not Found{% endblock %}
+
+{% block body %}
+<p>Sorry, we hit <a href="http://www.haskell.org/haskellwiki/Bottom">&perp;</a> when trying to find the
+page you requested.</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/500.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,11 @@
+{% extends "simple.html" %}
+
+{% block title %}Internal Server Error{% endblock %}
+
+{% block body %}
+<p>Sorry, we hit <a
+href="http://www.haskell.org/haskellwiki/Bottom">&perp;</a> when
+trying to process your request.  If possible, please let <a
+href="mailto:bos@serpentine.com">Bryan</a> know that this problem happened,
+and what you were doing when it occurred.</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/boilerplate.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>{% block pagetitle %}Mercurial: The Definitive Guide{% endblock %}</title>
+    <link rel="stylesheet" href="/support/styles.css" type="text/css"/>
+    <link rel="alternate" type="application/atom+xml" title="Comments"
+      href="/feeds/comments/"/>
+    <link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/>
+    <script type="text/javascript" src="/support/jquery.js"></script>
+      <script type="text/javascript" src="/support/form.js"></script>
+    <script type="text/javascript" src="/support/hsbook.js"></script>
+  </head>
+
+  <body>
+    {% block bodycontent %}{% endblock %}
+
+    <div class="hgbookfooter"> <p><img src="/support/figs/rss.png"> Want to stay
+	up to date? Subscribe to comment feeds for any chapter, or
+	the <a class="feed"
+	  href="/feeds/comments/">entire book</a>.</p> <p>Copyright
+	2006, 2007, 2008, 2009 Bryan O'Sullivan.
+	  Icons by
+	  <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a
+	  href="http://mattahan.deviantart.com/">Mattahan</a>.</p>
+    </div>
+
+    <script type="text/javascript">
+    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script>
+    <script type="text/javascript">
+    try {
+    var pageTracker = _gat._getTracker("UA-1805907-5");
+    pageTracker._trackPageview();
+    } catch(err) {}</script>
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/comment.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,62 @@
+{% ifequal length 1 %}
+  <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">One comment</a>
+{% else %}
+  {% if length %}
+    <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">{{ length }} comments</a>
+  {% else %}
+    <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">No comments</a>
+    <div class="comment" {% if not newid %} style="display: none;" {% endif %}>
+      <div class="comment_body">Be the first to comment on this paragraph!</div>
+    </div>
+  {% endif %}
+{% endifequal %}
+{% for c in query %}
+  <div class="{% ifequal c.id newid %}new_{% endifequal %}comment"
+      {% if not newid %} style="display: none;" {% endif %}
+    id="comment{{ c.id }}">
+    <a name="comment{{ c.id }}"/>
+    <div class="comment_header">
+	<span class="comment_id"><a href="/admin/comments/comment/{{ c.id }}/">{{ c.id }}</a></span>
+      {% if c.submitter_url %}
+	<span class="comment_name"><a rel="nofollow"
+	  href="{{ c.submitter_url }}">{{ c.submitter_name|escape }}</a></span>
+      {% else %}
+	<span class="comment_name">{{ c.submitter_name|escape }}</span>
+      {% endif %}
+      <span class="comment_date">{{ c.date|date:"Y-m-d" }}</span>
+      {% if c.reviewed %}
+	<span class="comment_reviewed">(reviewed)</span>
+      {% endif %}
+      {% ifequal c.id newid %}
+	<span class="comment_thanks">thank you for your comment!</span>
+      {% endifequal %}
+    </div>
+    <div class="comment_body">{{ c.comment|escape|linebreaks }}</div>
+  </div>
+{% endfor %}
+<form class="comment" id="form_{{ id }}" action="/comments/submit/{{ id }}/"
+    method="post" {% if not newid %} style="display: none;" {% endif %}>
+  {{ form.id }}
+  <table>
+    <tbody>
+      <tr><td align="right" valign="top">Comment<br><a class="comment_help"
+		href="web.html#web.comment">[ help ]</a></td>
+	  <td>{{ form.comment }}</td></tr>
+      <tr><td align="right">Your name</td><td>{{ form.name }}
+	    <span class="comment_help"><b>Required</b> so we can <a
+		href="web.html#web.comment.name">give you credit</a></span></td></tr>
+      <tr><td align="right">Your URL</td><td>{{ form.url }}
+	    <span class="comment_help"><b>Optional</b> link to blog, home page,
+	      <i>etc</i>.</span></td></tr>
+      <tr><td align="right">Remember you?</td><td>{{ form.remember }}</td></tr>
+      <tr><td/><td><input name="submit" type="submit"
+	      value="Submit Comment"/><span class="comment_error">{{ error }}</span></td></tr>
+    </tbody>
+  </table>
+</form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/feeds/comments_description.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,12 @@
+<p>On {{ obj.date|date:"Y-m-d" }},
+      {% if obj.submitter_url %}
+	<a rel="nofollow" href="{{ obj.submitter_url }}">{{ obj.submitter_name|escape }}</a>
+      {% else %}
+	{{ obj.submitter_name|escape }}
+      {% endif %}
+commented on &#8220;{{ obj.element.title|escape }}&#8221;:</p>
+<blockquote>
+{{ obj.comment|escape|linebreaks }}
+</blockquote>
+<p>To see this comment in context or to respond, visit <a
+	href="http://{{ site.domain }}{{ obj.get_absolute_url }}">{{ site.domain }}</a></p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/feeds/comments_title.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+Comment on &#8220;{{ obj.element.title|escape }}&#8221;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/templates/simple.html	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,7 @@
+{% extends "boilerplate.html" %}
+
+{% block bodycontent %}
+<div class="navheader"><h1>{% block title %}{% endblock %}</h1></div>
+
+<div class="basetemplate">{% block body %}{% endblock %}</div>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/hgbook/urls.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,25 @@
+import os
+from django.conf.urls.defaults import *
+import hgbook.comments.feeds as feeds
+from django.contrib import admin
+
+admin.autodiscover()
+
+feeds = {
+    'comments': feeds.Comments,
+    }
+
+urlpatterns = patterns('',
+    (r'^comments/', include('hgbook.comments.urls')),
+
+    (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
+     {'feed_dict': feeds}),          
+
+    # Only uncomment this for local testing without Apache.
+    # (r'^html/(?P<path>.*)$', 'django.views.static.serve',
+    # {'document_root': os.path.realpath(os.path.dirname(
+    #    sys.modules[__name__].__file__) + '/../../en/html'),
+
+    # Uncomment this for admin:
+    (r'^admin/(.*)', admin.site.root),
+)
Binary file web/icons/caution.png has changed
Binary file web/icons/favicon.png has changed
Binary file web/icons/important.png has changed
Binary file web/icons/note.png has changed
Binary file web/icons/remark.png has changed
Binary file web/icons/rss.png has changed
Binary file web/icons/shell.png has changed
Binary file web/icons/source.png has changed
Binary file web/icons/tip.png has changed
Binary file web/icons/warning.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/index.html.in	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,65 @@
+<!-- -*- html -*- -->
+{% extends "boilerplate.html" %}
+
+{% block bodycontent %}
+<div class="navheader"><h1 class="booktitle">Mercurial: The Definitive Guide<div class="authors">by Bryan O'Sullivan</div></h1></div>
+
+<div class="book">
+  <h2>Welcome to Mercurial: The Definitive Guide</h2>
+
+  <p>This is the online home of the book &#8220;Mercurial: The
+    Definitive Guide&#8221;.  
+    It will be published in 2009 by O'Reilly Media.</p>
+
+  <p>I make the content <a href="/read/">freely available
+      online</a>.  If you like it, please make a note to buy a copy!</p>
+
+  <p>For news updates, please
+    visit <a href="http://www.serpentine.com/blog/">my blog</a>.</p>
+
+  <h2>You can contribute!</h2>
+
+  <p>I publish the <a href="http://hgbook.red-bean.com/">source
+      code</a> for this book as a Mercurial repository.  Please feel
+    welcome to clone it, make modifications to your copy, and send me
+    changes.</p>
+
+  <p>The online version of the book includes a comment system
+    that you can use to send feedback involving errors, omissions, and
+    suggestions.</p>
+
+  <p>(If you would like to adapt the comment system for a
+    publishing project of your own, the source for the web application
+    is included with the book source at the link above.)</p>
+
+  <h2>What is Mercurial?</h2>
+
+  <p><a href="http://www.selenic.com/mercurial">Mercurial</a> is a
+    fast, lightweight source control management system
+    designed for easy and efficient handling of very large distributed
+    projects.</p>
+
+  <h2>How I help Mercurial and free software, and you can too</h2>
+
+  <p>Mercurial is a member of the <a href="http://conservancy.softwarefreedom.org/">Software Freedom Conservancy</a>, a
+    wonderful non-profit organisation that offers its member projects
+    legal and administrative advice.</p>
+
+  <p>I am donating my royalties from the sales of this book (once it is
+    published) to the Software Freedom Conservancy, and I encourage
+    you to support their work, too.</p>
+
+  <p>The SFC can
+    accept <a href="http://conservancy.softwarefreedom.org/?donate">accept
+    donations</a> (tax-free under IRS 501(c)(3), within the United
+    States) on behalf of its member projects. If you would like to
+    support Mercurial directly, please consider making a donation to
+    the SFC on its behalf.</p>
+
+  <p>If you would like to help free software developers to provide
+    their important public services without being impeded by legal
+    issues, please consider donating to the SFC's sister organisation,
+    the <a href="http://www.softwarefreedom.org/">Software Freedom Law
+    Center</a>.</p>
+</div>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/javascript/form-min.js	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,1 @@
+(function($){$.fn.ajaxSubmit=function(_2){if(typeof _2=="function"){_2={success:_2};}_2=$.extend({url:this.attr("action")||window.location,type:this.attr("method")||"GET"},_2||{});var _3={};$.event.trigger("form.pre.serialize",[this,_2,_3]);if(_3.veto){return this;}var a=this.formToArray(_2.semantic);if(_2.data){for(var n in _2.data){a.push({name:n,value:_2.data[n]});}}if(_2.beforeSubmit&&_2.beforeSubmit(a,this,_2)===false){return this;}$.event.trigger("form.submit.validate",[a,this,_2,_3]);if(_3.veto){return this;}var q=$.param(a);if(_2.type.toUpperCase()=="GET"){_2.url+=(_2.url.indexOf("?")>=0?"&":"?")+q;_2.data=null;}else{_2.data=q;}var _7=this,callbacks=[];if(_2.resetForm){callbacks.push(function(){_7.resetForm();});}if(_2.clearForm){callbacks.push(function(){_7.clearForm();});}if(!_2.dataType&&_2.target){var _8=_2.success||function(){};callbacks.push(function(_9){if(this.evalScripts){$(_2.target).attr("innerHTML",_9).evalScripts().each(_8,arguments);}else{$(_2.target).html(_9).each(_8,arguments);}});}else{if(_2.success){callbacks.push(_2.success);}}_2.success=function(_a,_b){for(var i=0,max=callbacks.length;i<max;i++){callbacks[i](_a,_b,_7);}};var _d=$("input:file",this).fieldValue();var _e=false;for(var j=0;j<_d.length;j++){if(_d[j]){_e=true;}}if(_2.iframe||_e){fileUpload();}else{$.ajax(_2);}$.event.trigger("form.submit.notify",[this,_2]);return this;function fileUpload(){var _10=_7[0];var _11=$.extend({},$.ajaxSettings,_2);var id="jqFormIO"+$.fn.ajaxSubmit.counter++;var $io=$("<iframe id=\""+id+"\" name=\""+id+"\" />");var io=$io[0];var op8=$.browser.opera&&window.opera.version()<9;if($.browser.msie||op8){io.src="javascript:false;document.write(\"\");";}$io.css({position:"absolute",top:"-1000px",left:"-1000px"});var xhr={responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){}};var g=_11.global;if(g&&!$.active++){$.event.trigger("ajaxStart");}if(g){$.event.trigger("ajaxSend",[xhr,_11]);}var _18=0;var _19=0;setTimeout(function(){$io.appendTo("body");io.attachEvent?io.attachEvent("onload",cb):io.addEventListener("load",cb,false);var _1a=_10.encoding?"encoding":"enctype";var t=_7.attr("target");_7.attr({target:id,method:"POST",action:_11.url});_10[_1a]="multipart/form-data";if(_11.timeout){setTimeout(function(){_19=true;cb();},_11.timeout);}_10.submit();_7.attr("target",t);},10);function cb(){if(_18++){return;}io.detachEvent?io.detachEvent("onload",cb):io.removeEventListener("load",cb,false);var ok=true;try{if(_19){throw "timeout";}var _1d,doc;doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;xhr.responseText=doc.body?doc.body.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(_11.dataType=="json"||_11.dataType=="script"){var ta=doc.getElementsByTagName("textarea")[0];_1d=ta?ta.value:xhr.responseText;if(_11.dataType=="json"){eval("data = "+_1d);}else{$.globalEval(_1d);}}else{if(_11.dataType=="xml"){_1d=xhr.responseXML;if(!_1d&&xhr.responseText!=null){_1d=toXml(xhr.responseText);}}else{_1d=xhr.responseText;}}}catch(e){ok=false;$.handleError(_11,xhr,"error",e);}if(ok){_11.success(_1d,"success");if(g){$.event.trigger("ajaxSuccess",[xhr,_11]);}}if(g){$.event.trigger("ajaxComplete",[xhr,_11]);}if(g&&!--$.active){$.event.trigger("ajaxStop");}if(_11.complete){_11.complete(xhr,ok?"success":"error");}setTimeout(function(){$io.remove();xhr.responseXML=null;},100);}function toXml(s,doc){if(window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(s);}else{doc=(new DOMParser()).parseFromString(s,"text/xml");}return (doc&&doc.documentElement&&doc.documentElement.tagName!="parsererror")?doc:null;}}};$.fn.ajaxSubmit.counter=0;$.fn.ajaxForm=function(_21){return this.ajaxFormUnbind().submit(submitHandler).each(function(){this.formPluginId=$.fn.ajaxForm.counter++;$.fn.ajaxForm.optionHash[this.formPluginId]=_21;$(":submit,input:image",this).click(clickHandler);});};$.fn.ajaxForm.counter=1;$.fn.ajaxForm.optionHash={};function clickHandler(e){var _23=this.form;_23.clk=this;if(this.type=="image"){if(e.offsetX!=undefined){_23.clk_x=e.offsetX;_23.clk_y=e.offsetY;}else{if(typeof $.fn.offset=="function"){var _24=$(this).offset();_23.clk_x=e.pageX-_24.left;_23.clk_y=e.pageY-_24.top;}else{_23.clk_x=e.pageX-this.offsetLeft;_23.clk_y=e.pageY-this.offsetTop;}}}setTimeout(function(){_23.clk=_23.clk_x=_23.clk_y=null;},10);}function submitHandler(){var id=this.formPluginId;var _26=$.fn.ajaxForm.optionHash[id];$(this).ajaxSubmit(_26);return false;}$.fn.ajaxFormUnbind=function(){this.unbind("submit",submitHandler);return this.each(function(){$(":submit,input:image",this).unbind("click",clickHandler);});};$.fn.formToArray=function(_27){var a=[];if(this.length==0){return a;}var _29=this[0];var els=_27?_29.getElementsByTagName("*"):_29.elements;if(!els){return a;}for(var i=0,max=els.length;i<max;i++){var el=els[i];var n=el.name;if(!n){continue;}if(_27&&_29.clk&&el.type=="image"){if(!el.disabled&&_29.clk==el){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}continue;}var v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(var j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:n,value:v});}}}if(!_27&&_29.clk){var _30=_29.getElementsByTagName("input");for(var i=0,max=_30.length;i<max;i++){var _32=_30[i];var n=_32.name;if(n&&!_32.disabled&&_32.type=="image"&&_29.clk==_32){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}}}return a;};$.fn.formSerialize=function(_34){return $.param(this.formToArray(_34));};$.fn.fieldSerialize=function(_35){var a=[];this.each(function(){var n=this.name;if(!n){return;}var v=$.fieldValue(this,_35);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:this.name,value:v});}}});return $.param(a);};$.fn.fieldValue=function(_3a){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,_3a);if(v===null||typeof v=="undefined"||(v.constructor==Array&&!v.length)){continue;}v.constructor==Array?$.merge(val,v):val.push(v);}return val;};$.fieldValue=function(el,_3f){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(typeof _3f=="undefined"){_3f=true;}if(_3f&&(!n||el.disabled||t=="reset"||t=="button"||(t=="checkbox"||t=="radio")&&!el.checked||(t=="submit"||t=="image")&&el.form&&el.form.clk!=el||tag=="select"&&el.selectedIndex==-1)){return null;}if(tag=="select"){var _41=el.selectedIndex;if(_41<0){return null;}var a=[],ops=el.options;var one=(t=="select-one");var max=(one?_41+1:ops.length);for(var i=(one?_41:0);i<max;i++){var op=ops[i];if(op.selected){var v=$.browser.msie&&!(op.attributes["value"].specified)?op.text:op.value;if(one){return v;}a.push(v);}}return a;}return el.value;};$.fn.clearForm=function(){return this.each(function(){$("input,select,textarea",this).clearFields();});};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=="text"||t=="password"||tag=="textarea"){this.value="";}else{if(t=="checkbox"||t=="radio"){this.checked=false;}else{if(tag=="select"){this.selectedIndex=-1;}}}});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset();}});};})(jQuery);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/javascript/form.js	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,819 @@
+/*
+ * jQuery Form Plugin
+ * @requires jQuery v1.1 or later
+ *
+ * Examples at: http://malsup.com/jquery/form/
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id$
+ */
+ (function($) {
+/**
+ * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
+ *
+ * ajaxSubmit accepts a single argument which can be either a success callback function
+ * or an options Object.  If a function is provided it will be invoked upon successful
+ * completion of the submit and will be passed the response from the server.
+ * If an options Object is provided, the following attributes are supported:
+ *
+ *  target:   Identifies the element(s) in the page to be updated with the server response.
+ *            This value may be specified as a jQuery selection string, a jQuery object,
+ *            or a DOM element.
+ *            default value: null
+ *
+ *  url:      URL to which the form data will be submitted.
+ *            default value: value of form's 'action' attribute
+ *
+ *  type:     The method in which the form data should be submitted, 'GET' or 'POST'.
+ *            default value: value of form's 'method' attribute (or 'GET' if none found)
+ *
+ *  data:     Additional data to add to the request, specified as key/value pairs (see $.ajax).
+ *
+ *  beforeSubmit:  Callback method to be invoked before the form is submitted.
+ *            default value: null
+ *
+ *  success:  Callback method to be invoked after the form has been successfully submitted
+ *            and the response has been returned from the server
+ *            default value: null
+ *
+ *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json'
+ *            default value: null
+ *
+ *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
+ *            default value: false
+ *
+ *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
+ *
+ *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
+ *
+ *
+ * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
+ * validating the form data.  If the 'beforeSubmit' callback returns false then the form will
+ * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
+ * in array format, the jQuery object, and the options object passed into ajaxSubmit.
+ * The form data array takes the following form:
+ *
+ *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * If a 'success' callback method is provided it is invoked after the response has been returned
+ * from the server.  It is passed the responseText or responseXML value (depending on dataType).
+ * See jQuery.ajax for further details.
+ *
+ *
+ * The dataType option provides a means for specifying how the server response should be handled.
+ * This maps directly to the jQuery.httpData method.  The following values are supported:
+ *
+ *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success'
+ *                   callback method, if specified, will be passed the responseXML value
+ *      'json':   if dataType == 'json' the server response will be evaluted and passed to
+ *                   the 'success' callback, if specified
+ *      'script': if dataType == 'script' the server response is evaluated in the global context
+ *
+ *
+ * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both
+ * are provided the target will be ignored.
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * This is normally true anyway, unless the form contains input elements of type='image'.
+ * If your form must be submitted with name/value pairs in semantic order and your form
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
+ * (or nothing) to avoid the overhead for this logic.
+ *
+ *
+ * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
+ *
+ * $("#form-id").submit(function() {
+ *     $(this).ajaxSubmit(options);
+ *     return false; // cancel conventional submit
+ * });
+ *
+ * When using ajaxForm(), however, this is done for you.
+ *
+ * @example
+ * $('#myForm').ajaxSubmit(function(data) {
+ *     alert('Form submit succeeded! Server returned: ' + data);
+ * });
+ * @desc Submit form and alert server response
+ *
+ *
+ * @example
+ * var options = {
+ *     target: '#myTargetDiv'
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Submit form and update page element with server response
+ *
+ *
+ * @example
+ * var options = {
+ *     success: function(responseText) {
+ *         alert(responseText);
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Submit form and alert the server response
+ *
+ *
+ * @example
+ * var options = {
+ *     beforeSubmit: function(formArray, jqForm) {
+ *         if (formArray.length == 0) {
+ *             alert('Please enter data.');
+ *             return false;
+ *         }
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Pre-submit validation which aborts the submit operation if form data is empty
+ *
+ *
+ * @example
+ * var options = {
+ *     url: myJsonUrl.php,
+ *     dataType: 'json',
+ *     success: function(data) {
+ *        // 'data' is an object representing the the evaluated json data
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc json data returned and evaluated
+ *
+ *
+ * @example
+ * var options = {
+ *     url: myXmlUrl.php,
+ *     dataType: 'xml',
+ *     success: function(responseXML) {
+ *        // responseXML is XML document object
+ *        var data = $('myElement', responseXML).text();
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc XML data returned from server
+ *
+ *
+ * @example
+ * var options = {
+ *     resetForm: true
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc submit form and reset it if successful
+ *
+ * @example
+ * $('#myForm).submit(function() {
+ *    $(this).ajaxSubmit();
+ *    return false;
+ * });
+ * @desc Bind form's submit event to use ajaxSubmit
+ *
+ *
+ * @name ajaxSubmit
+ * @type jQuery
+ * @param options  object literal containing options which control the form submission process
+ * @cat Plugins/Form
+ * @return jQuery
+ */
+$.fn.ajaxSubmit = function(options) {
+    if (typeof options == 'function')
+        options = { success: options };
+
+    options = $.extend({
+        url:  this.attr('action') || window.location,
+        type: this.attr('method') || 'GET'
+    }, options || {});
+
+    // hook for manipulating the form data before it is extracted;
+    // convenient for use with rich editors like tinyMCE or FCKEditor
+    var veto = {};
+    $.event.trigger('form.pre.serialize', [this, options, veto]);
+    if (veto.veto) return this;
+
+    var a = this.formToArray(options.semantic);
+	if (options.data) {
+	    for (var n in options.data)
+	        a.push( { name: n, value: options.data[n] } );
+	}
+
+    // give pre-submit callback an opportunity to abort the submit
+    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
+
+    // fire vetoable 'validate' event
+    $.event.trigger('form.submit.validate', [a, this, options, veto]);
+    if (veto.veto) return this;
+
+    var q = $.param(a);//.replace(/%20/g,'+');
+
+    if (options.type.toUpperCase() == 'GET') {
+        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
+        options.data = null;  // data is null for 'get'
+    }
+    else
+        options.data = q; // data is the query string for 'post'
+
+    var $form = this, callbacks = [];
+    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
+    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
+
+    // perform a load on the target only if dataType is not provided
+    if (!options.dataType && options.target) {
+        var oldSuccess = options.success || function(){};
+        callbacks.push(function(data) {
+            if (this.evalScripts)
+                $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);
+            else // jQuery v1.1.4
+                $(options.target).html(data).each(oldSuccess, arguments);
+        });
+    }
+    else if (options.success)
+        callbacks.push(options.success);
+
+    options.success = function(data, status) {
+        for (var i=0, max=callbacks.length; i < max; i++)
+            callbacks[i](data, status, $form);
+    };
+
+    // are there files to upload?
+    var files = $('input:file', this).fieldValue();
+    var found = false;
+    for (var j=0; j < files.length; j++)
+        if (files[j])
+            found = true;
+
+    if (options.iframe || found) // options.iframe allows user to force iframe mode
+        fileUpload();
+    else
+        $.ajax(options);
+
+    // fire 'notify' event
+    $.event.trigger('form.submit.notify', [this, options]);
+    return this;
+
+
+    // private function for handling file uploads (hat tip to YAHOO!)
+    function fileUpload() {
+        var form = $form[0];
+        var opts = $.extend({}, $.ajaxSettings, options);
+
+        var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
+        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
+        var io = $io[0];
+        var op8 = $.browser.opera && window.opera.version() < 9;
+        if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
+        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
+
+        var xhr = { // mock object
+            responseText: null,
+            responseXML: null,
+            status: 0,
+            statusText: 'n/a',
+            getAllResponseHeaders: function() {},
+            getResponseHeader: function() {},
+            setRequestHeader: function() {}
+        };
+
+        var g = opts.global;
+        // trigger ajax global events so that activity/block indicators work like normal
+        if (g && ! $.active++) $.event.trigger("ajaxStart");
+        if (g) $.event.trigger("ajaxSend", [xhr, opts]);
+
+        var cbInvoked = 0;
+        var timedOut = 0;
+
+        // take a breath so that pending repaints get some cpu time before the upload starts
+        setTimeout(function() {
+            $io.appendTo('body');
+            // jQuery's event binding doesn't work for iframe events in IE
+            io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
+
+            // make sure form attrs are set
+            var encAttr = form.encoding ? 'encoding' : 'enctype';
+            var t = $form.attr('target');
+            $form.attr({
+                target:   id,
+                method:  'POST',
+                action:   opts.url
+            });
+            form[encAttr] = 'multipart/form-data';
+
+            // support timout
+            if (opts.timeout)
+                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
+
+            form.submit();
+            $form.attr('target', t); // reset target
+        }, 10);
+
+        function cb() {
+            if (cbInvoked++) return;
+
+            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
+
+            var ok = true;
+            try {
+                if (timedOut) throw 'timeout';
+                // extract the server response from the iframe
+                var data, doc;
+                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
+                xhr.responseText = doc.body ? doc.body.innerHTML : null;
+                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
+
+                if (opts.dataType == 'json' || opts.dataType == 'script') {
+                    var ta = doc.getElementsByTagName('textarea')[0];
+                    data = ta ? ta.value : xhr.responseText;
+                    if (opts.dataType == 'json')
+                        eval("data = " + data);
+                    else
+                        $.globalEval(data);
+                }
+                else if (opts.dataType == 'xml') {
+                    data = xhr.responseXML;
+                    if (!data && xhr.responseText != null)
+                        data = toXml(xhr.responseText);
+                }
+                else {
+                    data = xhr.responseText;
+                }
+            }
+            catch(e){
+                ok = false;
+                $.handleError(opts, xhr, 'error', e);
+            }
+
+            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
+            if (ok) {
+                opts.success(data, 'success');
+                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
+            }
+            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
+            if (g && ! --$.active) $.event.trigger("ajaxStop");
+            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
+
+            // clean up
+            setTimeout(function() {
+                $io.remove();
+                xhr.responseXML = null;
+            }, 100);
+        };
+
+        function toXml(s, doc) {
+            if (window.ActiveXObject) {
+                doc = new ActiveXObject('Microsoft.XMLDOM');
+                doc.async = 'false';
+                doc.loadXML(s);
+            }
+            else
+                doc = (new DOMParser()).parseFromString(s, 'text/xml');
+            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
+        };
+    };
+};
+$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids
+
+/**
+ * ajaxForm() provides a mechanism for fully automating form submission.
+ *
+ * The advantages of using this method instead of ajaxSubmit() are:
+ *
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
+ *    is used to submit the form).
+ * 2. This method will include the submit element's name/value data (for the element that was
+ *    used to submit the form).
+ * 3. This method binds the submit() method to the form for you.
+ *
+ * Note that for accurate x/y coordinates of image submit elements in all browsers
+ * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
+ *
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
+ * passes the options argument along after properly binding events for submit elements and
+ * the form itself.  See ajaxSubmit for a full description of the options argument.
+ *
+ *
+ * @example
+ * var options = {
+ *     target: '#myTargetDiv'
+ * };
+ * $('#myForm').ajaxSForm(options);
+ * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
+ *       when the form is submitted.
+ *
+ *
+ * @example
+ * var options = {
+ *     success: function(responseText) {
+ *         alert(responseText);
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Bind form's submit event so that server response is alerted after the form is submitted.
+ *
+ *
+ * @example
+ * var options = {
+ *     beforeSubmit: function(formArray, jqForm) {
+ *         if (formArray.length == 0) {
+ *             alert('Please enter data.');
+ *             return false;
+ *         }
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Bind form's submit event so that pre-submit callback is invoked before the form
+ *       is submitted.
+ *
+ *
+ * @name   ajaxForm
+ * @param  options  object literal containing options which control the form submission process
+ * @return jQuery
+ * @cat    Plugins/Form
+ * @type   jQuery
+ */
+$.fn.ajaxForm = function(options) {
+    return this.ajaxFormUnbind().submit(submitHandler).each(function() {
+        // store options in hash
+        this.formPluginId = $.fn.ajaxForm.counter++;
+        $.fn.ajaxForm.optionHash[this.formPluginId] = options;
+        $(":submit,input:image", this).click(clickHandler);
+    });
+};
+
+$.fn.ajaxForm.counter = 1;
+$.fn.ajaxForm.optionHash = {};
+
+function clickHandler(e) {
+    var $form = this.form;
+    $form.clk = this;
+    if (this.type == 'image') {
+        if (e.offsetX != undefined) {
+            $form.clk_x = e.offsetX;
+            $form.clk_y = e.offsetY;
+        } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
+            var offset = $(this).offset();
+            $form.clk_x = e.pageX - offset.left;
+            $form.clk_y = e.pageY - offset.top;
+        } else {
+            $form.clk_x = e.pageX - this.offsetLeft;
+            $form.clk_y = e.pageY - this.offsetTop;
+        }
+    }
+    // clear form vars
+    setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
+};
+
+function submitHandler() {
+    // retrieve options from hash
+    var id = this.formPluginId;
+    var options = $.fn.ajaxForm.optionHash[id];
+    $(this).ajaxSubmit(options);
+    return false;
+};
+
+/**
+ * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
+ *
+ * @name   ajaxFormUnbind
+ * @return jQuery
+ * @cat    Plugins/Form
+ * @type   jQuery
+ */
+$.fn.ajaxFormUnbind = function() {
+    this.unbind('submit', submitHandler);
+    return this.each(function() {
+        $(":submit,input:image", this).unbind('click', clickHandler);
+    });
+
+};
+
+/**
+ * formToArray() gathers form element data into an array of objects that can
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
+ * Each object in the array has both a 'name' and 'value' property.  An example of
+ * an array for a simple login form might be:
+ *
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * It is this array that is passed to pre-submit callback functions provided to the
+ * ajaxSubmit() and ajaxForm() methods.
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * This is normally true anyway, unless the form contains input elements of type='image'.
+ * If your form must be submitted with name/value pairs in semantic order and your form
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
+ * (or nothing) to avoid the overhead for this logic.
+ *
+ * @example var data = $("#myForm").formToArray();
+ * $.post( "myscript.cgi", data );
+ * @desc Collect all the data from a form and submit it to the server.
+ *
+ * @name formToArray
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type Array<Object>
+ * @cat Plugins/Form
+ */
+$.fn.formToArray = function(semantic) {
+    var a = [];
+    if (this.length == 0) return a;
+
+    var form = this[0];
+    var els = semantic ? form.getElementsByTagName('*') : form.elements;
+    if (!els) return a;
+    for(var i=0, max=els.length; i < max; i++) {
+        var el = els[i];
+        var n = el.name;
+        if (!n) continue;
+
+        if (semantic && form.clk && el.type == "image") {
+            // handle image inputs on the fly when semantic == true
+            if(!el.disabled && form.clk == el)
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+            continue;
+        }
+
+        var v = $.fieldValue(el, true);
+        if (v && v.constructor == Array) {
+            for(var j=0, jmax=v.length; j < jmax; j++)
+                a.push({name: n, value: v[j]});
+        }
+        else if (v !== null && typeof v != 'undefined')
+            a.push({name: n, value: v});
+    }
+
+    if (!semantic && form.clk) {
+        // input type=='image' are not found in elements array! handle them here
+        var inputs = form.getElementsByTagName("input");
+        for(var i=0, max=inputs.length; i < max; i++) {
+            var input = inputs[i];
+            var n = input.name;
+            if(n && !input.disabled && input.type == "image" && form.clk == input)
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+        }
+    }
+    return a;
+};
+
+
+/**
+ * Serializes form data into a 'submittable' string. This method will return a string
+ * in the format: name1=value1&amp;name2=value2
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * If your form must be submitted with name/value pairs in semantic order then pass
+ * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
+ * this logic (which can be significant for very large forms).
+ *
+ * @example var data = $("#myForm").formSerialize();
+ * $.ajax('POST', "myscript.cgi", data);
+ * @desc Collect all the data from a form into a single string
+ *
+ * @name formSerialize
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type String
+ * @cat Plugins/Form
+ */
+$.fn.formSerialize = function(semantic) {
+    //hand off to jQuery.param for proper encoding
+    return $.param(this.formToArray(semantic));
+};
+
+
+/**
+ * Serializes all field elements in the jQuery object into a query string.
+ * This method will return a string in the format: name1=value1&amp;name2=value2
+ *
+ * The successful argument controls whether or not serialization is limited to
+ * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.
+ *
+ * @example var data = $("input").formSerialize();
+ * @desc Collect the data from all successful input elements into a query string
+ *
+ * @example var data = $(":radio").formSerialize();
+ * @desc Collect the data from all successful radio input elements into a query string
+ *
+ * @example var data = $("#myForm :checkbox").formSerialize();
+ * @desc Collect the data from all successful checkbox input elements in myForm into a query string
+ *
+ * @example var data = $("#myForm :checkbox").formSerialize(false);
+ * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
+ *
+ * @example var data = $(":input").formSerialize();
+ * @desc Collect the data from all successful input, select, textarea and button elements into a query string
+ *
+ * @name fieldSerialize
+ * @param successful true if only successful controls should be serialized (default is true)
+ * @type String
+ * @cat Plugins/Form
+ */
+$.fn.fieldSerialize = function(successful) {
+    var a = [];
+    this.each(function() {
+        var n = this.name;
+        if (!n) return;
+        var v = $.fieldValue(this, successful);
+        if (v && v.constructor == Array) {
+            for (var i=0,max=v.length; i < max; i++)
+                a.push({name: n, value: v[i]});
+        }
+        else if (v !== null && typeof v != 'undefined')
+            a.push({name: this.name, value: v});
+    });
+    //hand off to jQuery.param for proper encoding
+    return $.param(a);
+};
+
+
+/**
+ * Returns the value(s) of the element in the matched set.  For example, consider the following form:
+ *
+ *  <form><fieldset>
+ *      <input name="A" type="text" />
+ *      <input name="A" type="text" />
+ *      <input name="B" type="checkbox" value="B1" />
+ *      <input name="B" type="checkbox" value="B2"/>
+ *      <input name="C" type="radio" value="C1" />
+ *      <input name="C" type="radio" value="C2" />
+ *  </fieldset></form>
+ *
+ *  var v = $(':text').fieldValue();
+ *  // if no values are entered into the text inputs
+ *  v == ['','']
+ *  // if values entered into the text inputs are 'foo' and 'bar'
+ *  v == ['foo','bar']
+ *
+ *  var v = $(':checkbox').fieldValue();
+ *  // if neither checkbox is checked
+ *  v === undefined
+ *  // if both checkboxes are checked
+ *  v == ['B1', 'B2']
+ *
+ *  var v = $(':radio').fieldValue();
+ *  // if neither radio is checked
+ *  v === undefined
+ *  // if first radio is checked
+ *  v == ['C1']
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If this value is false the value(s)
+ * for each element is returned.
+ *
+ * Note: This method *always* returns an array.  If no valid value can be determined the
+ *       array will be empty, otherwise it will contain one or more values.
+ *
+ * @example var data = $("#myPasswordElement").fieldValue();
+ * alert(data[0]);
+ * @desc Alerts the current value of the myPasswordElement element
+ *
+ * @example var data = $("#myForm :input").fieldValue();
+ * @desc Get the value(s) of the form elements in myForm
+ *
+ * @example var data = $("#myForm :checkbox").fieldValue();
+ * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
+ *
+ * @example var data = $("#mySingleSelect").fieldValue();
+ * @desc Get the value(s) of the select control
+ *
+ * @example var data = $(':text').fieldValue();
+ * @desc Get the value(s) of the text input or textarea elements
+ *
+ * @example var data = $("#myMultiSelect").fieldValue();
+ * @desc Get the values for the select-multiple control
+ *
+ * @name fieldValue
+ * @param Boolean successful true if only the values for successful controls should be returned (default is true)
+ * @type Array<String>
+ * @cat Plugins/Form
+ */
+$.fn.fieldValue = function(successful) {
+    for (var val=[], i=0, max=this.length; i < max; i++) {
+        var el = this[i];
+        var v = $.fieldValue(el, successful);
+        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
+            continue;
+        v.constructor == Array ? $.merge(val, v) : val.push(v);
+    }
+    return val;
+};
+
+/**
+ * Returns the value of the field element.
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If the given element is not
+ * successful and the successful arg is not false then the returned value will be null.
+ *
+ * Note: If the successful flag is true (default) but the element is not successful, the return will be null
+ * Note: The value returned for a successful select-multiple element will always be an array.
+ * Note: If the element has no value the return value will be undefined.
+ *
+ * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
+ * @desc Gets the current value of the myPasswordElement element
+ *
+ * @name fieldValue
+ * @param Element el The DOM element for which the value will be returned
+ * @param Boolean successful true if value returned must be for a successful controls (default is true)
+ * @type String or Array<String> or null or undefined
+ * @cat Plugins/Form
+ */
+$.fieldValue = function(el, successful) {
+    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
+    if (typeof successful == 'undefined') successful = true;
+
+    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
+        (t == 'checkbox' || t == 'radio') && !el.checked ||
+        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
+        tag == 'select' && el.selectedIndex == -1))
+            return null;
+
+    if (tag == 'select') {
+        var index = el.selectedIndex;
+        if (index < 0) return null;
+        var a = [], ops = el.options;
+        var one = (t == 'select-one');
+        var max = (one ? index+1 : ops.length);
+        for(var i=(one ? index : 0); i < max; i++) {
+            var op = ops[i];
+            if (op.selected) {
+                // extra pain for IE...
+                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
+                if (one) return v;
+                a.push(v);
+            }
+        }
+        return a;
+    }
+    return el.value;
+};
+
+
+/**
+ * Clears the form data.  Takes the following actions on the form's input fields:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ * @example $('form').clearForm();
+ * @desc Clears all forms on the page.
+ *
+ * @name clearForm
+ * @type jQuery
+ * @cat Plugins/Form
+ */
+$.fn.clearForm = function() {
+    return this.each(function() {
+        $('input,select,textarea', this).clearFields();
+    });
+};
+
+/**
+ * Clears the selected form elements.  Takes the following actions on the matched elements:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ * @example $('.myInputs').clearFields();
+ * @desc Clears all inputs with class myInputs
+ *
+ * @name clearFields
+ * @type jQuery
+ * @cat Plugins/Form
+ */
+$.fn.clearFields = $.fn.clearInputs = function() {
+    return this.each(function() {
+        var t = this.type, tag = this.tagName.toLowerCase();
+        if (t == 'text' || t == 'password' || tag == 'textarea')
+            this.value = '';
+        else if (t == 'checkbox' || t == 'radio')
+            this.checked = false;
+        else if (tag == 'select')
+            this.selectedIndex = -1;
+    });
+};
+
+
+/**
+ * Resets the form data.  Causes all form elements to be reset to their original value.
+ *
+ * @example $('form').resetForm();
+ * @desc Resets all forms on the page.
+ *
+ * @name resetForm
+ * @type jQuery
+ * @cat Plugins/Form
+ */
+$.fn.resetForm = function() {
+    return this.each(function() {
+        // guard against an input with the name of 'reset'
+        // note that IE reports the reset function as an 'object'
+        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
+            this.reset();
+    });
+};
+
+})(jQuery);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/javascript/hsbook.js	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,91 @@
+function qid(id) {
+  return id.replace(/([.:])/g, "\\$1");
+}
+
+function beforeComment(formData, jqForm, options) {
+  var form = jqForm[0];
+  if (!form.comment.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Your comment is empty</span>");
+    return false;
+  }
+  if (!form.name.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Please provide a name</span>");
+    return false;
+  }
+  $(options.target + " span.comment_error").empty().after(
+    "<img src=\"figs/throbber.gif\" style=\"vertical-align: middle\"/>");
+  $(options.target + " input[@name=submit]").attr("disabled", true);
+}
+
+function ajaxifyForm(id) {
+  var q = qid(id);
+  
+  $("#form_" + q).ajaxForm({ beforeSubmit: beforeComment,
+			     success: function() { ajaxifyForm(id); },
+			     target: "#comments_" + q });
+}
+
+function toggleComment(id) {
+  $("#toggle_" + qid(id)).nextAll().toggle();
+  return false;
+}
+
+function loadComments(id) {
+  $("#comments_" + qid(id)).load(location.protocol + "//" + location.host +
+				 "/comments/single/" + id + "/", function() {
+    ajaxifyForm(id);
+  });
+  return false;
+}
+
+function loadAllComments() {
+  $("a.commenttoggle").each(function() {
+    var id = $(this).attr("pid");
+    if (id) {
+      loadComments(id);
+    }
+  });
+}
+
+$(document).ready(function() {
+  function loading(id) {
+    return " <span id=\"comments_" + id + "\" class=\"comment\">" +
+      "<span pid=\"" + id + "\" class=\"commenttoggle\">Loading..." +
+      "</span></span>";
+  }
+  $("div.toc>p")
+    .after("<p style='display: none;'><a onclick='return loadAllComments()'>" +
+	   "Load all comments (<b>slow</b>)</a></p>")
+    .toggle(function() { $(this).nextAll().show("normal"); },
+	    function() { $(this).nextAll().hide("normal"); })
+    .hover(function() { $(this).fadeTo("normal", 0.8); },
+	   function() { $(this).fadeTo("normal", 0.35); });
+  $("p[@id]").each(function() {
+    $(this).append(loading($(this).attr("id")));
+  });
+  $("pre[@id]").each(function() {
+    $(this).after(loading($(this).attr("id")));
+  });
+  var chapid = $("div.preface, div.chapter, div.appendix, div.bibliography").attr("id");
+  $("#chapterfeed").attr("href",
+			 $("#chapterfeed").attr("href") + chapid + "/");
+  $.getJSON(location.protocol + "//" + location.host + "/comments/chapter/" +
+	    chapid + "/count/", function(data) {
+    $.each(data, function(id, item) {
+      var s = item == 1 ? "" : "s";
+      $("#comments_" + qid(id) + " span.commenttoggle").replaceWith(
+        "<a class='commenttoggle' id='toggle_" + id + "' " +
+	"pid='" + id + "' " +
+	"onclick='return loadComments(\"" + id + "\")' " +
+	"href='comments: show / hide'>" + item + " comment" + s + "</a>");
+    });
+    $("span.commenttoggle").each(function() {
+      var id = $(this).attr("pid");
+      $(this).replaceWith("<a class='commenttoggle' id='toggle_" + id + "' " +
+			  "onclick='return loadComments(\"" + id + "\")' " +
+			  "href='comment: add'>No comments</a>");
+    });
+  });
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/javascript/jquery-min.js	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,31 @@
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else
+selector=[];}}else
+return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){var val=jQuery.browser.msie&&!option.attributes["value"].specified?option.text:option.value;if(one)return val;a.push(val);}}return a;}else
+return this[0].value.replace(/\r/g,"");}}else
+return this.each(function(){if(val.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,val)>=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else
+this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
+jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a<al;a++)if((prop=arguments[a])!=null)for(var i in prop){if(target==prop[i])continue;if(deep&&typeof prop[i]=='object'&&target[i])jQuery.extend(target[i],prop[i]);else if(prop[i]!=undefined)target[i]=prop[i];}return target;};var expando="jQuery"+(new Date()).getTime(),uuid=0,win={};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){if(window.execScript)window.execScript(data);else if(jQuery.browser.safari)window.setTimeout(data,0);else
+eval.call(window,data);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?win:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!=undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?win:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(obj,fn,args){if(args){if(obj.length==undefined)for(var i in obj)fn.apply(obj[i],args);else
+for(var i=0,ol=obj.length;i<ol;i++)if(fn.apply(obj[i],args)===false)break;}else{if(obj.length==undefined)for(var i in obj)fn.call(obj[i],i,obj[i]);else
+for(var i=0,ol=obj.length,val=obj[0];i<ol&&fn.call(val,i,val)!==false;val=obj[++i]){}}return obj;},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value))value=value.call(elem,[index]);var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value;},className:{add:function(elem,c){jQuery.each((c||"").split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur))elem.className+=(elem.className?" ":"")+cur;});},remove:function(elem,c){elem.className=c!=undefined?jQuery.grep(elem.className.split(/\s+/),function(cur){return!jQuery.className.has(c,cur);}).join(" "):"";},has:function(t,c){return jQuery.inArray(c,(t.className||t).toString().split(/\s+/))>-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a<stack.length;a++)if(color(stack[a])){swap[a]=stack[a].style.display;stack[a].style.display="block";}ret=prop=="display"&&swap[stack.length-1]!=null?"none":document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop)||"";for(a=0;a<swap.length;a++)if(swap[a]!=null)stack[a].style.display=swap[a];}if(prop=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});ret=elem.currentStyle[prop]||elem.currentStyle[newProp];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left;var runtimeStyle=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;elem.style.left=ret||0;ret=elem.style.pixelLeft+"px";elem.style.left=style;elem.runtimeStyle.left=runtimeStyle;}}return ret;},clean:function(a,doc){var r=[];doc=doc||document;jQuery.each(a,function(i,arg){if(!arg)return;if(arg.constructor==Number)arg=arg.toString();if(typeof arg=="string"){arg=arg.replace(/(<(\w+)[^>]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+"></"+tag+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||!s.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!s.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0)tb=div.firstChild&&div.firstChild.childNodes;else if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0)tb=div.childNodes;for(var n=tb.length-1;n>=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else
+r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i<al;i++)r.push(a[i]);else
+r=a.slice(0);return r;},inArray:function(b,a){for(var i=0,al=a.length;i<al;i++)if(a[i]==b)return i;return-1;},merge:function(first,second){if(jQuery.browser.msie){for(var i=0;second[i];i++)if(second[i].nodeType!=8)first.push(second[i]);}else
+for(var i=0;second[i];i++)first.push(second[i]);return first;},unique:function(first){var r=[],done={};try{for(var i=0,fl=first.length;i<fl;i++){var id=jQuery.data(first[i]);if(!done[id]){done[id]=true;r.push(first[i]);}}}catch(e){r=first;}return r;},grep:function(elems,fn,inv){if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++)if(!inv&&fn(elems[i],i)||inv&&!fn(elems[i],i))result.push(elems[i]);return result;},map:function(elems,fn){if(typeof fn=="string")fn=eval("false||function(a){return "+fn+"}");var result=[];for(var i=0,el=elems.length;i<el;i++){var val=fn(elems[i],i);if(val!==null&&val!=undefined){if(val.constructor!=Array)val=[val];result=result.concat(val);}}return result;}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",styleFloat:jQuery.browser.msie?"styleFloat":"cssFloat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected",maxlength:"maxLength"}});jQuery.each({parent:"a.parentNode",parents:"jQuery.dir(a,'parentNode')",next:"jQuery.nth(a,2,'nextSibling')",prev:"jQuery.nth(a,2,'previousSibling')",nextAll:"jQuery.dir(a,'nextSibling')",prevAll:"jQuery.dir(a,'previousSibling')",siblings:"jQuery.sibling(a.parentNode.firstChild,a)",children:"jQuery.sibling(a.firstChild)",contents:"jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"},function(i,n){jQuery.fn[i]=function(a){var ret=jQuery.map(this,n);if(a&&typeof a=="string")ret=jQuery.multiFilter(a,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(i,n){jQuery.fn[i]=function(){var a=arguments;return this.each(function(){for(var j=0,al=a.length;j<al;j++)jQuery(a[j])[n](this);});};});jQuery.each({removeAttr:function(key){jQuery.attr(this,key,"");this.removeAttribute(key);},addClass:function(c){jQuery.className.add(this,c);},removeClass:function(c){jQuery.className.remove(this,c);},toggleClass:function(c){jQuery.className[jQuery.className.has(this,c)?"remove":"add"](this,c);},remove:function(a){if(!a||jQuery.filter(a,[this]).r.length){jQuery.removeData(this);this.parentNode.removeChild(this);}},empty:function(){jQuery("*",this).each(function(){jQuery.removeData(this);});while(this.firstChild)this.removeChild(this.firstChild);}},function(i,n){jQuery.fn[i]=function(){return this.each(n,arguments);};});jQuery.each(["Height","Width"],function(i,name){var n=name.toLowerCase();jQuery.fn[n]=function(h){return this[0]==window?jQuery.browser.safari&&self["inner"+name]||jQuery.boxModel&&Math.max(document.documentElement["client"+name],document.body["client"+name])||document.body["client"+name]:this[0]==document?Math.max(document.body["scroll"+name],document.body["offset"+name]):h==undefined?(this.length?jQuery.css(this[0],n):null):this.css(n,h.constructor==String?h:h+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"i<m[3]-0",gt:"i>m[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&!context.nodeType)context=null;context=context||document;var ret=[context],done=[],last;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){var nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase()))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var nodeName=m[2],merge={};m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName.toUpperCase()){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=jQuery.filter(m[3],r,true).r;else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(\d*)n\+?(\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==1){if(last==0||node.nodeIndex==last)add=true;}else if((node.nodeIndex+last)%first==0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var f=jQuery.expr[m[1]];if(typeof f!="string")f=jQuery.expr[m[1]][m[2]];f=eval("false||function(a,i){return "+f+"}");r=jQuery.grep(r,f,not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(element,type,handler,data){if(jQuery.browser.msie&&element.setInterval!=undefined)element=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var parts=type.split(".");type=parts[0];handler.type=parts[1];var events=jQuery.data(element,"events")||jQuery.data(element,"events",{});var handle=jQuery.data(element,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(element,arguments);return val;});var handlers=events[type];if(!handlers){handlers=events[type]={};if(element.addEventListener)element.addEventListener(type,handle,false);else
+element.attachEvent("on"+type,handle);}handlers[handler.guid]=handler;this.global[type]=true;},guid:1,global:{},remove:function(element,type,handler){var events=jQuery.data(element,"events"),ret,index;if(typeof type=="string"){var parts=type.split(".");type=parts[0];}if(events){if(type&&type.type){handler=type.handler;type=type.type;}if(!type){for(type in events)this.remove(element,type);}else if(events[type]){if(handler)delete events[type][handler.guid];else
+for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(element.removeEventListener)element.removeEventListener(type,jQuery.data(element,"handle"),false);else
+element.detachEvent("on"+type,jQuery.data(element,"handle"));ret=null;delete events[type];}}for(ret in events)break;if(!ret){jQuery.removeData(element,"events");jQuery.removeData(element,"handle");}}},trigger:function(type,data,element,donative,extra){data=jQuery.makeArray(data||[]);if(!element){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{var val,ret,fn=jQuery.isFunction(element[type]||null),evt=!data[0]||!data[0].preventDefault;if(evt)data.unshift(this.fix({type:type,target:element}));data[0].type=type;if(jQuery.isFunction(jQuery.data(element,"handle")))val=jQuery.data(element,"handle").apply(element,data);if(!fn&&element["on"+type]&&element["on"+type].apply(element,data)===false)val=false;if(evt)data.shift();if(extra&&extra.apply(element,data)===false)val=false;if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(element,'a')&&type=="click")){this.triggered=true;element[type]();}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var c=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in c){args[0].handler=c[j];args[0].data=c[j].data;if(!parts[1]||c[j].type==parts[1]){var tmp=c[j].apply(this,args);if(val!==false)val=tmp;if(tmp===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target&&event.srcElement)event.target=event.srcElement;if(jQuery.browser.safari&&event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var e=document.documentElement,b=document.body;event.pageX=event.clientX+(e&&e.scrollLeft||b.scrollLeft||0);event.pageY=event.clientY+(e&&e.scrollTop||b.scrollTop||0);}if(!event.which&&(event.charCode||event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(){var a=arguments;return this.click(function(e){this.lastToggle=0==this.lastToggle?1:0;e.preventDefault();return a[this.lastToggle].apply(this,[e])||false;});},hover:function(f,g){function handleHover(e){var p=e.relatedTarget;while(p&&p!=this)try{p=p.parentNode;}catch(e){p=this;};if(p==this)return false;return(e.type=="mouseover"?f:g).apply(this,[e]);}return this.mouseover(handleHover).mouseout(handleHover);},ready:function(f){bindReady();if(jQuery.isReady)f.apply(document,[jQuery]);else
+jQuery.readyList.push(function(){return f.apply(this,[jQuery]);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}if(jQuery.browser.mozilla||jQuery.browser.opera)document.removeEventListener("DOMContentLoaded",jQuery.ready,false);if(!window.frames.length)jQuery(window).load(function(){jQuery("#__ie_init").remove();});}}});jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,o){jQuery.fn[o]=function(f){return f?this.bind(o,f):this.trigger(o);};});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(jQuery.browser.mozilla||jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);else if(jQuery.browser.msie){document.write("<scr"+"ipt id=__ie_init defer=true "+"src=//:><\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=s.data.replace(jsre,"="+jsonp);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
+jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();return xml;function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
+for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
+s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");if(this.oldblock=="none")this.oldblock="block";this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
+e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i<timers.length;i++)if(timers[i].elem==this)timers.splice(i--,1);}).dequeue();}});var queue=function(elem,type,array){if(!elem)return;var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.curCSS(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length)clearInterval(timer);},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(){var t=(new Date()).getTime();if(t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if(safari2&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})();
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/javascript/jquery.js	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2992 @@
+(function(){
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+	var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(selector, context) {
+	// If the context is a namespace object, return a new object
+	return this instanceof jQuery ?
+		this.init(selector, context) :
+		new jQuery(selector, context);
+};
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+	var _$ = $;
+	
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+jQuery.fn = jQuery.prototype = {
+	init: function(selector, context) {
+		// Make sure that a selection was provided
+		selector = selector || document;
+
+		// Handle HTML strings
+		if ( typeof selector  == "string" ) {
+			var m = quickExpr.exec(selector);
+			if ( m && (m[1] || !context) ) {
+				// HANDLE: $(html) -> $(array)
+				if ( m[1] )
+					selector = jQuery.clean( [ m[1] ], context );
+
+				// HANDLE: $("#id")
+				else {
+					var tmp = document.getElementById( m[3] );
+					if ( tmp )
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( tmp.id != m[3] )
+							return jQuery().find( selector );
+						else {
+							this[0] = tmp;
+							this.length = 1;
+							return this;
+						}
+					else
+						selector = [];
+				}
+
+			// HANDLE: $(expr)
+			} else
+				return new jQuery( context ).find( selector );
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction(selector) )
+			return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+		return this.setArray(
+			// HANDLE: $(array)
+			selector.constructor == Array && selector ||
+
+			// HANDLE: $(arraylike)
+			// Watch for when an array-like object is passed as the selector
+			(selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+			// HANDLE: $(*)
+			[ selector ] );
+	},
+	
+	jquery: "1.2.1",
+
+	size: function() {
+		return this.length;
+	},
+	
+	length: 0,
+
+	get: function( num ) {
+		return num == undefined ?
+
+			// Return a 'clean' array
+			jQuery.makeArray( this ) :
+
+			// Return just the object
+			this[num];
+	},
+	
+	pushStack: function( a ) {
+		var ret = jQuery(a);
+		ret.prevObject = this;
+		return ret;
+	},
+	
+	setArray: function( a ) {
+		this.length = 0;
+		Array.prototype.push.apply( this, a );
+		return this;
+	},
+
+	each: function( fn, args ) {
+		return jQuery.each( this, fn, args );
+	},
+
+	index: function( obj ) {
+		var pos = -1;
+		this.each(function(i){
+			if ( this == obj ) pos = i;
+		});
+		return pos;
+	},
+
+	attr: function( key, value, type ) {
+		var obj = key;
+		
+		// Look for the case where we're accessing a style value
+		if ( key.constructor == String )
+			if ( value == undefined )
+				return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+			else {
+				obj = {};
+				obj[ key ] = value;
+			}
+		
+		// Check to see if we're setting style values
+		return this.each(function(index){
+			// Set all the styles
+			for ( var prop in obj )
+				jQuery.attr(
+					type ? this.style : this,
+					prop, jQuery.prop(this, obj[prop], type, index, prop)
+				);
+		});
+	},
+
+	css: function( key, value ) {
+		return this.attr( key, value, "curCSS" );
+	},
+
+	text: function(e) {
+		if ( typeof e != "object" && e != null )
+			return this.empty().append( document.createTextNode( e ) );
+
+		var t = "";
+		jQuery.each( e || this, function(){
+			jQuery.each( this.childNodes, function(){
+				if ( this.nodeType != 8 )
+					t += this.nodeType != 1 ?
+						this.nodeValue : jQuery.fn.text([ this ]);
+			});
+		});
+		return t;
+	},
+
+	wrapAll: function(html) {
+		if ( this[0] )
+			// The elements to wrap the target around
+			jQuery(html, this[0].ownerDocument)
+				.clone()
+				.insertBefore(this[0])
+				.map(function(){
+					var elem = this;
+					while ( elem.firstChild )
+						elem = elem.firstChild;
+					return elem;
+				})
+				.append(this);
+
+		return this;
+	},
+
+	wrapInner: function(html) {
+		return this.each(function(){
+			jQuery(this).contents().wrapAll(html);
+		});
+	},
+
+	wrap: function(html) {
+		return this.each(function(){
+			jQuery(this).wrapAll(html);
+		});
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, 1, function(a){
+			this.appendChild( a );
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, -1, function(a){
+			this.insertBefore( a, this.firstChild );
+		});
+	},
+	
+	before: function() {
+		return this.domManip(arguments, false, 1, function(a){
+			this.parentNode.insertBefore( a, this );
+		});
+	},
+
+	after: function() {
+		return this.domManip(arguments, false, -1, function(a){
+			this.parentNode.insertBefore( a, this.nextSibling );
+		});
+	},
+
+	end: function() {
+		return this.prevObject || jQuery([]);
+	},
+
+	find: function(t) {
+		var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
+		return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
+			jQuery.unique( data ) : data );
+	},
+
+	clone: function(events) {
+		// Do the clone
+		var ret = this.map(function(){
+			return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+		});
+
+		// Need to set the expando to null on the cloned set if it exists
+		// removeData doesn't work here, IE removes it from the original as well
+		// this is primarily for IE but the data expando shouldn't be copied over in any browser
+		var clone = ret.find("*").andSelf().each(function(){
+			if ( this[ expando ] != undefined )
+				this[ expando ] = null;
+		});
+		
+		// Copy the events from the original to the clone
+		if (events === true)
+			this.find("*").andSelf().each(function(i) {
+				var events = jQuery.data(this, "events");
+				for ( var type in events )
+					for ( var handler in events[type] )
+						jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+			});
+
+		// Return the cloned set
+		return ret;
+	},
+
+	filter: function(t) {
+		return this.pushStack(
+			jQuery.isFunction( t ) &&
+			jQuery.grep(this, function(el, index){
+				return t.apply(el, [index]);
+			}) ||
+
+			jQuery.multiFilter(t,this) );
+	},
+
+	not: function(t) {
+		return this.pushStack(
+			t.constructor == String &&
+			jQuery.multiFilter(t, this, true) ||
+
+			jQuery.grep(this, function(a) {
+				return ( t.constructor == Array || t.jquery )
+					? jQuery.inArray( a, t ) < 0
+					: a != t;
+			})
+		);
+	},
+
+	add: function(t) {
+		return this.pushStack( jQuery.merge(
+			this.get(),
+			t.constructor == String ?
+				jQuery(t).get() :
+				t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
+					t : [t] )
+		);
+	},
+
+	is: function(expr) {
+		return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+	},
+
+	hasClass: function(expr) {
+		return this.is("." + expr);
+	},
+	
+	val: function( val ) {
+		if ( val == undefined ) {
+			if ( this.length ) {
+				var elem = this[0];
+		    	
+				// We need to handle select boxes special
+				if ( jQuery.nodeName(elem, "select") ) {
+					var index = elem.selectedIndex,
+						a = [],
+						options = elem.options,
+						one = elem.type == "select-one";
+					
+					// Nothing was selected
+					if ( index < 0 )
+						return null;
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[i];
+						if ( option.selected ) {
+							// Get the specifc value for the option
+							var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+							
+							// We don't need an array for one selects
+							if ( one )
+								return val;
+							
+							// Multi-Selects return an array
+							a.push(val);
+						}
+					}
+					
+					return a;
+					
+				// Everything else, we just grab the value
+				} else
+					return this[0].value.replace(/\r/g, "");
+			}
+		} else
+			return this.each(function(){
+				if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
+					this.checked = (jQuery.inArray(this.value, val) >= 0 ||
+						jQuery.inArray(this.name, val) >= 0);
+				else if ( jQuery.nodeName(this, "select") ) {
+					var tmp = val.constructor == Array ? val : [val];
+
+					jQuery("option", this).each(function(){
+						this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
+						jQuery.inArray(this.text, tmp) >= 0);
+					});
+
+					if ( !tmp.length )
+						this.selectedIndex = -1;
+				} else
+					this.value = val;
+			});
+	},
+	
+	html: function( val ) {
+		return val == undefined ?
+			( this.length ? this[0].innerHTML : null ) :
+			this.empty().append( val );
+	},
+
+	replaceWith: function( val ) {
+		return this.after( val ).remove();
+	},
+
+	eq: function(i){
+		return this.slice(i, i+1);
+	},
+
+	slice: function() {
+		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+	},
+
+	map: function(fn) {
+		return this.pushStack(jQuery.map( this, function(elem,i){
+			return fn.call( elem, i, elem );
+		}));
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	},
+	
+	domManip: function(args, table, dir, fn) {
+		var clone = this.length > 1, a; 
+
+		return this.each(function(){
+			if ( !a ) {
+				a = jQuery.clean(args, this.ownerDocument);
+				if ( dir < 0 )
+					a.reverse();
+			}
+
+			var obj = this;
+
+			if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
+				obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+
+			jQuery.each( a, function(){
+				var elem = clone ? this.cloneNode(true) : this;
+				if ( !evalScript(0, elem) )
+					fn.call( obj, elem );
+			});
+		});
+	}
+};
+
+function evalScript(i, elem){
+	var script = jQuery.nodeName(elem, "script");
+
+	if ( script ) {
+		if ( elem.src )
+			jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
+		else
+			jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+	
+		if ( elem.parentNode )
+			elem.parentNode.removeChild(elem);
+
+	} else if ( elem.nodeType == 1 )
+    jQuery("script", elem).each(evalScript);
+
+	return script;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+	// copy reference to target object
+	var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+	// Handle a deep copy situation
+	if ( target.constructor == Boolean ) {
+		deep = target;
+		target = arguments[1] || {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( al == 1 ) {
+		target = this;
+		a = 0;
+	}
+
+	var prop;
+
+	for ( ; a < al; a++ )
+		// Only deal with non-null/undefined values
+		if ( (prop = arguments[a]) != null )
+			// Extend the base object
+			for ( var i in prop ) {
+				// Prevent never-ending loop
+				if ( target == prop[i] )
+					continue;
+
+				// Recurse if we're merging object values
+				if ( deep && typeof prop[i] == 'object' && target[i] )
+					jQuery.extend( target[i], prop[i] );
+
+				// Don't bring in undefined values
+				else if ( prop[i] != undefined )
+					target[i] = prop[i];
+			}
+
+	// Return the modified object
+	return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+
+jQuery.extend({
+	noConflict: function(deep) {
+		window.$ = _$;
+		if ( deep )
+			window.jQuery = _jQuery;
+		return jQuery;
+	},
+
+	// This may seem like some crazy code, but trust me when I say that this
+	// is the only cross-browser way to do this. --John
+	isFunction: function( fn ) {
+		return !!fn && typeof fn != "string" && !fn.nodeName && 
+			fn.constructor != Array && /function/i.test( fn + "" );
+	},
+	
+	// check if an element is in a XML document
+	isXMLDoc: function(elem) {
+		return elem.documentElement && !elem.body ||
+			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+	},
+
+	// Evalulates a script in a global context
+	// Evaluates Async. in Safari 2 :-(
+	globalEval: function( data ) {
+		data = jQuery.trim( data );
+		if ( data ) {
+			if ( window.execScript )
+				window.execScript( data );
+			else if ( jQuery.browser.safari )
+				// safari doesn't provide a synchronous global eval
+				window.setTimeout( data, 0 );
+			else
+				eval.call( window, data );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+	},
+	
+	cache: {},
+	
+	data: function( elem, name, data ) {
+		elem = elem == window ? win : elem;
+
+		var id = elem[ expando ];
+
+		// Compute a unique ID for the element
+		if ( !id ) 
+			id = elem[ expando ] = ++uuid;
+
+		// Only generate the data cache if we're
+		// trying to access or manipulate it
+		if ( name && !jQuery.cache[ id ] )
+			jQuery.cache[ id ] = {};
+		
+		// Prevent overriding the named cache with undefined values
+		if ( data != undefined )
+			jQuery.cache[ id ][ name ] = data;
+		
+		// Return the named cache data, or the ID for the element	
+		return name ? jQuery.cache[ id ][ name ] : id;
+	},
+	
+	removeData: function( elem, name ) {
+		elem = elem == window ? win : elem;
+
+		var id = elem[ expando ];
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( jQuery.cache[ id ] ) {
+				// Remove the section of cache data
+				delete jQuery.cache[ id ][ name ];
+
+				// If we've removed all the data, remove the element's cache
+				name = "";
+				for ( name in jQuery.cache[ id ] ) break;
+				if ( !name )
+					jQuery.removeData( elem );
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			// Clean up the element expando
+			try {
+				delete elem[ expando ];
+			} catch(e){
+				// IE has trouble directly removing the expando
+				// but it's ok with using removeAttribute
+				if ( elem.removeAttribute )
+					elem.removeAttribute( expando );
+			}
+
+			// Completely remove the data cache
+			delete jQuery.cache[ id ];
+		}
+	},
+
+	// args is for internal usage only
+	each: function( obj, fn, args ) {
+		if ( args ) {
+			if ( obj.length == undefined )
+				for ( var i in obj )
+					fn.apply( obj[i], args );
+			else
+				for ( var i = 0, ol = obj.length; i < ol; i++ )
+					if ( fn.apply( obj[i], args ) === false ) break;
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( obj.length == undefined )
+				for ( var i in obj )
+					fn.call( obj[i], i, obj[i] );
+			else
+				for ( var i = 0, ol = obj.length, val = obj[0]; 
+					i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+		}
+
+		return obj;
+	},
+	
+	prop: function(elem, value, type, index, prop){
+			// Handle executable functions
+			if ( jQuery.isFunction( value ) )
+				value = value.call( elem, [index] );
+				
+			// exclude the following css properties to add px
+			var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+			// Handle passing in a number to a CSS property
+			return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+				value + "px" :
+				value;
+	},
+
+	className: {
+		// internal only, use addClass("class")
+		add: function( elem, c ){
+			jQuery.each( (c || "").split(/\s+/), function(i, cur){
+				if ( !jQuery.className.has( elem.className, cur ) )
+					elem.className += ( elem.className ? " " : "" ) + cur;
+			});
+		},
+
+		// internal only, use removeClass("class")
+		remove: function( elem, c ){
+			elem.className = c != undefined ?
+				jQuery.grep( elem.className.split(/\s+/), function(cur){
+					return !jQuery.className.has( c, cur );	
+				}).join(" ") : "";
+		},
+
+		// internal only, use is(".class")
+		has: function( t, c ) {
+			return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+		}
+	},
+
+	swap: function(e,o,f) {
+		for ( var i in o ) {
+			e.style["old"+i] = e.style[i];
+			e.style[i] = o[i];
+		}
+		f.apply( e, [] );
+		for ( var i in o )
+			e.style[i] = e.style["old"+i];
+	},
+
+	css: function(e,p) {
+		if ( p == "height" || p == "width" ) {
+			var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+
+			jQuery.each( d, function(){
+				old["padding" + this] = 0;
+				old["border" + this + "Width"] = 0;
+			});
+
+			jQuery.swap( e, old, function() {
+				if ( jQuery(e).is(':visible') ) {
+					oHeight = e.offsetHeight;
+					oWidth = e.offsetWidth;
+				} else {
+					e = jQuery(e.cloneNode(true))
+						.find(":radio").removeAttr("checked").end()
+						.css({
+							visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
+						}).appendTo(e.parentNode)[0];
+
+					var parPos = jQuery.css(e.parentNode,"position") || "static";
+					if ( parPos == "static" )
+						e.parentNode.style.position = "relative";
+
+					oHeight = e.clientHeight;
+					oWidth = e.clientWidth;
+
+					if ( parPos == "static" )
+						e.parentNode.style.position = "static";
+
+					e.parentNode.removeChild(e);
+				}
+			});
+
+			return p == "height" ? oHeight : oWidth;
+		}
+
+		return jQuery.curCSS( e, p );
+	},
+
+	curCSS: function(elem, prop, force) {
+		var ret, stack = [], swap = [];
+
+		// A helper method for determining if an element's values are broken
+		function color(a){
+			if ( !jQuery.browser.safari )
+				return false;
+
+			var ret = document.defaultView.getComputedStyle(a,null);
+			return !ret || ret.getPropertyValue("color") == "";
+		}
+
+		if (prop == "opacity" && jQuery.browser.msie) {
+			ret = jQuery.attr(elem.style, "opacity");
+			return ret == "" ? "1" : ret;
+		}
+		
+		if (prop.match(/float/i))
+			prop = styleFloat;
+
+		if (!force && elem.style[prop])
+			ret = elem.style[prop];
+
+		else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+			if (prop.match(/float/i))
+				prop = "float";
+
+			prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+			var cur = document.defaultView.getComputedStyle(elem, null);
+
+			if ( cur && !color(elem) )
+				ret = cur.getPropertyValue(prop);
+
+			// If the element isn't reporting its values properly in Safari
+			// then some display: none elements are involved
+			else {
+				// Locate all of the parent display: none elements
+				for ( var a = elem; a && color(a); a = a.parentNode )
+					stack.unshift(a);
+
+				// Go through and make them visible, but in reverse
+				// (It would be better if we knew the exact display type that they had)
+				for ( a = 0; a < stack.length; a++ )
+					if ( color(stack[a]) ) {
+						swap[a] = stack[a].style.display;
+						stack[a].style.display = "block";
+					}
+
+				// Since we flip the display style, we have to handle that
+				// one special, otherwise get the value
+				ret = prop == "display" && swap[stack.length-1] != null ?
+					"none" :
+					document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+				// Finally, revert the display styles back
+				for ( a = 0; a < swap.length; a++ )
+					if ( swap[a] != null )
+						stack[a].style.display = swap[a];
+			}
+
+			if ( prop == "opacity" && ret == "" )
+				ret = "1";
+
+		} else if (elem.currentStyle) {
+			var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
+			ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+			// From the awesome hack by Dean Edwards
+			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+			// If we're not dealing with a regular pixel number
+			// but a number that has a weird ending, we need to convert it to pixels
+			if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
+				var style = elem.style.left;
+				var runtimeStyle = elem.runtimeStyle.left;
+				elem.runtimeStyle.left = elem.currentStyle.left;
+				elem.style.left = ret || 0;
+				ret = elem.style.pixelLeft + "px";
+				elem.style.left = style;
+				elem.runtimeStyle.left = runtimeStyle;
+			}
+		}
+
+		return ret;
+	},
+	
+	clean: function(a, doc) {
+		var r = [];
+		doc = doc || document;
+
+		jQuery.each( a, function(i,arg){
+			if ( !arg ) return;
+
+			if ( arg.constructor == Number )
+				arg = arg.toString();
+			
+			// Convert html string into DOM nodes
+			if ( typeof arg == "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
+					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">";
+				});
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+
+				var wrap =
+					// option or optgroup
+					!s.indexOf("<opt") &&
+					[1, "<select>", "</select>"] ||
+					
+					!s.indexOf("<leg") &&
+					[1, "<fieldset>", "</fieldset>"] ||
+					
+					s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+					[1, "<table>", "</table>"] ||
+					
+					!s.indexOf("<tr") &&
+					[2, "<table><tbody>", "</tbody></table>"] ||
+					
+				 	// <thead> matched above
+					(!s.indexOf("<td") || !s.indexOf("<th")) &&
+					[3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+					
+					!s.indexOf("<col") &&
+					[2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+					// IE can't serialize <link> and <script> tags normally
+					jQuery.browser.msie &&
+					[1, "div<div>", "</div>"] ||
+					
+					[0,"",""];
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + arg + wrap[2];
+				
+				// Move to the right depth
+				while ( wrap[0]-- )
+					div = div.lastChild;
+				
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( jQuery.browser.msie ) {
+					
+					// String was a <table>, *may* have spurious <tbody>
+					if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) 
+						tb = div.firstChild && div.firstChild.childNodes;
+						
+					// String was a bare <thead> or <tfoot>
+					else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
+						tb = div.childNodes;
+
+					for ( var n = tb.length-1; n >= 0 ; --n )
+						if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
+							tb[n].parentNode.removeChild(tb[n]);
+	
+					// IE completely kills leading whitespace when innerHTML is used	
+					if ( /^\s/.test(arg) )	
+						div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
+
+				}
+				
+				arg = jQuery.makeArray( div.childNodes );
+			}
+
+			if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
+				return;
+
+			if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
+				r.push( arg );
+			else
+				r = jQuery.merge( r, arg );
+
+		});
+
+		return r;
+	},
+	
+	attr: function(elem, name, value){
+		var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+
+		// Safari mis-reports the default selected property of a hidden option
+		// Accessing the parent's selectedIndex property fixes it
+		if ( name == "selected" && jQuery.browser.safari )
+			elem.parentNode.selectedIndex;
+		
+		// Certain attributes only work when accessed via the old DOM 0 way
+		if ( fix[name] ) {
+			if ( value != undefined ) elem[fix[name]] = value;
+			return elem[fix[name]];
+		} else if ( jQuery.browser.msie && name == "style" )
+			return jQuery.attr( elem.style, "cssText", value );
+
+		else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
+			return elem.getAttributeNode(name).nodeValue;
+
+		// IE elem.getAttribute passes even for style
+		else if ( elem.tagName ) {
+
+			if ( value != undefined ) {
+				if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode )
+					throw "type property can't be changed";
+				elem.setAttribute( name, value );
+			}
+
+			if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) ) 
+				return elem.getAttribute( name, 2 );
+
+			return elem.getAttribute( name );
+
+		// elem is actually elem.style ... set the style
+		} else {
+			// IE actually uses filters for opacity
+			if ( name == "opacity" && jQuery.browser.msie ) {
+				if ( value != undefined ) {
+					// IE has trouble with opacity if it does not have layout
+					// Force it by setting the zoom level
+					elem.zoom = 1; 
+	
+					// Set the alpha filter to set the opacity
+					elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
+						(parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+				}
+	
+				return elem.filter ? 
+					(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
+			}
+			name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
+			if ( value != undefined ) elem[name] = value;
+			return elem[name];
+		}
+	},
+	
+	trim: function(t){
+		return (t||"").replace(/^\s+|\s+$/g, "");
+	},
+
+	makeArray: function( a ) {
+		var r = [];
+
+		// Need to use typeof to fight Safari childNodes crashes
+		if ( typeof a != "array" )
+			for ( var i = 0, al = a.length; i < al; i++ )
+				r.push( a[i] );
+		else
+			r = a.slice( 0 );
+
+		return r;
+	},
+
+	inArray: function( b, a ) {
+		for ( var i = 0, al = a.length; i < al; i++ )
+			if ( a[i] == b )
+				return i;
+		return -1;
+	},
+
+	merge: function(first, second) {
+		// We have to loop this way because IE & Opera overwrite the length
+		// expando of getElementsByTagName
+
+		// Also, we need to make sure that the correct elements are being returned
+		// (IE returns comment nodes in a '*' query)
+		if ( jQuery.browser.msie ) {
+			for ( var i = 0; second[i]; i++ )
+				if ( second[i].nodeType != 8 )
+					first.push(second[i]);
+		} else
+			for ( var i = 0; second[i]; i++ )
+				first.push(second[i]);
+
+		return first;
+	},
+
+	unique: function(first) {
+		var r = [], done = {};
+
+		try {
+			for ( var i = 0, fl = first.length; i < fl; i++ ) {
+				var id = jQuery.data(first[i]);
+				if ( !done[id] ) {
+					done[id] = true;
+					r.push(first[i]);
+				}
+			}
+		} catch(e) {
+			r = first;
+		}
+
+		return r;
+	},
+
+	grep: function(elems, fn, inv) {
+		// If a string is passed in for the function, make a function
+		// for it (a handy shortcut)
+		if ( typeof fn == "string" )
+			fn = eval("false||function(a,i){return " + fn + "}");
+
+		var result = [];
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, el = elems.length; i < el; i++ )
+			if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
+				result.push( elems[i] );
+
+		return result;
+	},
+
+	map: function(elems, fn) {
+		// If a string is passed in for the function, make a function
+		// for it (a handy shortcut)
+		if ( typeof fn == "string" )
+			fn = eval("false||function(a){return " + fn + "}");
+
+		var result = [];
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, el = elems.length; i < el; i++ ) {
+			var val = fn(elems[i],i);
+
+			if ( val !== null && val != undefined ) {
+				if ( val.constructor != Array ) val = [val];
+				result = result.concat( val );
+			}
+		}
+
+		return result;
+	}
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+	version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+	safari: /webkit/.test(userAgent),
+	opera: /opera/.test(userAgent),
+	msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+	mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+};
+
+var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+	
+jQuery.extend({
+	// Check to see if the W3C box model is being used
+	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+	
+	styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
+	
+	props: {
+		"for": "htmlFor",
+		"class": "className",
+		"float": styleFloat,
+		cssFloat: styleFloat,
+		styleFloat: styleFloat,
+		innerHTML: "innerHTML",
+		className: "className",
+		value: "value",
+		disabled: "disabled",
+		checked: "checked",
+		readonly: "readOnly",
+		selected: "selected",
+		maxlength: "maxLength"
+	}
+});
+
+jQuery.each({
+	parent: "a.parentNode",
+	parents: "jQuery.dir(a,'parentNode')",
+	next: "jQuery.nth(a,2,'nextSibling')",
+	prev: "jQuery.nth(a,2,'previousSibling')",
+	nextAll: "jQuery.dir(a,'nextSibling')",
+	prevAll: "jQuery.dir(a,'previousSibling')",
+	siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
+	children: "jQuery.sibling(a.firstChild)",
+	contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
+}, function(i,n){
+	jQuery.fn[ i ] = function(a) {
+		var ret = jQuery.map(this,n);
+		if ( a && typeof a == "string" )
+			ret = jQuery.multiFilter(a,ret);
+		return this.pushStack( jQuery.unique(ret) );
+	};
+});
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function(i,n){
+	jQuery.fn[ i ] = function(){
+		var a = arguments;
+		return this.each(function(){
+			for ( var j = 0, al = a.length; j < al; j++ )
+				jQuery(a[j])[n]( this );
+		});
+	};
+});
+
+jQuery.each( {
+	removeAttr: function( key ) {
+		jQuery.attr( this, key, "" );
+		this.removeAttribute( key );
+	},
+	addClass: function(c){
+		jQuery.className.add(this,c);
+	},
+	removeClass: function(c){
+		jQuery.className.remove(this,c);
+	},
+	toggleClass: function( c ){
+		jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
+	},
+	remove: function(a){
+		if ( !a || jQuery.filter( a, [this] ).r.length ) {
+			jQuery.removeData( this );
+			this.parentNode.removeChild( this );
+		}
+	},
+	empty: function() {
+		// Clean up the cache
+		jQuery("*", this).each(function(){ jQuery.removeData(this); });
+
+		while ( this.firstChild )
+			this.removeChild( this.firstChild );
+	}
+}, function(i,n){
+	jQuery.fn[ i ] = function() {
+		return this.each( n, arguments );
+	};
+});
+
+jQuery.each( [ "Height", "Width" ], function(i,name){
+	var n = name.toLowerCase();
+	
+	jQuery.fn[ n ] = function(h) {
+		return this[0] == window ?
+			jQuery.browser.safari && self["inner" + name] ||
+			jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
+			document.body["client" + name] :
+		
+			this[0] == document ?
+				Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
+        
+				h == undefined ?
+					( this.length ? jQuery.css( this[0], n ) : null ) :
+					this.css( n, h.constructor == String ? h : h + "px" );
+	};
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+		"(?:[\\w*_-]|\\\\.)" :
+		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+	expr: {
+		"": "m[2]=='*'||jQuery.nodeName(a,m[2])",
+		"#": "a.getAttribute('id')==m[2]",
+		":": {
+			// Position Checks
+			lt: "i<m[3]-0",
+			gt: "i>m[3]-0",
+			nth: "m[3]-0==i",
+			eq: "m[3]-0==i",
+			first: "i==0",
+			last: "i==r.length-1",
+			even: "i%2==0",
+			odd: "i%2",
+
+			// Child Checks
+			"first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
+			"last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
+			"only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+
+			// Parent Checks
+			parent: "a.firstChild",
+			empty: "!a.firstChild",
+
+			// Text Check
+			contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",
+
+			// Visibility
+			visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
+			hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+
+			// Form attributes
+			enabled: "!a.disabled",
+			disabled: "a.disabled",
+			checked: "a.checked",
+			selected: "a.selected||jQuery.attr(a,'selected')",
+
+			// Form elements
+			text: "'text'==a.type",
+			radio: "'radio'==a.type",
+			checkbox: "'checkbox'==a.type",
+			file: "'file'==a.type",
+			password: "'password'==a.type",
+			submit: "'submit'==a.type",
+			image: "'image'==a.type",
+			reset: "'reset'==a.type",
+			button: '"button"==a.type||jQuery.nodeName(a,"button")',
+			input: "/input|select|textarea|button/i.test(a.nodeName)",
+
+			// :has()
+			has: "jQuery.find(m[3],a).length",
+
+			// :header
+			header: "/h\\d/i.test(a.nodeName)",
+
+			// :animated
+			animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+		}
+	},
+	
+	// The regular expressions that power the parsing engine
+	parse: [
+		// Match: [@value='test'], [@foo]
+		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+		// Match: :contains('foo')
+		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+		// Match: :even, :last-chlid, #id, .class
+		new RegExp("^([:.#]*)(" + chars + "+)")
+	],
+
+	multiFilter: function( expr, elems, not ) {
+		var old, cur = [];
+
+		while ( expr && expr != old ) {
+			old = expr;
+			var f = jQuery.filter( expr, elems, not );
+			expr = f.t.replace(/^\s*,\s*/, "" );
+			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+		}
+
+		return cur;
+	},
+
+	find: function( t, context ) {
+		// Quickly handle non-string expressions
+		if ( typeof t != "string" )
+			return [ t ];
+
+		// Make sure that the context is a DOM Element
+		if ( context && !context.nodeType )
+			context = null;
+
+		// Set the correct context (if none is provided)
+		context = context || document;
+
+		// Initialize the search
+		var ret = [context], done = [], last;
+
+		// Continue while a selector expression exists, and while
+		// we're no longer looping upon ourselves
+		while ( t && last != t ) {
+			var r = [];
+			last = t;
+
+			t = jQuery.trim(t);
+
+			var foundToken = false;
+
+			// An attempt at speeding up child selectors that
+			// point to a specific element tag
+			var re = quickChild;
+			var m = re.exec(t);
+
+			if ( m ) {
+				var nodeName = m[1].toUpperCase();
+
+				// Perform our own iteration and filter
+				for ( var i = 0; ret[i]; i++ )
+					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+							r.push( c );
+
+				ret = r;
+				t = t.replace( re, "" );
+				if ( t.indexOf(" ") == 0 ) continue;
+				foundToken = true;
+			} else {
+				re = /^([>+~])\s*(\w*)/i;
+
+				if ( (m = re.exec(t)) != null ) {
+					r = [];
+
+					var nodeName = m[2], merge = {};
+					m = m[1];
+
+					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+						for ( ; n; n = n.nextSibling )
+							if ( n.nodeType == 1 ) {
+								var id = jQuery.data(n);
+
+								if ( m == "~" && merge[id] ) break;
+								
+								if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+									if ( m == "~" ) merge[id] = true;
+									r.push( n );
+								}
+								
+								if ( m == "+" ) break;
+							}
+					}
+
+					ret = r;
+
+					// And remove the token
+					t = jQuery.trim( t.replace( re, "" ) );
+					foundToken = true;
+				}
+			}
+
+			// See if there's still an expression, and that we haven't already
+			// matched a token
+			if ( t && !foundToken ) {
+				// Handle multiple expressions
+				if ( !t.indexOf(",") ) {
+					// Clean the result set
+					if ( context == ret[0] ) ret.shift();
+
+					// Merge the result sets
+					done = jQuery.merge( done, ret );
+
+					// Reset the context
+					r = ret = [context];
+
+					// Touch up the selector string
+					t = " " + t.substr(1,t.length);
+
+				} else {
+					// Optimize for the case nodeName#idName
+					var re2 = quickID;
+					var m = re2.exec(t);
+					
+					// Re-organize the results, so that they're consistent
+					if ( m ) {
+					   m = [ 0, m[2], m[3], m[1] ];
+
+					} else {
+						// Otherwise, do a traditional filter check for
+						// ID, class, and element selectors
+						re2 = quickClass;
+						m = re2.exec(t);
+					}
+
+					m[2] = m[2].replace(/\\/g, "");
+
+					var elem = ret[ret.length-1];
+
+					// Try to do a global search by ID, where we can
+					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+						// Optimization for HTML document case
+						var oid = elem.getElementById(m[2]);
+						
+						// Do a quick check for the existence of the actual ID attribute
+						// to avoid selecting by the name attribute in IE
+						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+						// Do a quick check for node name (where applicable) so
+						// that div#foo searches will be really fast
+						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+					} else {
+						// We need to find all descendant elements
+						for ( var i = 0; ret[i]; i++ ) {
+							// Grab the tag name being searched for
+							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+							// Handle IE7 being really dumb about <object>s
+							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+								tag = "param";
+
+							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+						}
+
+						// It's faster to filter by class and be done with it
+						if ( m[1] == "." )
+							r = jQuery.classFilter( r, m[2] );
+
+						// Same with ID filtering
+						if ( m[1] == "#" ) {
+							var tmp = [];
+
+							// Try to find the element with the ID
+							for ( var i = 0; r[i]; i++ )
+								if ( r[i].getAttribute("id") == m[2] ) {
+									tmp = [ r[i] ];
+									break;
+								}
+
+							r = tmp;
+						}
+
+						ret = r;
+					}
+
+					t = t.replace( re2, "" );
+				}
+
+			}
+
+			// If a selector string still exists
+			if ( t ) {
+				// Attempt to filter it
+				var val = jQuery.filter(t,r);
+				ret = r = val.r;
+				t = jQuery.trim(val.t);
+			}
+		}
+
+		// An error occurred with the selector;
+		// just return an empty set instead
+		if ( t )
+			ret = [];
+
+		// Remove the root context
+		if ( ret && context == ret[0] )
+			ret.shift();
+
+		// And combine the results
+		done = jQuery.merge( done, ret );
+
+		return done;
+	},
+
+	classFilter: function(r,m,not){
+		m = " " + m + " ";
+		var tmp = [];
+		for ( var i = 0; r[i]; i++ ) {
+			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+			if ( !not && pass || not && !pass )
+				tmp.push( r[i] );
+		}
+		return tmp;
+	},
+
+	filter: function(t,r,not) {
+		var last;
+
+		// Look for common filter expressions
+		while ( t  && t != last ) {
+			last = t;
+
+			var p = jQuery.parse, m;
+
+			for ( var i = 0; p[i]; i++ ) {
+				m = p[i].exec( t );
+
+				if ( m ) {
+					// Remove what we just matched
+					t = t.substring( m[0].length );
+
+					m[2] = m[2].replace(/\\/g, "");
+					break;
+				}
+			}
+
+			if ( !m )
+				break;
+
+			// :not() is a special case that can be optimized by
+			// keeping it out of the expression list
+			if ( m[1] == ":" && m[2] == "not" )
+				r = jQuery.filter(m[3], r, true).r;
+
+			// We can get a big speed boost by filtering by class here
+			else if ( m[1] == "." )
+				r = jQuery.classFilter(r, m[2], not);
+
+			else if ( m[1] == "[" ) {
+				var tmp = [], type = m[3];
+				
+				for ( var i = 0, rl = r.length; i < rl; i++ ) {
+					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+					
+					if ( z == null || /href|src|selected/.test(m[2]) )
+						z = jQuery.attr(a,m[2]) || '';
+
+					if ( (type == "" && !!z ||
+						 type == "=" && z == m[5] ||
+						 type == "!=" && z != m[5] ||
+						 type == "^=" && z && !z.indexOf(m[5]) ||
+						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+							tmp.push( a );
+				}
+				
+				r = tmp;
+
+			// We can get a speed boost by handling nth-child here
+			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
+				var merge = {}, tmp = [],
+					test = /(\d*)n\+?(\d*)/.exec(
+						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+						!/\D/.test(m[3]) && "n+" + m[3] || m[3]),
+					first = (test[1] || 1) - 0, last = test[2] - 0;
+
+				for ( var i = 0, rl = r.length; i < rl; i++ ) {
+					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+					if ( !merge[id] ) {
+						var c = 1;
+
+						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+							if ( n.nodeType == 1 )
+								n.nodeIndex = c++;
+
+						merge[id] = true;
+					}
+
+					var add = false;
+
+					if ( first == 1 ) {
+						if ( last == 0 || node.nodeIndex == last )
+							add = true;
+					} else if ( (node.nodeIndex + last) % first == 0 )
+						add = true;
+
+					if ( add ^ not )
+						tmp.push( node );
+				}
+
+				r = tmp;
+
+			// Otherwise, find the expression to execute
+			} else {
+				var f = jQuery.expr[m[1]];
+				if ( typeof f != "string" )
+					f = jQuery.expr[m[1]][m[2]];
+
+				// Build a custom macro to enclose it
+				f = eval("false||function(a,i){return " + f + "}");
+
+				// Execute it against the current filter
+				r = jQuery.grep( r, f, not );
+			}
+		}
+
+		// Return an array of filtered elements (r)
+		// and the modified expression string (t)
+		return { r: r, t: t };
+	},
+
+	dir: function( elem, dir ){
+		var matched = [];
+		var cur = elem[dir];
+		while ( cur && cur != document ) {
+			if ( cur.nodeType == 1 )
+				matched.push( cur );
+			cur = cur[dir];
+		}
+		return matched;
+	},
+	
+	nth: function(cur,result,dir,elem){
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] )
+			if ( cur.nodeType == 1 && ++num == result )
+				break;
+
+		return cur;
+	},
+	
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType == 1 && (!elem || n != elem) )
+				r.push( n );
+		}
+
+		return r;
+	}
+});
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from 
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function(element, type, handler, data) {
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( jQuery.browser.msie && element.setInterval != undefined )
+			element = window;
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid )
+			handler.guid = this.guid++;
+			
+		// if data is passed, bind to handler 
+		if( data != undefined ) { 
+        		// Create temporary function pointer to original handler 
+			var fn = handler; 
+
+			// Create unique handler function, wrapped around original handler 
+			handler = function() { 
+				// Pass arguments and context to original handler 
+				return fn.apply(this, arguments); 
+			};
+
+			// Store data in unique handler 
+			handler.data = data;
+
+			// Set the guid of unique handler to the same of original handler, so it can be removed 
+			handler.guid = fn.guid;
+		}
+
+		// Namespaced event handlers
+		var parts = type.split(".");
+		type = parts[0];
+		handler.type = parts[1];
+
+		// Init the element's event structure
+		var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
+		
+		var handle = jQuery.data(element, "handle", function(){
+			// returned undefined or false
+			var val;
+
+			// Handle the second event of a trigger and when
+			// an event is called after a page has unloaded
+			if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+				return val;
+			
+			val = jQuery.event.handle.apply(element, arguments);
+			
+			return val;
+		});
+
+		// Get the current list of functions bound to this event
+		var handlers = events[type];
+
+		// Init the event handler queue
+		if (!handlers) {
+			handlers = events[type] = {};	
+			
+			// And bind the global event handler to the element
+			if (element.addEventListener)
+				element.addEventListener(type, handle, false);
+			else
+				element.attachEvent("on" + type, handle);
+		}
+
+		// Add the function to the element's handler list
+		handlers[handler.guid] = handler;
+
+		// Keep track of which events have been used, for global triggering
+		this.global[type] = true;
+	},
+
+	guid: 1,
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function(element, type, handler) {
+		var events = jQuery.data(element, "events"), ret, index;
+
+		// Namespaced event handlers
+		if ( typeof type == "string" ) {
+			var parts = type.split(".");
+			type = parts[0];
+		}
+
+		if ( events ) {
+			// type is actually an event object here
+			if ( type && type.type ) {
+				handler = type.handler;
+				type = type.type;
+			}
+			
+			if ( !type ) {
+				for ( type in events )
+					this.remove( element, type );
+
+			} else if ( events[type] ) {
+				// remove the given handler for the given type
+				if ( handler )
+					delete events[type][handler.guid];
+				
+				// remove all handlers for the given type
+				else
+					for ( handler in events[type] )
+						// Handle the removal of namespaced events
+						if ( !parts[1] || events[type][handler].type == parts[1] )
+							delete events[type][handler];
+
+				// remove generic event handler if no more handlers exist
+				for ( ret in events[type] ) break;
+				if ( !ret ) {
+					if (element.removeEventListener)
+						element.removeEventListener(type, jQuery.data(element, "handle"), false);
+					else
+						element.detachEvent("on" + type, jQuery.data(element, "handle"));
+					ret = null;
+					delete events[type];
+				}
+			}
+
+			// Remove the expando if it's no longer used
+			for ( ret in events ) break;
+			if ( !ret ) {
+				jQuery.removeData( element, "events" );
+				jQuery.removeData( element, "handle" );
+			}
+		}
+	},
+
+	trigger: function(type, data, element, donative, extra) {
+		// Clone the incoming data, if any
+		data = jQuery.makeArray(data || []);
+
+		// Handle a global trigger
+		if ( !element ) {
+			// Only trigger if we've ever bound an event for it
+			if ( this.global[type] )
+				jQuery("*").add([window, document]).trigger(type, data);
+
+		// Handle triggering a single element
+		} else {
+			var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
+				// Check to see if we need to provide a fake event, or not
+				evt = !data[0] || !data[0].preventDefault;
+			
+			// Pass along a fake event
+			if ( evt )
+				data.unshift( this.fix({ type: type, target: element }) );
+
+			// Enforce the right trigger type
+			data[0].type = type;
+
+			// Trigger the event
+			if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
+				val = jQuery.data(element, "handle").apply( element, data );
+
+			// Handle triggering native .onfoo handlers
+			if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
+				val = false;
+
+			// Extra functions don't get the custom event object
+			if ( evt )
+				data.shift();
+
+			// Handle triggering of extra function
+			if ( extra && extra.apply( element, data ) === false )
+				val = false;
+
+			// Trigger the native events (except for clicks on links)
+			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
+				this.triggered = true;
+				element[ type ]();
+			}
+
+			this.triggered = false;
+		}
+
+		return val;
+	},
+
+	handle: function(event) {
+		// returned undefined or false
+		var val;
+
+		// Empty object is for triggered events with no data
+		event = jQuery.event.fix( event || window.event || {} ); 
+
+		// Namespaced event handlers
+		var parts = event.type.split(".");
+		event.type = parts[0];
+
+		var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+		args.unshift( event );
+
+		for ( var j in c ) {
+			// Pass in a reference to the handler function itself
+			// So that we can later remove it
+			args[0].handler = c[j];
+			args[0].data = c[j].data;
+
+			// Filter the functions by class
+			if ( !parts[1] || c[j].type == parts[1] ) {
+				var tmp = c[j].apply( this, args );
+
+				if ( val !== false )
+					val = tmp;
+
+				if ( tmp === false ) {
+					event.preventDefault();
+					event.stopPropagation();
+				}
+			}
+		}
+
+		// Clean up added properties in IE to prevent memory leak
+		if (jQuery.browser.msie)
+			event.target = event.preventDefault = event.stopPropagation =
+				event.handler = event.data = null;
+
+		return val;
+	},
+
+	fix: function(event) {
+		// store a copy of the original event object 
+		// and clone to set read-only properties
+		var originalEvent = event;
+		event = jQuery.extend({}, originalEvent);
+		
+		// add preventDefault and stopPropagation since 
+		// they will not work on the clone
+		event.preventDefault = function() {
+			// if preventDefault exists run it on the original event
+			if (originalEvent.preventDefault)
+				originalEvent.preventDefault();
+			// otherwise set the returnValue property of the original event to false (IE)
+			originalEvent.returnValue = false;
+		};
+		event.stopPropagation = function() {
+			// if stopPropagation exists run it on the original event
+			if (originalEvent.stopPropagation)
+				originalEvent.stopPropagation();
+			// otherwise set the cancelBubble property of the original event to true (IE)
+			originalEvent.cancelBubble = true;
+		};
+		
+		// Fix target property, if necessary
+		if ( !event.target && event.srcElement )
+			event.target = event.srcElement;
+				
+		// check if target is a textnode (safari)
+		if (jQuery.browser.safari && event.target.nodeType == 3)
+			event.target = originalEvent.target.parentNode;
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement )
+			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var e = document.documentElement, b = document.body;
+			event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
+			event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+		}
+			
+		// Add which for key events
+		if ( !event.which && (event.charCode || event.keyCode) )
+			event.which = event.charCode || event.keyCode;
+		
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey )
+			event.metaKey = event.ctrlKey;
+
+		// Add which for click: 1 == left; 2 == middle; 3 == right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button )
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+			
+		return event;
+	}
+};
+
+jQuery.fn.extend({
+	bind: function( type, data, fn ) {
+		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+			jQuery.event.add( this, type, fn || data, fn && data );
+		});
+	},
+	
+	one: function( type, data, fn ) {
+		return this.each(function(){
+			jQuery.event.add( this, type, function(event) {
+				jQuery(this).unbind(event);
+				return (fn || data).apply( this, arguments);
+			}, fn && data);
+		});
+	},
+
+	unbind: function( type, fn ) {
+		return this.each(function(){
+			jQuery.event.remove( this, type, fn );
+		});
+	},
+
+	trigger: function( type, data, fn ) {
+		return this.each(function(){
+			jQuery.event.trigger( type, data, this, true, fn );
+		});
+	},
+
+	triggerHandler: function( type, data, fn ) {
+		if ( this[0] )
+			return jQuery.event.trigger( type, data, this[0], false, fn );
+	},
+
+	toggle: function() {
+		// Save reference to arguments for access in closure
+		var a = arguments;
+
+		return this.click(function(e) {
+			// Figure out which function to execute
+			this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+			
+			// Make sure that clicks stop
+			e.preventDefault();
+			
+			// and execute the function
+			return a[this.lastToggle].apply( this, [e] ) || false;
+		});
+	},
+
+	hover: function(f,g) {
+		
+		// A private function for handling mouse 'hovering'
+		function handleHover(e) {
+			// Check if mouse(over|out) are still within the same parent element
+			var p = e.relatedTarget;
+	
+			// Traverse up the tree
+			while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
+			
+			// If we actually just moused on to a sub-element, ignore it
+			if ( p == this ) return false;
+			
+			// Execute the right function
+			return (e.type == "mouseover" ? f : g).apply(this, [e]);
+		}
+		
+		// Bind the function to the two event listeners
+		return this.mouseover(handleHover).mouseout(handleHover);
+	},
+	
+	ready: function(f) {
+		// Attach the listeners
+		bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady )
+			// Execute the function immediately
+			f.apply( document, [jQuery] );
+			
+		// Otherwise, remember the function for later
+		else
+			// Add the function to the wait list
+			jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
+	
+		return this;
+	}
+});
+
+jQuery.extend({
+	/*
+	 * All the code that makes DOM Ready work nicely.
+	 */
+	isReady: false,
+	readyList: [],
+	
+	// Handle when the DOM is ready
+	ready: function() {
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.isReady ) {
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+			
+			// If there are functions bound, to execute
+			if ( jQuery.readyList ) {
+				// Execute all of them
+				jQuery.each( jQuery.readyList, function(){
+					this.apply( document );
+				});
+				
+				// Reset the list of functions
+				jQuery.readyList = null;
+			}
+			// Remove event listener to avoid memory leak
+			if ( jQuery.browser.mozilla || jQuery.browser.opera )
+				document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
+			
+			// Remove script element used by IE hack
+			if( !window.frames.length ) // don't remove if frames are present (#1187)
+				jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+		}
+	}
+});
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
+	"submit,keydown,keypress,keyup,error").split(","), function(i,o){
+	
+	// Handle event binding
+	jQuery.fn[o] = function(f){
+		return f ? this.bind(o, f) : this.trigger(o);
+	};
+});
+
+var readyBound = false;
+
+function bindReady(){
+	if ( readyBound ) return;
+	readyBound = true;
+
+	// If Mozilla is used
+	if ( jQuery.browser.mozilla || jQuery.browser.opera )
+		// Use the handy event callback
+		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+	
+	// If IE is used, use the excellent hack by Matthias Miller
+	// http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
+	else if ( jQuery.browser.msie ) {
+	
+		// Only works if you document.write() it
+		document.write("<scr" + "ipt id=__ie_init defer=true " + 
+			"src=//:><\/script>");
+	
+		// Use the defer script hack
+		var script = document.getElementById("__ie_init");
+		
+		// script does not exist if jQuery is loaded dynamically
+		if ( script ) 
+			script.onreadystatechange = function() {
+				if ( this.readyState != "complete" ) return;
+				jQuery.ready();
+			};
+	
+		// Clear from memory
+		script = null;
+	
+	// If Safari  is used
+	} else if ( jQuery.browser.safari )
+		// Continually check to see if the document.readyState is valid
+		jQuery.safariTimer = setInterval(function(){
+			// loaded and complete are both valid states
+			if ( document.readyState == "loaded" || 
+				document.readyState == "complete" ) {
+	
+				// If either one are found, remove the timer
+				clearInterval( jQuery.safariTimer );
+				jQuery.safariTimer = null;
+	
+				// and execute any waiting functions
+				jQuery.ready();
+			}
+		}, 10); 
+
+	// A fallback to window.onload, that will always work
+	jQuery.event.add( window, "load", jQuery.ready );
+}
+jQuery.fn.extend({
+	load: function( url, params, callback ) {
+		if ( jQuery.isFunction( url ) )
+			return this.bind("load", url);
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		callback = callback || function(){};
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params )
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else {
+				params = jQuery.param( params );
+				type = "POST";
+			}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			data: params,
+			complete: function(res, status){
+				// If successful, inject the HTML into all the matched elements
+				if ( status == "success" || status == "notmodified" )
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div/>")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+
+				// Add delay to account for Safari's delay in globalEval
+				setTimeout(function(){
+					self.each( callback, [res.responseText, status, res] );
+				}, 13);
+			}
+		});
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+	serializeArray: function() {
+		return this.map(function(){
+			return jQuery.nodeName(this, "form") ?
+				jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function(){
+			return this.name && !this.disabled && 
+				(this.checked || /select|textarea/i.test(this.nodeName) || 
+					/text|hidden|password/i.test(this.type));
+		})
+		.map(function(i, elem){
+			var val = jQuery(this).val();
+			return val == null ? null :
+				val.constructor == Array ?
+					jQuery.map( val, function(val, i){
+						return {name: elem.name, value: val};
+					}) :
+					{name: elem.name, value: val};
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+	jQuery.fn[o] = function(f){
+		return this.bind(o, f);
+	};
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was ommited
+		if ( jQuery.isFunction( data ) ) {
+			callback = data;
+			data = null;
+		}
+		
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		if ( jQuery.isFunction( data ) ) {
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		global: true,
+		type: "GET",
+		timeout: 0,
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		data: null
+	},
+	
+	// Last-Modified header cache for next request
+	lastModified: {},
+
+	ajax: function( s ) {
+		var jsonp, jsre = /=(\?|%3F)/g, status, data;
+
+		// Extend the settings, but re-extend 's' so that it can be
+		// checked again later (in the test suite, specifically)
+		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data != "string" )
+			s.data = jQuery.param(s.data);
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType == "jsonp" ) {
+			if ( s.type.toLowerCase() == "get" ) {
+				if ( !s.url.match(jsre) )
+					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+			} else if ( !s.data || !s.data.match(jsre) )
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+			jsonp = "jsonp" + jsc++;
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data )
+				s.data = s.data.replace(jsre, "=" + jsonp);
+			s.url = s.url.replace(jsre, "=" + jsonp);
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			window[ jsonp ] = function(tmp){
+				data = tmp;
+				success();
+				complete();
+				// Garbage collect
+				window[ jsonp ] = undefined;
+				try{ delete window[ jsonp ]; } catch(e){}
+			};
+		}
+
+		if ( s.dataType == "script" && s.cache == null )
+			s.cache = false;
+
+		if ( s.cache === false && s.type.toLowerCase() == "get" )
+			s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime();
+
+		// If data is available, append data to url for get requests
+		if ( s.data && s.type.toLowerCase() == "get" ) {
+			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+			// IE likes to send both get and post data, prevent this
+			s.data = null;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && ! jQuery.active++ )
+			jQuery.event.trigger( "ajaxStart" );
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script
+		if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+			var head = document.getElementsByTagName("head")[0];
+			var script = document.createElement("script");
+			script.src = s.url;
+
+			// Handle Script loading
+			if ( !jsonp && (s.success || s.complete) ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function(){
+					if ( !done && (!this.readyState || 
+							this.readyState == "loaded" || this.readyState == "complete") ) {
+						done = true;
+						success();
+						complete();
+						head.removeChild( script );
+					}
+				};
+			}
+
+			head.appendChild(script);
+
+			// We handle everything using the script element injection
+			return;
+		}
+
+		var requestDone = false;
+
+		// Create the request object; Microsoft failed to properly
+		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+		var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+		// Open the socket
+		xml.open(s.type, s.url, s.async);
+
+		// Set the correct header, if data is being sent
+		if ( s.data )
+			xml.setRequestHeader("Content-Type", s.contentType);
+
+		// Set the If-Modified-Since header, if ifModified mode.
+		if ( s.ifModified )
+			xml.setRequestHeader("If-Modified-Since",
+				jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+		// Set header so the called script knows that it's an XMLHttpRequest
+		xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+		// Allow custom headers/mimetypes
+		if ( s.beforeSend )
+			s.beforeSend(xml);
+			
+		if ( s.global )
+		    jQuery.event.trigger("ajaxSend", [xml, s]);
+
+		// Wait for a response to come back
+		var onreadystatechange = function(isTimeout){
+			// The transfer is complete and the data is available, or the request timed out
+			if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+				requestDone = true;
+				
+				// clear poll interval
+				if (ival) {
+					clearInterval(ival);
+					ival = null;
+				}
+				
+				status = isTimeout == "timeout" && "timeout" ||
+					!jQuery.httpSuccess( xml ) && "error" ||
+					s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+					"success";
+
+				if ( status == "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xml, s.dataType );
+					} catch(e) {
+						status = "parsererror";
+					}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status == "success" ) {
+					// Cache Last-Modified header, if ifModified mode.
+					var modRes;
+					try {
+						modRes = xml.getResponseHeader("Last-Modified");
+					} catch(e) {} // swallow exception thrown by FF if header is not available
+	
+					if ( s.ifModified && modRes )
+						jQuery.lastModified[s.url] = modRes;
+
+					// JSONP handles its own success callback
+					if ( !jsonp )
+						success();	
+				} else
+					jQuery.handleError(s, xml, status);
+
+				// Fire the complete handlers
+				complete();
+
+				// Stop memory leaks
+				if ( s.async )
+					xml = null;
+			}
+		};
+		
+		if ( s.async ) {
+			// don't attach the handler to the request, just poll it instead
+			var ival = setInterval(onreadystatechange, 13); 
+
+			// Timeout checker
+			if ( s.timeout > 0 )
+				setTimeout(function(){
+					// Check to see if the request is still happening
+					if ( xml ) {
+						// Cancel the request
+						xml.abort();
+	
+						if( !requestDone )
+							onreadystatechange( "timeout" );
+					}
+				}, s.timeout);
+		}
+			
+		// Send the data
+		try {
+			xml.send(s.data);
+		} catch(e) {
+			jQuery.handleError(s, xml, null, e);
+		}
+		
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async )
+			onreadystatechange();
+		
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xml;
+
+		function success(){
+			// If a local callback was specified, fire it and pass it the data
+			if ( s.success )
+				s.success( data, status );
+
+			// Fire the global callback
+			if ( s.global )
+				jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+		}
+
+		function complete(){
+			// Process result
+			if ( s.complete )
+				s.complete(xml, status);
+
+			// The request was completed
+			if ( s.global )
+				jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active )
+				jQuery.event.trigger( "ajaxStop" );
+		}
+	},
+
+	handleError: function( s, xml, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) s.error( xml, status, e );
+
+		// Fire the global callback
+		if ( s.global )
+			jQuery.event.trigger( "ajaxError", [xml, s, e] );
+	},
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( r ) {
+		try {
+			return !r.status && location.protocol == "file:" ||
+				( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+				jQuery.browser.safari && r.status == undefined;
+		} catch(e){}
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xml, url ) {
+		try {
+			var xmlRes = xml.getResponseHeader("Last-Modified");
+
+			// Firefox always returns 200. check Last-Modified date
+			return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+				jQuery.browser.safari && xml.status == undefined;
+		} catch(e){}
+		return false;
+	},
+
+	httpData: function( r, type ) {
+		var ct = r.getResponseHeader("content-type");
+		var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+		var data = xml ? r.responseXML : r.responseText;
+
+		if ( xml && data.documentElement.tagName == "parsererror" )
+			throw "parsererror";
+
+		// If the type is "script", eval it in global context
+		if ( type == "script" )
+			jQuery.globalEval( data );
+
+		// Get the JavaScript object, if JSON is used.
+		if ( type == "json" )
+			data = eval("(" + data + ")");
+
+		return data;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a ) {
+		var s = [];
+
+		// If an array was passed in, assume that it is an array
+		// of form elements
+		if ( a.constructor == Array || a.jquery )
+			// Serialize the form elements
+			jQuery.each( a, function(){
+				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+			});
+
+		// Otherwise, assume that it's an object of key/value pairs
+		else
+			// Serialize the key/values
+			for ( var j in a )
+				// If the value is an array then the key names need to be repeated
+				if ( a[j] && a[j].constructor == Array )
+					jQuery.each( a[j], function(){
+						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+					});
+				else
+					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+		// Return the resulting serialization
+		return s.join("&").replace(/%20/g, "+");
+	}
+
+});
+jQuery.fn.extend({
+	show: function(speed,callback){
+		return speed ?
+			this.animate({
+				height: "show", width: "show", opacity: "show"
+			}, speed, callback) :
+			
+			this.filter(":hidden").each(function(){
+				this.style.display = this.oldblock ? this.oldblock : "";
+				if ( jQuery.css(this,"display") == "none" )
+					this.style.display = "block";
+			}).end();
+	},
+	
+	hide: function(speed,callback){
+		return speed ?
+			this.animate({
+				height: "hide", width: "hide", opacity: "hide"
+			}, speed, callback) :
+			
+			this.filter(":visible").each(function(){
+				this.oldblock = this.oldblock || jQuery.css(this,"display");
+				if ( this.oldblock == "none" )
+					this.oldblock = "block";
+				this.style.display = "none";
+			}).end();
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+	
+	toggle: function( fn, fn2 ){
+		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+			this._toggle( fn, fn2 ) :
+			fn ?
+				this.animate({
+					height: "toggle", width: "toggle", opacity: "toggle"
+				}, fn, fn2) :
+				this.each(function(){
+					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+				});
+	},
+	
+	slideDown: function(speed,callback){
+		return this.animate({height: "show"}, speed, callback);
+	},
+	
+	slideUp: function(speed,callback){
+		return this.animate({height: "hide"}, speed, callback);
+	},
+
+	slideToggle: function(speed, callback){
+		return this.animate({height: "toggle"}, speed, callback);
+	},
+	
+	fadeIn: function(speed, callback){
+		return this.animate({opacity: "show"}, speed, callback);
+	},
+	
+	fadeOut: function(speed, callback){
+		return this.animate({opacity: "hide"}, speed, callback);
+	},
+	
+	fadeTo: function(speed,to,callback){
+		return this.animate({opacity: to}, speed, callback);
+	},
+	
+	animate: function( prop, speed, easing, callback ) {
+		var opt = jQuery.speed(speed, easing, callback);
+
+		return this[ opt.queue === false ? "each" : "queue" ](function(){
+			opt = jQuery.extend({}, opt);
+			var hidden = jQuery(this).is(":hidden"), self = this;
+			
+			for ( var p in prop ) {
+				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+					return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+				if ( p == "height" || p == "width" ) {
+					// Store display property
+					opt.display = jQuery.css(this, "display");
+
+					// Make sure that nothing sneaks out
+					opt.overflow = this.style.overflow;
+				}
+			}
+
+			if ( opt.overflow != null )
+				this.style.overflow = "hidden";
+
+			opt.curAnim = jQuery.extend({}, prop);
+			
+			jQuery.each( prop, function(name, val){
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( /toggle|show|hide/.test(val) )
+					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+				else {
+					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+						start = e.cur(true) || 0;
+
+					if ( parts ) {
+						var end = parseFloat(parts[2]),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit != "px" ) {
+							self.style[ name ] = (end || 1) + unit;
+							start = ((end || 1) / e.cur(true)) * start;
+							self.style[ name ] = start + unit;
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] )
+							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+						e.custom( start, end, unit );
+					} else
+						e.custom( start, val, "" );
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+	
+	queue: function(type, fn){
+		if ( jQuery.isFunction(type) ) {
+			fn = type;
+			type = "fx";
+		}
+
+		if ( !type || (typeof type == "string" && !fn) )
+			return queue( this[0], type );
+
+		return this.each(function(){
+			if ( fn.constructor == Array )
+				queue(this, type, fn);
+			else {
+				queue(this, type).push( fn );
+			
+				if ( queue(this, type).length == 1 )
+					fn.apply(this);
+			}
+		});
+	},
+
+	stop: function(){
+		var timers = jQuery.timers;
+
+		return this.each(function(){
+			for ( var i = 0; i < timers.length; i++ )
+				if ( timers[i].elem == this )
+					timers.splice(i--, 1);
+		}).dequeue();
+	}
+
+});
+
+var queue = function( elem, type, array ) {
+	if ( !elem )
+		return;
+
+	var q = jQuery.data( elem, type + "queue" );
+
+	if ( !q || array )
+		q = jQuery.data( elem, type + "queue", 
+			array ? jQuery.makeArray(array) : [] );
+
+	return q;
+};
+
+jQuery.fn.dequeue = function(type){
+	type = type || "fx";
+
+	return this.each(function(){
+		var q = queue(this, type);
+
+		q.shift();
+
+		if ( q.length )
+			q[0].apply( this );
+	});
+};
+
+jQuery.extend({
+	
+	speed: function(speed, easing, fn) {
+		var opt = speed && speed.constructor == Object ? speed : {
+			complete: fn || !fn && easing || 
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && easing.constructor != Function && easing
+		};
+
+		opt.duration = (opt.duration && opt.duration.constructor == Number ? 
+			opt.duration : 
+			{ slow: 600, fast: 200 }[opt.duration]) || 400;
+	
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function(){
+			jQuery(this).dequeue();
+			if ( jQuery.isFunction( opt.old ) )
+				opt.old.apply( this );
+		};
+	
+		return opt;
+	},
+	
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+	
+	timers: [],
+
+	fx: function( elem, options, prop ){
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig )
+			options.orig = {};
+	}
+
+});
+
+jQuery.fx.prototype = {
+
+	// Simple function for setting a style value
+	update: function(){
+		if ( this.options.step )
+			this.options.step.apply( this.elem, [ this.now, this ] );
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+		// Set display property to block for height/width animations
+		if ( this.prop == "height" || this.prop == "width" )
+			this.elem.style.display = "block";
+	},
+
+	// Get the current size
+	cur: function(force){
+		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+			return this.elem[ this.prop ];
+
+		var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
+		return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function(from, to, unit){
+		this.startTime = (new Date()).getTime();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+		this.update();
+
+		var self = this;
+		function t(){
+			return self.step();
+		}
+
+		t.elem = this.elem;
+
+		jQuery.timers.push(t);
+
+		if ( jQuery.timers.length == 1 ) {
+			var timer = setInterval(function(){
+				var timers = jQuery.timers;
+				
+				for ( var i = 0; i < timers.length; i++ )
+					if ( !timers[i]() )
+						timers.splice(i--, 1);
+
+				if ( !timers.length )
+					clearInterval( timer );
+			}, 13);
+		}
+	},
+
+	// Simple 'show' function
+	show: function(){
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		this.custom(0, this.cur());
+
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		if ( this.prop == "width" || this.prop == "height" )
+			this.elem.style[this.prop] = "1px";
+		
+		// Start by showing the element
+		jQuery(this.elem).show();
+	},
+
+	// Simple 'hide' function
+	hide: function(){
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function(){
+		var t = (new Date()).getTime();
+
+		if ( t > this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			var done = true;
+			for ( var i in this.options.curAnim )
+				if ( this.options.curAnim[i] !== true )
+					done = false;
+
+			if ( done ) {
+				if ( this.options.display != null ) {
+					// Reset the overflow
+					this.elem.style.overflow = this.options.overflow;
+				
+					// Reset the display
+					this.elem.style.display = this.options.display;
+					if ( jQuery.css(this.elem, "display") == "none" )
+						this.elem.style.display = "block";
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide )
+					this.elem.style.display = "none";
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show )
+					for ( var p in this.options.curAnim )
+						jQuery.attr(this.elem.style, p, this.options.orig[p]);
+			}
+
+			// If a callback was provided, execute it
+			if ( done && jQuery.isFunction( this.options.complete ) )
+				// Execute the complete function
+				this.options.complete.apply( this.elem );
+
+			return false;
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+
+};
+
+jQuery.fx.step = {
+	scrollLeft: function(fx){
+		fx.elem.scrollLeft = fx.now;
+	},
+
+	scrollTop: function(fx){
+		fx.elem.scrollTop = fx.now;
+	},
+
+	opacity: function(fx){
+		jQuery.attr(fx.elem.style, "opacity", fx.now);
+	},
+
+	_default: function(fx){
+		fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+	}
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+	var left = 0, top = 0, elem = this[0], results;
+	
+	if ( elem ) with ( jQuery.browser ) {
+		var	absolute     = jQuery.css(elem, "position") == "absolute", 
+		    parent       = elem.parentNode, 
+		    offsetParent = elem.offsetParent, 
+		    doc          = elem.ownerDocument,
+		    safari2      = safari && parseInt(version) < 522;
+	
+		// Use getBoundingClientRect if available
+		if ( elem.getBoundingClientRect ) {
+			box = elem.getBoundingClientRect();
+		
+			// Add the document scroll offsets
+			add(
+				box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop)
+			);
+		
+			// IE adds the HTML element's border, by default it is medium which is 2px
+			// IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+			// IE 7 standards mode, the border is always 2px
+			if ( msie ) {
+				var border = jQuery("html").css("borderWidth");
+				border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border;
+				add( -border, -border );
+			}
+	
+		// Otherwise loop through the offsetParents and parentNodes
+		} else {
+		
+			// Initial element offsets
+			add( elem.offsetLeft, elem.offsetTop );
+		
+			// Get parent offsets
+			while ( offsetParent ) {
+				// Add offsetParent offsets
+				add( offsetParent.offsetLeft, offsetParent.offsetTop );
+			
+				// Mozilla and Safari > 2 does not include the border on offset parents
+				// However Mozilla adds the border for table cells
+				if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
+					border( offsetParent );
+				
+				// Safari <= 2 doubles body offsets with an absolutely positioned element or parent
+				if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" )
+					absolute = true;
+			
+				// Get next offsetParent
+				offsetParent = offsetParent.offsetParent;
+			}
+		
+			// Get parent scroll offsets
+			while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+				// Work around opera inline/table scrollLeft/Top bug
+				if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) )
+					// Subtract parent scroll offsets
+					add( -parent.scrollLeft, -parent.scrollTop );
+			
+				// Mozilla does not add the border for a parent that has overflow != visible
+				if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+					border( parent );
+			
+				// Get next parent
+				parent = parent.parentNode;
+			}
+		
+			// Safari doubles body offsets with an absolutely positioned element or parent
+			if ( safari2 && absolute )
+				add( -doc.body.offsetLeft, -doc.body.offsetTop );
+		}
+
+		// Return an object with top and left properties
+		results = { top: top, left: left };
+	}
+
+	return results;
+
+	function border(elem) {
+		add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") );
+	}
+
+	function add(l, t) {
+		left += parseInt(l) || 0;
+		top += parseInt(t) || 0;
+	}
+};
+})();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/robots.txt	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /feeds/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/styles.css	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,292 @@
+body {
+  background: #f2f1f0;
+  font-family: verdana,sans-serif;
+}
+
+.navheader, .book, .preface, .chapter, .appendix, .bibliography, .navfooter, .basetemplate {
+  width: 50em;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+a.commenttoggle:hover, a.commenttoggle:active {
+  opacity: 0.7;
+}
+
+a:hover, a:active {
+  border-bottom: 1px solid #aaaaaa;
+}
+
+.book, .preface, .chapter, .appendix, .bibliography, .basetemplate {
+  background: white;
+  padding: 2em;
+}
+
+h1 {
+  margin-top: 1.5em;
+}
+
+span.beta {
+  font-size: 80%;
+  font-style: italic;
+  opacity: 0.4;
+}
+
+h2, h3 {
+  margin-top: 2em;
+}
+
+h1, h2, h3 {
+  font-family: georgia,serif;
+  font-weight: normal;
+  margin-bottom: 0.5em;
+}
+
+h1.booktitle {
+  margin-bottom: 0px;
+}
+
+h2.booktitle {
+  text-align: center;
+}
+
+h2.booktitle > a {
+  color: black;
+}
+
+div.authors {
+  font-size: 80%;
+  margin-bottom: 1em;
+  padding-left: 0.25em;
+}
+
+span.authors {
+  font-size: 80%;
+  opacity: 0.55;
+  padding-left: 0.5em;
+}
+
+div.note th, div.tip th, div.warning th {
+  font-family: georgia,serif;
+  font-weight: normal;
+  font-size: 110%;
+}
+
+div.navheader th, div.navfooter td {
+  font-family: georgia,serif;
+}
+
+div.navheader th {
+  opacity: 0;
+  font-size: 0;
+}
+
+pre.screen {
+  background-image: url(figs/shell.png);
+}
+
+pre.programlisting {
+  background-image: url(figs/source.png);
+}
+
+pre.programlisting, pre.screen, p.remark {
+  border-style: solid;
+  border-width: 1px;
+  font-size: medium;
+  padding: 1em;
+  background-repeat: no-repeat;
+  background-position: 10px 10px;
+  padding-left: 70px;
+}
+
+strong.command, code, pre, span.type {
+  font-family: monospace;
+  font-weight: normal;
+}
+
+strong.userinput > code {
+  font-weight: bolder;
+  color: #303030;
+}
+
+div.toc > p {
+  opacity: 0.35;
+  font-family: georgia,serif;
+  cursor: pointer;
+}
+
+div.toc b {
+  font-weight: normal;
+  font-size: large;
+}
+
+ul.booktoc {
+  padding-left: 0px;
+  list-style-type: none;
+}
+
+.booktoc > li {
+  padding: 0.5em;
+}
+
+.chapinfo {
+  float: right;
+  color: #a0a0a0;
+}
+
+.unpublished {
+  color: #a0a0a0;
+}
+
+.chapinfo img {
+  vertical-align: -35%;
+  border: 0px;
+}
+
+.zebra_b {
+  background: #f4f4f4;
+}
+
+.book .titlepage {
+  display: none;
+}
+
+.chapter div.toc > dl {
+  display: none;
+}
+
+pre.programlisting, pre.screen, p.remark {
+  overflow: hidden;
+}
+
+p.remark {
+  background-image: url(figs/remark.png);
+}
+
+div.warning, p.remark {
+  background-color: #FFEFE8;
+  border-color: #e0a8a0;
+}
+
+span.remark {
+  font-style: normal;
+  color: #707070;
+}
+
+.screen {
+  background: #e7ffc7 none repeat scroll 0% 50%;
+  border-color: #94DA3A;
+}
+
+.programlisting {
+  background: #F0F4FF none repeat scroll 0% 50%;
+  border-color: #B4BAEA;
+}
+
+.prompt {
+  color: #448844;
+}
+
+div.note, div.tip {
+  background: #ffffc9;
+  border-color: #B4BAEA;
+}
+
+div.note, div.warning, div.tip {
+  border-style: solid;
+  border-width: 1px;
+  padding: 1em;
+}
+
+.note .title {
+  font-size: 90%;
+}
+
+.comment {
+  font-size: 80%;
+}
+
+div.comment, div.new_comment {
+  padding: 0.5em;
+  margin: 0.5em;
+  margin-left: 2em;
+  border-style: solid;
+  border-width: 1px;
+  border-color: #aaaaff;
+}
+
+div.comment {
+  background: #eeeeff;
+}
+
+div.new_comment {
+  background: #d0d0ff;
+}
+
+.commenttoggle {
+  opacity: 0.35;
+}
+
+.comment_help {
+  font-size: 80%;
+}
+
+.comment_header {
+  opacity: 0.75;
+}
+
+.comment_id {
+  float: right;
+  opacity: 0.3;
+  font-size: 60%;
+}
+
+.comment_name {
+  font-weight: bolder;
+}
+
+.comment_reviewed {
+  color: darkgreen;
+  margin-left: 1em;
+  font-style: italic;
+}
+
+.comment_date {
+  opacity: 0.75;
+}
+
+.comment_thanks {
+  color: darkblue;
+  margin-left: 1em;
+  font-style: italic;
+  font-weight: bolder;
+}
+
+.comment_error {
+  padding-left: 1em;
+  font-weight: bolder;
+  font-size: 80%;
+  color: darkred;
+}
+
+.hgfooter {
+  width: 60em;
+  margin-left: auto;
+  margin-right: auto;
+  margin-top: 2em;
+  margin-bottom: 2em;
+  font-size: 80%;
+  color: #727272;
+}
+
+.hgfooter a {
+  color: #5555ff;
+}
+
+.hgfooter a:visited {
+  opacity: 0.7;
+}
+
+.hgfooter img {
+  vertical-align: -45%;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/texpand.py	Tue Apr 21 00:36:40 2009 +0900
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# Use Django's template machinery to expand static web pages.  First
+# tries the default template path for a particular installation, then
+# looks for templates in the filesystem.
+
+from django.template import Context, TemplateDoesNotExist
+from django.template.loader import get_template, get_template_from_string
+from django.core.management import setup_environ
+import hgbook.settings as settings
+import sys
+
+setup_environ(settings)
+c = Context()
+
+if len(sys.argv) == 2:
+    in_name = sys.argv[1]
+    out_name = 'stdout'
+    out_fp = sys.stdout
+elif len(sys.argv) == 3:
+    in_name = sys.argv[1]
+    out_name = sys.argv[2]
+    out_fp = None
+else:
+    print >> sys.stderr, 'Usage: %s template-file [output-file]'
+    sys.exit(1)
+    
+try:
+    t = get_template(in_name)
+except TemplateDoesNotExist:
+    t = get_template_from_string(open(in_name).read(), name=in_name)
+if out_fp is None:
+    out_fp = open(out_name, 'w')
+out_fp.write(t.render(c))
+out_fp.close()