changeset 753:1c13ed2130a7

Merge with http://hg.serpentine.com/mercurial/book
author Dongsheng Song <dongsheng.song@gmail.com>
date Mon, 30 Mar 2009 16:23:33 +0800
parents 6b1577ef5135 (diff) 9e8e5292acaa (current diff)
children 65e9a18d2c7e
files .hgignore Makefile en/00book.xml en/Makefile en/appA-cmdref.xml en/appB-mq-ref.xml en/appC-srcinstall.xml en/appD-license.xml en/ch00-preface.xml en/ch01-tour-basic.xml en/ch02-tour-merge.xml en/ch03-concepts.xml en/ch04-daily.xml en/ch05-collab.xml en/ch06-filenames.xml en/ch07-branch.xml en/ch08-undo.xml en/ch09-hook.xml en/ch10-template.xml en/ch11-mq.xml en/ch12-mq-collab.xml en/ch13-hgext.xml en/examples/auto-snippets.xml en/examples/results/backout.init.out en/examples/results/backout.manual.backout.out en/examples/results/backout.manual.cat.out en/examples/results/backout.manual.clone.out en/examples/results/backout.manual.heads.out en/examples/results/backout.manual.log.out en/examples/results/backout.manual.merge.out en/examples/results/backout.manual.parents.out en/examples/results/backout.non-tip.backout.out en/examples/results/backout.non-tip.cat.out en/examples/results/backout.non-tip.clone.out en/examples/results/backout.simple.log.out en/examples/results/backout.simple.out en/examples/results/bisect.commits.out en/examples/results/bisect.help.out en/examples/results/bisect.init.out en/examples/results/bisect.search.bad-init.out en/examples/results/bisect.search.good-init.out en/examples/results/bisect.search.init.out en/examples/results/bisect.search.mytest.out en/examples/results/bisect.search.reset.out en/examples/results/bisect.search.rest.out en/examples/results/bisect.search.step1.out en/examples/results/bisect.search.step2.out en/examples/results/branch-named.branch.out en/examples/results/branch-named.branches.out en/examples/results/branch-named.commit.out en/examples/results/branch-named.create.out en/examples/results/branch-named.foo-commit.out en/examples/results/branch-named.merge.out en/examples/results/branch-named.parents.out en/examples/results/branch-named.rebranch.out en/examples/results/branch-named.status.out en/examples/results/branch-named.update-bar.out en/examples/results/branch-named.update-foo.out en/examples/results/branch-named.update-nothing.out en/examples/results/branch-named.update-switchy.out en/examples/results/branch-named.update.out en/examples/results/branch-repo.bugfix.out en/examples/results/branch-repo.clone.out en/examples/results/branch-repo.merge.out en/examples/results/branch-repo.new.out en/examples/results/branch-repo.pull.out en/examples/results/branch-repo.tag.out en/examples/results/branching.clone.out en/examples/results/branching.init.out en/examples/results/branching.main.out en/examples/results/branching.merge.out en/examples/results/branching.stable.out en/examples/results/branching.tag.out en/examples/results/branching.update.out en/examples/results/cmdref.diff-p.out en/examples/results/daily.copy.after.out en/examples/results/daily.copy.cat.out en/examples/results/daily.copy.clone.out en/examples/results/daily.copy.copy.out en/examples/results/daily.copy.dir-dest.out en/examples/results/daily.copy.dir-src-dest.out en/examples/results/daily.copy.dir-src.out en/examples/results/daily.copy.init.out en/examples/results/daily.copy.merge.out en/examples/results/daily.copy.other.out en/examples/results/daily.copy.simple.out en/examples/results/daily.copy.status-copy.out en/examples/results/daily.copy.status.out en/examples/results/daily.files.add-dir.out en/examples/results/daily.files.add.out en/examples/results/daily.files.addremove.out en/examples/results/daily.files.commit-addremove.out en/examples/results/daily.files.hidden.out en/examples/results/daily.files.missing.out en/examples/results/daily.files.recover-missing.out en/examples/results/daily.files.remove-after.out en/examples/results/daily.files.remove.out en/examples/results/daily.rename.rename.out en/examples/results/daily.rename.status-copy.out en/examples/results/daily.rename.status.out en/examples/results/daily.revert.add.out en/examples/results/daily.revert.copy.out en/examples/results/daily.revert.missing.out en/examples/results/daily.revert.modify.out en/examples/results/daily.revert.remove.out en/examples/results/daily.revert.rename-orig.out en/examples/results/daily.revert.rename.out en/examples/results/daily.revert.status.out en/examples/results/daily.revert.unmodify.out en/examples/results/extdiff.diff.out en/examples/results/extdiff.extdiff-ctx.out en/examples/results/extdiff.extdiff.out en/examples/results/filenames.dirs.out en/examples/results/filenames.files.out en/examples/results/filenames.filter.exclude.out en/examples/results/filenames.filter.include.out en/examples/results/filenames.glob.group.out en/examples/results/filenames.glob.question.out en/examples/results/filenames.glob.range.out en/examples/results/filenames.glob.star-starstar.out en/examples/results/filenames.glob.star.out en/examples/results/filenames.glob.starstar.out en/examples/results/filenames.wdir-relname.out en/examples/results/filenames.wdir-subdir.out en/examples/results/hook.msglen.go.out en/examples/results/hook.msglen.run.out en/examples/results/hook.simple.ext.out en/examples/results/hook.simple.init.out en/examples/results/hook.simple.pretxncommit.out en/examples/results/hook.ws.better.out en/examples/results/hook.ws.simple.out en/examples/results/issue29.go.out en/examples/results/mq.dodiff.diff.out en/examples/results/mq.guards.init.out en/examples/results/mq.guards.qguard.neg.out en/examples/results/mq.guards.qguard.out en/examples/results/mq.guards.qguard.pos.out en/examples/results/mq.guards.qselect.cat.out en/examples/results/mq.guards.qselect.error.out en/examples/results/mq.guards.qselect.foo.out en/examples/results/mq.guards.qselect.foobar.out en/examples/results/mq.guards.qselect.qpush.out en/examples/results/mq.guards.qselect.quux.out en/examples/results/mq.guards.series.out en/examples/results/mq.id.out.out en/examples/results/mq.id.output.out en/examples/results/mq.qinit-help.help.out en/examples/results/mq.tarball.download.out en/examples/results/mq.tarball.newsource.out en/examples/results/mq.tarball.qinit.out en/examples/results/mq.tarball.repush.out en/examples/results/mq.tools.lsdiff.out en/examples/results/mq.tools.tools.out en/examples/results/mq.tutorial.add.out en/examples/results/mq.tutorial.qinit.out en/examples/results/mq.tutorial.qnew.out en/examples/results/mq.tutorial.qnew2.out en/examples/results/mq.tutorial.qpop.out en/examples/results/mq.tutorial.qpush-a.out en/examples/results/mq.tutorial.qrefresh.out en/examples/results/mq.tutorial.qrefresh2.out en/examples/results/mq.tutorial.qseries.out en/examples/results/rename.divergent.clone.out en/examples/results/rename.divergent.merge.out en/examples/results/rename.divergent.rename.anne.out en/examples/results/rename.divergent.rename.bob.out en/examples/results/rollback.add.out en/examples/results/rollback.commit.out en/examples/results/rollback.rollback.out en/examples/results/rollback.status.out en/examples/results/rollback.tip.out en/examples/results/rollback.twice.out en/examples/results/tag.init.out en/examples/results/tag.log.out en/examples/results/tag.log.v1.0.out en/examples/results/tag.remove.out en/examples/results/tag.replace.out en/examples/results/tag.tag.out en/examples/results/tag.tags.out en/examples/results/tag.tip.out en/examples/results/template.simple.changelog.out en/examples/results/template.simple.combine.out en/examples/results/template.simple.compact.out en/examples/results/template.simple.datekeyword.out en/examples/results/template.simple.keywords.out en/examples/results/template.simple.manyfilters.out en/examples/results/template.simple.normal.out en/examples/results/template.simple.rev.out en/examples/results/template.simple.simplest.out en/examples/results/template.simple.simplesub.out en/examples/results/template.svnstyle.id.out en/examples/results/template.svnstyle.result.out en/examples/results/template.svnstyle.short.out en/examples/results/template.svnstyle.simplest.out en/examples/results/template.svnstyle.style.out en/examples/results/template.svnstyle.syntax.error.out en/examples/results/template.svnstyle.syntax.input.out en/examples/results/template.svnstyle.template.out en/examples/results/tour-merge-conflict.commit.out en/examples/results/tour-merge-conflict.cousin.out en/examples/results/tour-merge-conflict.merge.out en/examples/results/tour-merge-conflict.pull.out en/examples/results/tour-merge-conflict.son.out en/examples/results/tour-merge-conflict.wife.out en/examples/results/tour.clone-pull.out en/examples/results/tour.clone-push.out en/examples/results/tour.clone.out en/examples/results/tour.commit.out en/examples/results/tour.diff.out en/examples/results/tour.help.out en/examples/results/tour.incoming.out en/examples/results/tour.log-r.out en/examples/results/tour.log-v.out en/examples/results/tour.log-vp.out en/examples/results/tour.log.out en/examples/results/tour.log.range.out en/examples/results/tour.ls-a.out en/examples/results/tour.ls.out en/examples/results/tour.merge.cat.out en/examples/results/tour.merge.clone.out en/examples/results/tour.merge.commit.out en/examples/results/tour.merge.heads.out en/examples/results/tour.merge.merge.out en/examples/results/tour.merge.parents.out en/examples/results/tour.merge.pull.out en/examples/results/tour.merge.tip.out en/examples/results/tour.merge.update.out en/examples/results/tour.older.out en/examples/results/tour.outgoing.net.out en/examples/results/tour.outgoing.out en/examples/results/tour.parents.out en/examples/results/tour.pull.out en/examples/results/tour.push.net.out en/examples/results/tour.push.nothing.out en/examples/results/tour.push.out en/examples/results/tour.reclone.out en/examples/results/tour.sed.out en/examples/results/tour.status.out en/examples/results/tour.tip.out en/examples/results/tour.update.out en/examples/results/tour.version.out en/images/feature-branches.dot en/images/filelog.svg en/images/kdiff3.png en/images/metadata.svg en/images/mq-stack.svg en/images/note.png en/images/revlog.svg en/images/snapshot.svg en/images/tour-history.svg en/images/tour-merge-conflict.svg en/images/tour-merge-merge.svg en/images/tour-merge-pull.svg en/images/tour-merge-sep-repos.svg en/images/undo-manual-merge.dot en/images/undo-manual.dot en/images/undo-non-tip.dot en/images/undo-simple.dot en/images/wdir-after-commit.svg en/images/wdir-branch.svg en/images/wdir-merge.svg en/images/wdir-pre-branch.svg en/images/wdir.svg stylesheets/base-html-stylesheet.xsl web/index.html
diffstat 272 files changed, 26136 insertions(+), 3068 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Mar 27 00:41:15 2009 -0700
+++ b/.hgignore	Mon Mar 30 16:23:33 2009 +0800
@@ -1,4 +1,4 @@
-[^/]+/html/
+[^/]+/htdocs/
 
 syntax: glob
 
@@ -19,4 +19,8 @@
 web/hgbook/.database.sqlite3
 web/hgbook/secrets.py
 web/index-read.html.in
-xsl/system-xsl
+stylesheets/system-xsl
+build
+en/html
+en/examples/results
+tools
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,219 @@
+#
+# Makefile for the hgbook, top-level
+#
+
+FORMATS=html html-single pdf
+
+PO_LANGUAGES := zh
+DBK_LANGUAGES := en
+LANGUAGES := $(DBK_LANGUAGES) $(PO_LANGUAGES)
+
+UPDATEPO = PERLLIB=../tools/po4a/lib/ ../tools/po4a/po4a-updatepo -M UTF-8 \
+	   -f docbook -o doctype='docbook' -o includeexternal \
+	   -o nodefault='<programlisting> <screen>' \
+	   -o untranslated='<programlisting> <screen>'
+TRANSLATE = PERLLIB=tools/po4a/lib/ tools/po4a/po4a-translate -M UTF-8 \
+	   -f docbook -o doctype='docbook' \
+	   -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 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 $(images)
+	mkdir -p build/$(LINGUA)/source/figs
+	cp $(LINGUA)/figs/*.png build/$(LINGUA)/source/figs
+	(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: build/en/source/hgbook.xml po/$(LINGUA).po $(images)
+	mkdir -p build/$(LINGUA)/source/figs
+	$(TRANSLATE) -m build/en/source/hgbook.xml -p po/$(LINGUA).po -l $@.tmp
+	cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@
+endif
+
+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 tools/fop/lib/saxon65.jar:tools/fop/lib/saxon65-dbxsl.jar:tools/fop/lib/xml-commons-resolver-1.2.jar:tools/fop/conf \
+	    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 && ../../../tools/fop/fop.sh 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/README	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,66 @@
+#!/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
+  )
+done
+
+upload_pass=$1
+upload_user=$2
+
+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}.pdf.gz" ] ; then
+      python googlecode_upload.py -u "dongsheng.song" -w "$1" \
+          -p "i18n-zh" -l "Type-Docs,hgbook" \
+          -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}-${rev_id}.pdf.gz" ] ; then
+        python googlecode_upload.py -u "dongsheng.song" -w "$1" \
+            -p "i18n-zh" -l "Type-Docs,hgbook" \
+            -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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.xml	Fri Mar 27 00:41:15 2009 -0700
+++ b/en/00book.xml	Mon Mar 30 16:23:33 2009 +0800
@@ -39,6 +39,11 @@
 
 <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>
     <authorgroup>
       <author>
--- a/en/Makefile	Fri Mar 27 00:41:15 2009 -0700
+++ b/en/Makefile	Mon Mar 30 16:23:33 2009 +0800
@@ -112,18 +112,18 @@
 
 all: web
 
-../xsl/system-xsl: $(system-xsl-dir)
+../stylesheets/system-xsl: $(system-xsl-dir)
 	ln -s $< $@
 
-web: ../xsl/system-xsl websup html
+web: ../stylesheets/system-xsl websup html
 
 html: $(obj-web-read)/index.html
 
 ../web/index-read.html.in: ../web/genindex.py $(xml-src-files)
 	$<
 
-$(obj-web-read)/index.html: ../xsl/system-xsl .validated-00book.xml ../web/index-read.html.in
-	xsltproc $(xsltproc-opts) -o $(obj-web-read)/x ../xsl/chunk-stylesheet.xsl 00book.xml
+$(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; \
@@ -131,11 +131,11 @@
 
 websup: $(extras-web) $(image-web)
 	mkdir -p $(obj-websup)/figs $(obj-web-read)/figs
-	cp ../xsl/system-xsl/images/*.png $(obj-websup)/figs
+	cp ../stylesheets/system-xsl/images/*.png $(obj-websup)/figs
 	cp -f ../web/icons/*.png $(obj-websup)/figs
 
-all-ids.dat: ../xsl/all-ids.xsl $(xml-src-files)
-	$(xsltproc) $(xsltproc-opts) -o $@ ../xsl/all-ids.xsl 00book.xml
+all-ids.dat: ../stylesheets/all-ids.xsl $(xml-src-files)
+	$(xsltproc) $(xsltproc-opts) -o $@ ../stylesheets/all-ids.xsl 00book.xml
 
 web: websup
 
--- a/en/appB-mq-ref.xml	Fri Mar 27 00:41:15 2009 -0700
+++ b/en/appB-mq-ref.xml	Mon Mar 30 16:23:33 2009 +0800
@@ -43,7 +43,7 @@
 	<title><command
 	  role="hg-ext-mq">qdelete</command>&emdash;delete a patch
 	from the <filename role="special">series</filename>
-	file}</title>
+	file</title>
 
       <para id="x_5ec">The <command role="hg-ext-mq">qdelete</command> command
 	removes the entry for a patch from the <filename
--- a/en/ch02-tour-merge.xml	Fri Mar 27 00:41:15 2009 -0700
+++ b/en/ch02-tour-merge.xml	Mon Mar 30 16:23:33 2009 +0800
@@ -249,7 +249,7 @@
 	  file</title>
 	<mediaobject>
 	  <imageobject>
-	    <imagedata fileref="figs/kdiff3.png"/></imageobject>
+	    <imagedata imagedata width="100%" fileref="figs/kdiff3.png"/></imageobject>
 	  <textobject>
 	    <phrase>XXX add text</phrase>
 	  </textobject>
--- a/en/ch05-collab.xml	Fri Mar 27 00:41:15 2009 -0700
+++ b/en/ch05-collab.xml	Mon Mar 30 16:23:33 2009 +0800
@@ -272,7 +272,7 @@
       <figure id="fig:collab:feature-branches">
 	<title>Feature branches</title>
 	<mediaobject>
-	  <imageobject><imagedata fileref="figs/feature-branches.png"/></imageobject>
+	  <imageobject><imagedata imagedata width="100%" fileref="figs/feature-branches.png"/></imageobject>
 	  <textobject><phrase>XXX add text</phrase></textobject>
 	</mediaobject>
       </figure>
--- a/en/examples/results/backout.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init myrepo</userinput>
-<prompt>$</prompt> <userinput>cd myrepo</userinput>
-<prompt>$</prompt> <userinput>echo first change &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg add myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'first change'</userinput>
-<prompt>$</prompt> <userinput>echo second change &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'second change'</userinput>
-</screen>
--- a/en/examples/results/backout.manual.backout.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo third change &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'third change'</userinput>
-<prompt>$</prompt> <userinput>hg backout -m 'back out second change' 1</userinput>
-reverting myfile
-created new head
-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)
-</screen>
--- a/en/examples/results/backout.manual.cat.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat myfile</userinput>
-first change
-second change
-third change
-</screen>
--- a/en/examples/results/backout.manual.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone -r1 myrepo newrepo</userinput>
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 2 changes to 1 files
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd newrepo</userinput>
-</screen>
--- a/en/examples/results/backout.manual.heads.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg heads</userinput>
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     back out second change
-
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     third change
-
-</screen>
--- a/en/examples/results/backout.manual.log.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log --style compact</userinput>
-3[tip]:1      2009-03-10 04:37 +0000   bos
-  back out second change
-
-2      2009-03-10 04:37 +0000   bos
-  third change
-
-1      2009-03-10 04:37 +0000   bos
-  second change
-
-0      2009-03-10 04:37 +0000   bos
-  first change
-
-</screen>
--- a/en/examples/results/backout.manual.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg merge</userinput>
-merging myfile
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-<prompt>$</prompt> <userinput>hg commit -m 'merged backout with previous tip'</userinput>
-<prompt>$</prompt> <userinput>cat myfile</userinput>
-first change
-third change
-</screen>
--- a/en/examples/results/backout.manual.parents.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     third change
-
-</screen>
--- a/en/examples/results/backout.non-tip.backout.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo third change &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'third change'</userinput>
-<prompt>$</prompt> <userinput>hg backout --merge -m 'back out second change' 1</userinput>
-reverting myfile
-created new head
-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)
-</screen>
--- a/en/examples/results/backout.non-tip.cat.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat myfile</userinput>
-first change
-third change
-</screen>
--- a/en/examples/results/backout.non-tip.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone -r1 myrepo non-tip-repo</userinput>
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 2 changes to 1 files
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd non-tip-repo</userinput>
-</screen>
--- a/en/examples/results/backout.simple.log.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log --style compact</userinput>
-2[tip]      2009-03-10 04:37 +0000   bos
-  back out second change
-
-1      2009-03-10 04:37 +0000   bos
-  second change
-
-0      2009-03-10 04:37 +0000   bos
-  first change
-
-</screen>
--- a/en/examples/results/backout.simple.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg backout -m 'back out second change' tip</userinput>
-reverting myfile
-changeset  backs out changeset 
-<prompt>$</prompt> <userinput>cat myfile</userinput>
-first change
-</screen>
--- a/en/examples/results/bisect.commits.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/bisect.help.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/bisect.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/results/bisect.search.bad-init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/results/bisect.search.good-init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
--- a/en/examples/results/bisect.search.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/results/bisect.search.mytest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/bisect.search.reset.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/results/bisect.search.rest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/bisect.search.step1.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/bisect.search.step2.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-
-
-
-
-
--- a/en/examples/results/branch-named.branch.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg branch</userinput>
-default
-</screen>
--- a/en/examples/results/branch-named.branches.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Initial commit
-
-<prompt>$</prompt> <userinput>hg branches</userinput>
-default                        
-</screen>
--- a/en/examples/results/branch-named.commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'hello again' &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Second commit'</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-branch:      foo
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Second commit
-
-</screen>
--- a/en/examples/results/branch-named.create.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg branch foo</userinput>
-marked working directory as branch foo
-<prompt>$</prompt> <userinput>hg branch</userinput>
-foo
-</screen>
--- a/en/examples/results/branch-named.foo-commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo something &gt; somefile</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'New file'</userinput>
-adding somefile
-created new head
-<prompt>$</prompt> <userinput>hg heads</userinput>
-changeset:   
-branch:      foo
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     New file
-
-changeset:   
-branch:      bar
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Third commit
-
-</screen>
--- a/en/examples/results/branch-named.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg branch</userinput>
-bar
-<prompt>$</prompt> <userinput>hg merge foo</userinput>
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-<prompt>$</prompt> <userinput>hg commit -m 'Merge'</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-branch:      bar
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Merge
-
-</screen>
--- a/en/examples/results/branch-named.parents.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Third commit
-
-<prompt>$</prompt> <userinput>hg branches</userinput>
-bar                            
-foo                             (inactive)
-default                         (inactive)
-</screen>
--- a/en/examples/results/branch-named.rebranch.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg branch</userinput>
-foo
-<prompt>$</prompt> <userinput>hg branch bar</userinput>
-marked working directory as branch bar
-<prompt>$</prompt> <userinput>echo new file &gt; newfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'Third commit'</userinput>
-adding newfile
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Third commit
-
-</screen>
--- a/en/examples/results/branch-named.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Initial commit
-
-</screen>
--- a/en/examples/results/branch-named.update-bar.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg update bar</userinput>
-1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/branch-named.update-foo.out	Fri Mar 27 00:41:15 2009 -0700
+++ /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/results/branch-named.update-nothing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg update foo</userinput>
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>hg update</userinput>
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/branch-named.update-switchy.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg update foo</userinput>
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-branch:      foo
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Second commit
-
-<prompt>$</prompt> <userinput>hg update bar</userinput>
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-branch:      bar
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Third commit
-
-</screen>
--- a/en/examples/results/branch-named.update.out	Fri Mar 27 00:41:15 2009 -0700
+++ /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/results/branch-repo.bugfix.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg clone myproject-1.0.1 my-1.0.1-bugfix</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd my-1.0.1-bugfix</userinput>
-<prompt>$</prompt> <userinput>echo 'I fixed a bug using only echo!' &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Important fix for 1.0.1'</userinput>
-<prompt>$</prompt> <userinput>hg push</userinput>
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-</screen>
--- a/en/examples/results/branch-repo.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone myproject myproject-1.0.1</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/branch-repo.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg merge</userinput>
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-<prompt>$</prompt> <userinput>hg commit -m 'Merge bugfix from 1.0.1 branch'</userinput>
-<prompt>$</prompt> <userinput>hg push</userinput>
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 2 changesets with 1 changes to 1 files
-</screen>
--- a/en/examples/results/branch-repo.new.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone myproject my-feature</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd my-feature</userinput>
-<prompt>$</prompt> <userinput>echo 'This sure is an exciting new feature!' &gt; mynewfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'New feature'</userinput>
-adding mynewfile
-<prompt>$</prompt> <userinput>hg push</userinput>
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-</screen>
--- a/en/examples/results/branch-repo.pull.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone myproject myproject-merge</userinput>
-updating working directory
-3 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd myproject-merge</userinput>
-<prompt>$</prompt> <userinput>hg pull ../myproject-1.0.1</userinput>
-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)
-</screen>
--- a/en/examples/results/branch-repo.tag.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd myproject</userinput>
-<prompt>$</prompt> <userinput>hg tag v1.0</userinput>
-</screen>
--- a/en/examples/results/branching.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone -rv1.0 main stable</userinput>
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/branching.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init main</userinput>
-<prompt>$</prompt> <userinput>cd main</userinput>
-<prompt>$</prompt> <userinput>echo 'This is a boring feature.' &gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'We have reached an important milestone!'</userinput>
-adding myfile
-</screen>
--- a/en/examples/results/branching.main.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ../main</userinput>
-<prompt>$</prompt> <userinput>echo 'This is exciting and new!' &gt;&gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Add a new feature'</userinput>
-<prompt>$</prompt> <userinput>cat myfile</userinput>
-This is a boring feature.
-This is exciting and new!
-</screen>
--- a/en/examples/results/branching.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ../main</userinput>
-<prompt>$</prompt> <userinput>hg pull ../stable</userinput>
-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)
-<prompt>$</prompt> <userinput>hg merge</userinput>
-merging myfile
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-<prompt>$</prompt> <userinput>hg commit -m 'Bring in bugfix from stable branch'</userinput>
-<prompt>$</prompt> <userinput>cat myfile</userinput>
-This is a fix to a boring feature.
-This is exciting and new!
-</screen>
--- a/en/examples/results/branching.stable.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg clone stable stable-fix</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd stable-fix</userinput>
-<prompt>$</prompt> <userinput>echo 'This is a fix to a boring feature.' &gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Fix a bug'</userinput>
-<prompt>$</prompt> <userinput>hg push</userinput>
-pushing to 
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-</screen>
--- a/en/examples/results/branching.tag.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tag v1.0</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added tag v1.0 for changeset 
-
-<prompt>$</prompt> <userinput>hg tags</userinput>
-tip                                
-v1.0                               
-</screen>
--- a/en/examples/results/branching.update.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone -U main main-old</userinput>
-<prompt>$</prompt> <userinput>cd main-old</userinput>
-<prompt>$</prompt> <userinput>hg update v1.0</userinput>
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cat myfile</userinput>
-This is a boring feature.
-</screen>
--- a/en/examples/results/cmdref.diff-p.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo '[diff]' &gt;&gt; $HGRC</userinput>
-<prompt>$</prompt> <userinput>echo 'showfunc = False' &gt;&gt; $HGRC</userinput>
-<prompt>$</prompt> <userinput>hg diff</userinput>
-diff -r  myfile.c
-
-
-@@ -1,4 +1,4 @@
- int myfunc()
- {
--    return 1;
-+    return 10;
- }
-<prompt>$</prompt> <userinput>hg diff -p</userinput>
-diff -r  myfile.c
-
-
-@@ -1,4 +1,4 @@
- int myfunc()
- {
--    return 1;
-+    return 10;
- }
-</screen>
--- a/en/examples/results/daily.copy.after.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cp a z</userinput>
-<prompt>$</prompt> <userinput>hg copy --after a z</userinput>
-</screen>
--- a/en/examples/results/daily.copy.cat.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat file</userinput>
-line
-new contents
-<prompt>$</prompt> <userinput>cat ../my-copy/new-file</userinput>
-line
-</screen>
--- a/en/examples/results/daily.copy.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone my-copy your-copy</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/daily.copy.copy.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd my-copy</userinput>
-<prompt>$</prompt> <userinput>hg copy file new-file</userinput>
-</screen>
--- a/en/examples/results/daily.copy.dir-dest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>mkdir d</userinput>
-<prompt>$</prompt> <userinput>hg copy a b d</userinput>
-<prompt>$</prompt> <userinput>ls d</userinput>
-a  b
-</screen>
--- a/en/examples/results/daily.copy.dir-src-dest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg copy c d</userinput>
-copying c/a/c to d/c/a/c
-</screen>
--- a/en/examples/results/daily.copy.dir-src.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg copy c e</userinput>
-copying c/a/c to e/a/c
-</screen>
--- a/en/examples/results/daily.copy.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init my-copy</userinput>
-<prompt>$</prompt> <userinput>cd my-copy</userinput>
-<prompt>$</prompt> <userinput>echo line &gt; file</userinput>
-<prompt>$</prompt> <userinput>hg add file</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Added a file'</userinput>
-</screen>
--- a/en/examples/results/daily.copy.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg pull ../my-copy</userinput>
-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)
-<prompt>$</prompt> <userinput>hg merge</userinput>
-merging file and new-file to new-file
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-<prompt>$</prompt> <userinput>cat new-file</userinput>
-line
-new contents
-</screen>
--- a/en/examples/results/daily.copy.other.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ../your-copy</userinput>
-<prompt>$</prompt> <userinput>echo 'new contents' &gt;&gt; file</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Changed file'</userinput>
-</screen>
--- a/en/examples/results/daily.copy.simple.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>mkdir k</userinput>
-<prompt>$</prompt> <userinput>hg copy a k</userinput>
-<prompt>$</prompt> <userinput>ls k</userinput>
-a
-</screen>
--- a/en/examples/results/daily.copy.status-copy.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status -C</userinput>
-A new-file
-  file
-<prompt>$</prompt> <userinput>hg commit -m 'Copied file'</userinput>
-</screen>
--- a/en/examples/results/daily.copy.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-A new-file
-</screen>
--- a/en/examples/results/daily.files.add-dir.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>mkdir b</userinput>
-<prompt>$</prompt> <userinput>echo b &gt; b/b</userinput>
-<prompt>$</prompt> <userinput>echo c &gt; b/c</userinput>
-<prompt>$</prompt> <userinput>mkdir b/d</userinput>
-<prompt>$</prompt> <userinput>echo d &gt; b/d/d</userinput>
-<prompt>$</prompt> <userinput>hg add b</userinput>
-adding b/b
-adding b/c
-adding b/d/d
-<prompt>$</prompt> <userinput>hg commit -m 'Added all files in subdirectory'</userinput>
-</screen>
--- a/en/examples/results/daily.files.add.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init add-example</userinput>
-<prompt>$</prompt> <userinput>cd add-example</userinput>
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-? a
-<prompt>$</prompt> <userinput>hg add a</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-A a
-<prompt>$</prompt> <userinput>hg commit -m 'Added one file'</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-</screen>
--- a/en/examples/results/daily.files.addremove.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init addremove-example</userinput>
-<prompt>$</prompt> <userinput>cd addremove-example</userinput>
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>echo b &gt; b</userinput>
-<prompt>$</prompt> <userinput>hg addremove</userinput>
-adding a
-adding b
-</screen>
--- a/en/examples/results/daily.files.commit-addremove.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo c &gt; c</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'Commit with addremove'</userinput>
-adding c
-</screen>
--- a/en/examples/results/daily.files.hidden.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init hidden-example</userinput>
-<prompt>$</prompt> <userinput>cd hidden-example</userinput>
-<prompt>$</prompt> <userinput>mkdir empty</userinput>
-<prompt>$</prompt> <userinput>touch empty/.hidden</userinput>
-<prompt>$</prompt> <userinput>hg add empty/.hidden</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Manage an empty-looking directory'</userinput>
-<prompt>$</prompt> <userinput>ls empty</userinput>
-<prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone hidden-example tmp</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>ls tmp</userinput>
-empty
-<prompt>$</prompt> <userinput>ls tmp/empty</userinput>
-</screen>
--- a/en/examples/results/daily.files.missing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init missing-example</userinput>
-<prompt>$</prompt> <userinput>cd missing-example</userinput>
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg add a</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'File about to be missing'</userinput>
-<prompt>$</prompt> <userinput>rm a</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-! a
-</screen>
--- a/en/examples/results/daily.files.recover-missing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg revert a</userinput>
-<prompt>$</prompt> <userinput>cat a</userinput>
-a
-<prompt>$</prompt> <userinput>hg status</userinput>
-</screen>
--- a/en/examples/results/daily.files.remove-after.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg remove --after a</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-R a
-</screen>
--- a/en/examples/results/daily.files.remove.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init remove-example</userinput>
-<prompt>$</prompt> <userinput>cd remove-example</userinput>
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>mkdir b</userinput>
-<prompt>$</prompt> <userinput>echo b &gt; b/b</userinput>
-<prompt>$</prompt> <userinput>hg add a b</userinput>
-adding b/b
-<prompt>$</prompt> <userinput>hg commit -m 'Small example for file removal'</userinput>
-<prompt>$</prompt> <userinput>hg remove a</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-R a
-<prompt>$</prompt> <userinput>hg remove b</userinput>
-removing b/b
-</screen>
--- a/en/examples/results/daily.rename.rename.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg rename a b</userinput>
-</screen>
--- a/en/examples/results/daily.rename.status-copy.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status -C</userinput>
-A b
-  a
-R a
-</screen>
--- a/en/examples/results/daily.rename.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-A b
-R a
-</screen>
--- a/en/examples/results/daily.revert.add.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo oops &gt; oops</userinput>
-<prompt>$</prompt> <userinput>hg add oops</userinput>
-<prompt>$</prompt> <userinput>hg status oops</userinput>
-A oops
-<prompt>$</prompt> <userinput>hg revert oops</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-? oops
-</screen>
--- a/en/examples/results/daily.revert.copy.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg copy file new-file</userinput>
-<prompt>$</prompt> <userinput>hg revert new-file</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-? new-file
-</screen>
--- a/en/examples/results/daily.revert.missing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>rm file</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-! file
-<prompt>$</prompt> <userinput>hg revert file</userinput>
-<prompt>$</prompt> <userinput>ls file</userinput>
-file
-</screen>
--- a/en/examples/results/daily.revert.modify.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat file</userinput>
-original content
-<prompt>$</prompt> <userinput>echo unwanted change &gt;&gt; file</userinput>
-<prompt>$</prompt> <userinput>hg diff file</userinput>
-diff -r  file
-
-
-@@ -1,1 +1,2 @@
- original content
-+unwanted change
-</screen>
--- a/en/examples/results/daily.revert.remove.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg remove file</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-R file
-<prompt>$</prompt> <userinput>hg revert file</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-<prompt>$</prompt> <userinput>ls file</userinput>
-file
-</screen>
--- a/en/examples/results/daily.revert.rename-orig.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg revert file</userinput>
-no changes needed to file
-<prompt>$</prompt> <userinput>hg status</userinput>
-? new-file
-</screen>
--- a/en/examples/results/daily.revert.rename.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg rename file new-file</userinput>
-<prompt>$</prompt> <userinput>hg revert new-file</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-? new-file
-</screen>
--- a/en/examples/results/daily.revert.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-? file.orig
-<prompt>$</prompt> <userinput>cat file.orig</userinput>
-original content
-unwanted change
-</screen>
--- a/en/examples/results/daily.revert.unmodify.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-M file
-<prompt>$</prompt> <userinput>hg revert file</userinput>
-<prompt>$</prompt> <userinput>cat file</userinput>
-original content
-</screen>
--- a/en/examples/results/extdiff.diff.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg diff</userinput>
-diff -r  myfile
-
-
-@@ -1,1 +1,2 @@
- The first line.
-+The second line.
-</screen>
--- a/en/examples/results/extdiff.extdiff-ctx.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg extdiff -o -NprcC5</userinput>
-
-
-***************
-*** 1 ****
-
-  The first line.
-+ The second line.
-</screen>
--- a/en/examples/results/extdiff.extdiff.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg extdiff</userinput>
-
-
-@@ -1 +1,2 @@
- The first line.
-+The second line.
-</screen>
--- a/en/examples/results/filenames.dirs.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status src</userinput>
-? src/main.py
-? src/watcher/_watcher.c
-? src/watcher/watcher.py
-? src/xyzzy.txt
-</screen>
--- a/en/examples/results/filenames.files.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg add COPYING README examples/simple.py</userinput>
-</screen>
--- a/en/examples/results/filenames.filter.exclude.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status -X '**.py' src</userinput>
-? src/watcher/_watcher.c
-? src/xyzzy.txt
-</screen>
--- a/en/examples/results/filenames.filter.include.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status -I '*.in'</userinput>
-? MANIFEST.in
-</screen>
--- a/en/examples/results/filenames.glob.group.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status 'glob:*.{in,py}'</userinput>
-? MANIFEST.in
-? setup.py
-</screen>
--- a/en/examples/results/filenames.glob.question.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status 'glob:**.?'</userinput>
-? src/watcher/_watcher.c
-</screen>
--- a/en/examples/results/filenames.glob.range.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status 'glob:**[nr-t]'</userinput>
-? MANIFEST.in
-? src/xyzzy.txt
-</screen>
--- a/en/examples/results/filenames.glob.star-starstar.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status 'glob:*.py'</userinput>
-? setup.py
-<prompt>$</prompt> <userinput>hg status 'glob:**.py'</userinput>
-A examples/simple.py
-A src/main.py
-? examples/performant.py
-? setup.py
-? src/watcher/watcher.py
-</screen>
--- a/en/examples/results/filenames.glob.star.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg add 'glob:*.py'</userinput>
-adding main.py
-</screen>
--- a/en/examples/results/filenames.glob.starstar.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg status 'glob:**.py'</userinput>
-A examples/simple.py
-A src/main.py
-? examples/performant.py
-? setup.py
-? src/watcher/watcher.py
-</screen>
--- a/en/examples/results/filenames.wdir-relname.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-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
-<prompt>$</prompt> <userinput>hg status `hg root`</userinput>
-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
-</screen>
--- a/en/examples/results/filenames.wdir-subdir.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd src</userinput>
-<prompt>$</prompt> <userinput>hg add -n</userinput>
-adding ../MANIFEST.in
-adding ../examples/performant.py
-adding ../setup.py
-adding main.py
-adding watcher/_watcher.c
-adding watcher/watcher.py
-adding xyzzy.txt
-<prompt>$</prompt> <userinput>hg add -n .</userinput>
-adding main.py
-adding watcher/_watcher.c
-adding watcher/watcher.py
-adding xyzzy.txt
-</screen>
--- a/en/examples/results/hook.msglen.go.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat .hg/hgrc</userinput>
-[hooks]
-pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg add a</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'too short'</userinput>
-transaction abort!
-rollback completed
-abort: pretxncommit.msglen hook exited with status 1
-<prompt>$</prompt> <userinput>hg commit -A -m 'long enough'</userinput>
-</screen>
--- a/en/examples/results/hook.msglen.run.out	Fri Mar 27 00:41:15 2009 -0700
+++ /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/results/hook.simple.ext.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'commit.when = echo -n "date of commit: "; date' &gt;&gt; .hg/hgrc</userinput>
-<prompt>$</prompt> <userinput>echo a &gt;&gt; a</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'i have two hooks'</userinput>
-committed 
-
-</screen>
--- a/en/examples/results/hook.simple.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init hook-test</userinput>
-<prompt>$</prompt> <userinput>cd hook-test</userinput>
-<prompt>$</prompt> <userinput>echo '[hooks]' &gt;&gt; .hg/hgrc</userinput>
-<prompt>$</prompt> <userinput>echo 'commit = echo committed $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
-<prompt>$</prompt> <userinput>cat .hg/hgrc</userinput>
-[hooks]
-commit = echo committed $HG_NODE
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg add a</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'testing commit hook'</userinput>
-committed 
-</screen>
--- a/en/examples/results/hook.simple.pretxncommit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat check_bug_id</userinput>
-#!/bin/sh
-# check that a commit comment mentions a numeric bug id
-hg log -r $1 --template {desc} | grep -q "\&lt;bug *[0-9]"
-<prompt>$</prompt> <userinput>echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' &gt;&gt; .hg/hgrc</userinput>
-<prompt>$</prompt> <userinput>echo a &gt;&gt; a</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'i am not mentioning a bug id'</userinput>
-transaction abort!
-rollback completed
-abort: pretxncommit.bug_id_required hook exited with status 1
-<prompt>$</prompt> <userinput>hg commit -m 'i refer you to bug 666'</userinput>
-committed 
-
-</screen>
--- a/en/examples/results/hook.ws.better.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat .hg/hgrc</userinput>
-[hooks]
-pretxncommit.whitespace = .hg/check_whitespace.py
-<prompt>$</prompt> <userinput>echo 'a ' &gt;&gt; a</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'add new line with trailing whitespace'</userinput>
-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
-<prompt>$</prompt> <userinput>sed -i 's, *$,,' a</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'trimmed trailing whitespace'</userinput>
-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
-</screen>
--- a/en/examples/results/hook.ws.simple.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat .hg/hgrc</userinput>
-[hooks]
-pretxncommit.whitespace = hg export tip | (! egrep -q '^\+.*[ \t]$')
-<prompt>$</prompt> <userinput>echo 'a ' &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'test with trailing whitespace'</userinput>
-adding a
-transaction abort!
-rollback completed
-abort: pretxncommit.whitespace hook exited with status 1
-<prompt>$</prompt> <userinput>echo 'a' &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'drop trailing whitespace and try again'</userinput>
-</screen>
--- a/en/examples/results/issue29.go.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init issue29</userinput>
-<prompt>$</prompt> <userinput>cd issue29</userinput>
-<prompt>$</prompt> <userinput>echo a &gt; a</userinput>
-<prompt>$</prompt> <userinput>hg ci -Ama</userinput>
-adding a
-<prompt>$</prompt> <userinput>echo b &gt; b</userinput>
-<prompt>$</prompt> <userinput>hg ci -Amb</userinput>
-adding b
-<prompt>$</prompt> <userinput>hg up 0</userinput>
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>mkdir b</userinput>
-<prompt>$</prompt> <userinput>echo b &gt; b/b</userinput>
-<prompt>$</prompt> <userinput>hg ci -Amc</userinput>
-adding b/b
-created new head
-<prompt>$</prompt> <userinput>hg merge</userinput>
-
-</screen>
--- a/en/examples/results/mq.dodiff.diff.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'this is my original thought' &gt; oldfile</userinput>
-<prompt>$</prompt> <userinput>echo 'i have changed my mind' &gt; newfile</userinput>
-<prompt>$</prompt> <userinput>diff -u oldfile newfile &gt; tiny.patch</userinput>
-<prompt>$</prompt> <userinput>cat tiny.patch</userinput>
-
-
-@@ -1 +1 @@
--this is my original thought
-+i have changed my mind
-<prompt>$</prompt> <userinput>patch &lt; tiny.patch</userinput>
-patching file oldfile
-<prompt>$</prompt> <userinput>cat oldfile</userinput>
-i have changed my mind
-</screen>
--- a/en/examples/results/mq.guards.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qinit</userinput>
-<prompt>$</prompt> <userinput>hg qnew hello.patch</userinput>
-<prompt>$</prompt> <userinput>echo hello &gt; hello</userinput>
-<prompt>$</prompt> <userinput>hg add hello</userinput>
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-<prompt>$</prompt> <userinput>hg qnew goodbye.patch</userinput>
-<prompt>$</prompt> <userinput>echo goodbye &gt; goodbye</userinput>
-<prompt>$</prompt> <userinput>hg add goodbye</userinput>
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-</screen>
--- a/en/examples/results/mq.guards.qguard.neg.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qguard hello.patch -quux</userinput>
-<prompt>$</prompt> <userinput>hg qguard hello.patch</userinput>
-hello.patch: -quux
-</screen>
--- a/en/examples/results/mq.guards.qguard.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qguard</userinput>
-goodbye.patch: unguarded
-</screen>
--- a/en/examples/results/mq.guards.qguard.pos.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qguard +foo</userinput>
-<prompt>$</prompt> <userinput>hg qguard</userinput>
-goodbye.patch: +foo
-</screen>
--- a/en/examples/results/mq.guards.qselect.cat.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat .hg/patches/guards</userinput>
-foo
-</screen>
--- a/en/examples/results/mq.guards.qselect.error.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qselect +foo</userinput>
-abort: guard '+foo' starts with invalid character: '+'
-</screen>
--- a/en/examples/results/mq.guards.qselect.foo.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qpop -a</userinput>
-patch queue now empty
-<prompt>$</prompt> <userinput>hg qselect</userinput>
-no active guards
-<prompt>$</prompt> <userinput>hg qselect foo</userinput>
-number of unguarded, unapplied patches has changed from 1 to 2
-<prompt>$</prompt> <userinput>hg qselect</userinput>
-foo
-</screen>
--- a/en/examples/results/mq.guards.qselect.foobar.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qselect foo bar</userinput>
-number of unguarded, unapplied patches has changed from 0 to 2
-<prompt>$</prompt> <userinput>hg qpop -a</userinput>
-no patches applied
-<prompt>$</prompt> <userinput>hg qpush -a</userinput>
-applying hello.patch
-applying goodbye.patch
-now at: goodbye.patch
-</screen>
--- a/en/examples/results/mq.guards.qselect.qpush.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qpush -a</userinput>
-applying hello.patch
-applying goodbye.patch
-now at: goodbye.patch
-</screen>
--- a/en/examples/results/mq.guards.qselect.quux.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qselect quux</userinput>
-number of guarded, applied patches has changed from 0 to 2
-<prompt>$</prompt> <userinput>hg qpop -a</userinput>
-patch queue now empty
-<prompt>$</prompt> <userinput>hg qpush -a</userinput>
-patch series already fully applied
-</screen>
--- a/en/examples/results/mq.guards.series.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat .hg/patches/series</userinput>
-hello.patch #-quux
-goodbye.patch #+foo
-</screen>
--- a/en/examples/results/mq.id.out.out	Fri Mar 27 00:41:15 2009 -0700
+++ /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/results/mq.id.output.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qapplied</userinput>
-first.patch
-second.patch
-<prompt>$</prompt> <userinput>hg log -r qbase:qtip</userinput>
-changeset:   
-tag:         first.patch
-tag:         qbase
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     [mq]: first.patch
-
-changeset:   
-tag:         qtip
-tag:         second.patch
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     [mq]: second.patch
-
-<prompt>$</prompt> <userinput>hg export second.patch</userinput>
-# HG changeset patch
-# User Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-# Node ID 
-# Parent  
-[mq]: second.patch
-
-diff -r  -r  other.c
-
-
-@@ -0,0 +1,1 @@
-+double u;
-</screen>
--- a/en/examples/results/mq.qinit-help.help.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg help qinit</userinput>
-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
-</screen>
--- a/en/examples/results/mq.tarball.download.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>download netplug-1.2.5.tar.bz2</userinput>
-<prompt>$</prompt> <userinput>tar jxf netplug-1.2.5.tar.bz2</userinput>
-<prompt>$</prompt> <userinput>cd netplug-1.2.5</userinput>
-<prompt>$</prompt> <userinput>hg init</userinput>
-<prompt>$</prompt> <userinput>hg commit -q --addremove --message netplug-1.2.5</userinput>
-<prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone netplug-1.2.5 netplug</userinput>
-updating working directory
-18 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/mq.tarball.newsource.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qpop -a</userinput>
-patch queue now empty
-<prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>download netplug-1.2.8.tar.bz2</userinput>
-<prompt>$</prompt> <userinput>hg clone netplug-1.2.5 netplug-1.2.8</userinput>
-updating working directory
-18 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd netplug-1.2.8</userinput>
-<prompt>$</prompt> <userinput>hg locate -0 | xargs -0 rm</userinput>
-<prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>tar jxf netplug-1.2.8.tar.bz2</userinput>
-<prompt>$</prompt> <userinput>cd netplug-1.2.8</userinput>
-<prompt>$</prompt> <userinput>hg commit --addremove --message netplug-1.2.8</userinput>
-</screen>
--- a/en/examples/results/mq.tarball.qinit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd netplug</userinput>
-<prompt>$</prompt> <userinput>hg qinit</userinput>
-<prompt>$</prompt> <userinput>hg qnew -m 'fix build problem with gcc 4' build-fix.patch</userinput>
-<prompt>$</prompt> <userinput>perl -pi -e 's/int addr_len/socklen_t addr_len/' netlink.c</userinput>
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-<prompt>$</prompt> <userinput>hg tip -p</userinput>
-changeset:   
-tag:         qtip
-tag:         build-fix.patch
-tag:         tip
-tag:         qbase
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     fix build problem with gcc 4
-
-diff -r  -r  netlink.c
-
-
-@@ -275,7 +275,7 @@
-         exit(1);
-     }
- 
--    int addr_len = sizeof(addr);
-+    socklen_t addr_len = sizeof(addr);
- 
-     if (getsockname(fd, (struct sockaddr *) &amp;addr, &amp;addr_len) == -1) {
-         do_log(LOG_ERR, "Could not get socket details: %m");
-
-</screen>
--- a/en/examples/results/mq.tarball.repush.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ../netplug</userinput>
-<prompt>$</prompt> <userinput>hg pull ../netplug-1.2.8</userinput>
-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)
-<prompt>$</prompt> <userinput>hg qpush -a</userinput>
-(working directory not at tip)
-applying build-fix.patch
-now at: build-fix.patch
-</screen>
--- a/en/examples/results/mq.tools.lsdiff.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<screen><prompt>$</prompt> <userinput>lsdiff -nvv remove-redundant-null-checks.patch</userinput>
-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)
-</screen>
--- a/en/examples/results/mq.tools.tools.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-<screen><prompt>$</prompt> <userinput>diffstat -p1 remove-redundant-null-checks.patch</userinput>
- 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(-)
-<prompt>$</prompt> <userinput>filterdiff -i '*/video/*' remove-redundant-null-checks.patch</userinput>
-
-
-@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void)
- {
- 	driver_unregister(&amp;au1100fb_driver);
- 
--	if (drv_info.opt_mode)
--		kfree(drv_info.opt_mode);
-+	kfree(drv_info.opt_mode);
- }
- 
- module_init(au1100fb_init);
-</screen>
--- a/en/examples/results/mq.tutorial.add.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'file 3, line 1' &gt;&gt; file3</userinput>
-<prompt>$</prompt> <userinput>hg qnew add-file3.patch</userinput>
-<prompt>$</prompt> <userinput>hg qnew -f add-file3.patch</userinput>
-abort: patch "add-file3.patch" already exists
-</screen>
--- a/en/examples/results/mq.tutorial.qinit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init mq-sandbox</userinput>
-<prompt>$</prompt> <userinput>cd mq-sandbox</userinput>
-<prompt>$</prompt> <userinput>echo 'line 1' &gt; file1</userinput>
-<prompt>$</prompt> <userinput>echo 'another line 1' &gt; file2</userinput>
-<prompt>$</prompt> <userinput>hg add file1 file2</userinput>
-<prompt>$</prompt> <userinput>hg commit -m'first change'</userinput>
-<prompt>$</prompt> <userinput>hg qinit</userinput>
-</screen>
--- a/en/examples/results/mq.tutorial.qnew.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     first change
-
-<prompt>$</prompt> <userinput>hg qnew first.patch</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         qtip
-tag:         first.patch
-tag:         tip
-tag:         qbase
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     [mq]: first.patch
-
-<prompt>$</prompt> <userinput>ls .hg/patches</userinput>
-first.patch  series  status
-</screen>
--- a/en/examples/results/mq.tutorial.qnew2.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qnew second.patch</userinput>
-<prompt>$</prompt> <userinput>hg log --style=compact --limit=2</userinput>
-2[qtip,second.patch,tip]      2009-03-10 04:38 +0000   bos
-  [mq]: second.patch
-
-1[first.patch,qbase]      2009-03-10 04:38 +0000   bos
-  [mq]: first.patch
-
-<prompt>$</prompt> <userinput>echo 'line 4' &gt;&gt; file1</userinput>
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-<prompt>$</prompt> <userinput>hg tip --style=compact --patch</userinput>
-2[qtip,second.patch,tip]      2009-03-10 04:38 +0000   bos
-  [mq]: second.patch
-
-diff -r  -r  file1
-
-
-@@ -1,3 +1,4 @@
- line 1
- line 2
- line 3
-+line 4
-
-<prompt>$</prompt> <userinput>hg annotate file1</userinput>
-0: line 1
-1: line 2
-1: line 3
-2: line 4
-</screen>
--- a/en/examples/results/mq.tutorial.qpop.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qapplied</userinput>
-first.patch
-second.patch
-<prompt>$</prompt> <userinput>hg qpop</userinput>
-now at: first.patch
-<prompt>$</prompt> <userinput>hg qseries</userinput>
-first.patch
-second.patch
-<prompt>$</prompt> <userinput>hg qapplied</userinput>
-first.patch
-<prompt>$</prompt> <userinput>cat file1</userinput>
-line 1
-line 2
-line 3
-</screen>
--- a/en/examples/results/mq.tutorial.qpush-a.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qpush -a</userinput>
-applying second.patch
-now at: second.patch
-<prompt>$</prompt> <userinput>cat file1</userinput>
-line 1
-line 2
-line 3
-line 4
-</screen>
--- a/en/examples/results/mq.tutorial.qrefresh.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'line 2' &gt;&gt; file1</userinput>
-<prompt>$</prompt> <userinput>hg diff</userinput>
-diff -r  file1
-
-
-@@ -1,1 +1,2 @@
- line 1
-+line 2
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-<prompt>$</prompt> <userinput>hg diff</userinput>
-<prompt>$</prompt> <userinput>hg tip --style=compact --patch</userinput>
-1[qtip,first.patch,tip,qbase]      2009-03-10 04:38 +0000   bos
-  [mq]: first.patch
-
-diff -r  -r  file1
-
-
-@@ -1,1 +1,2 @@
- line 1
-+line 2
-
-</screen>
--- a/en/examples/results/mq.tutorial.qrefresh2.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo 'line 3' &gt;&gt; file1</userinput>
-<prompt>$</prompt> <userinput>hg status</userinput>
-M file1
-<prompt>$</prompt> <userinput>hg qrefresh</userinput>
-<prompt>$</prompt> <userinput>hg tip --style=compact --patch</userinput>
-1[qtip,first.patch,tip,qbase]      2009-03-10 04:38 +0000   bos
-  [mq]: first.patch
-
-diff -r  -r  file1
-
-
-@@ -1,1 +1,3 @@
- line 1
-+line 2
-+line 3
-
-</screen>
--- a/en/examples/results/mq.tutorial.qseries.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg qseries</userinput>
-first.patch
-second.patch
-<prompt>$</prompt> <userinput>hg qapplied</userinput>
-first.patch
-second.patch
-</screen>
--- a/en/examples/results/rename.divergent.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg clone orig anne</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>hg clone orig bob</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/rename.divergent.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-<screen># See http://www.selenic.com/mercurial/bts/issue455
-<prompt>$</prompt> <userinput>cd ../orig</userinput>
-<prompt>$</prompt> <userinput>hg pull -u ../anne</userinput>
-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
-<prompt>$</prompt> <userinput>hg pull ../bob</userinput>
-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)
-<prompt>$</prompt> <userinput>hg merge</userinput>
-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)
-<prompt>$</prompt> <userinput>ls</userinput>
-bar  quux
-</screen>
--- a/en/examples/results/rename.divergent.rename.anne.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd anne</userinput>
-<prompt>$</prompt> <userinput>hg mv foo bar</userinput>
-<prompt>$</prompt> <userinput>hg ci -m 'Rename foo to bar'</userinput>
-</screen>
--- a/en/examples/results/rename.divergent.rename.bob.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ../bob</userinput>
-<prompt>$</prompt> <userinput>hg mv foo quux</userinput>
-<prompt>$</prompt> <userinput>hg ci -m 'Rename foo to quux'</userinput>
-</screen>
--- a/en/examples/results/rollback.add.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg add b</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Add file b, this time for real'</userinput>
-</screen>
--- a/en/examples/results/rollback.commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-M a
-<prompt>$</prompt> <userinput>echo b &gt; b</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Add file b'</userinput>
-</screen>
--- a/en/examples/results/rollback.rollback.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg rollback</userinput>
-rolling back last transaction
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     First commit
-
-<prompt>$</prompt> <userinput>hg status</userinput>
-M a
-? b
-</screen>
--- a/en/examples/results/rollback.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg status</userinput>
-? b
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Add file b
-
-</screen>
--- a/en/examples/results/rollback.tip.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<screen></screen>
--- a/en/examples/results/rollback.twice.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg rollback</userinput>
-rolling back last transaction
-<prompt>$</prompt> <userinput>hg rollback</userinput>
-no rollback information available
-</screen>
--- a/en/examples/results/tag.init.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg init mytag</userinput>
-<prompt>$</prompt> <userinput>cd mytag</userinput>
-<prompt>$</prompt> <userinput>echo hello &gt; myfile</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'Initial commit'</userinput>
-adding myfile
-</screen>
--- a/en/examples/results/tag.log.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added tag v1.0 for changeset 
-
-changeset:   
-tag:         v1.0
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Initial commit
-
-</screen>
--- a/en/examples/results/tag.log.v1.0.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>echo goodbye &gt; myfile2</userinput>
-<prompt>$</prompt> <userinput>hg commit -A -m 'Second commit'</userinput>
-adding myfile2
-<prompt>$</prompt> <userinput>hg log -r v1.0</userinput>
-changeset:   
-tag:         v1.0
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Initial commit
-
-</screen>
--- a/en/examples/results/tag.remove.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tag --remove v1.0</userinput>
-<prompt>$</prompt> <userinput>hg tags</userinput>
-tip                                
-</screen>
--- a/en/examples/results/tag.replace.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tag -r 1 v1.1</userinput>
-<prompt>$</prompt> <userinput>hg tags</userinput>
-tip                                
-v1.1                               
-<prompt>$</prompt> <userinput>hg tag -r 2 v1.1</userinput>
-abort: tag 'v1.1' already exists (use -f to force)
-<prompt>$</prompt> <userinput>hg tag -f -r 2 v1.1</userinput>
-<prompt>$</prompt> <userinput>hg tags</userinput>
-tip                                
-v1.1                               
-</screen>
--- a/en/examples/results/tag.tag.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tag v1.0</userinput>
-</screen>
--- a/en/examples/results/tag.tags.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tags</userinput>
-tip                                
-v1.0                               
-</screen>
--- a/en/examples/results/tag.tip.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added tag v1.1 for changeset 
-
-</screen>
--- a/en/examples/results/template.simple.changelog.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.combine.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.compact.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.datekeyword.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-
-
-
-
--- a/en/examples/results/template.simple.keywords.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.manyfilters.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.normal.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.simple.rev.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-
-
-
--- a/en/examples/results/template.simple.simplest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-
-
-
--- a/en/examples/results/template.simple.simplesub.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
--- a/en/examples/results/template.svnstyle.id.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -r0 --template '{node}'</userinput>
-</screen>
--- a/en/examples/results/template.svnstyle.result.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -r1 --style svn.style</userinput>
-------------------------------------------------------------------------
-
-r1 | bos | 
-
-added line to end of &lt;&lt;hello&gt;&gt; file.
-
-in addition, added a file with the helpful name (at least i hope that some
-might consider it so) of goodbye.
-
-------------------------------------------------------------------------
-</screen>
--- a/en/examples/results/template.svnstyle.short.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>svn log -r9653</userinput>
-------------------------------------------------------------------------
-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 &lt;sean.hefty@intel.com&gt;
-
-------------------------------------------------------------------------
-</screen>
--- a/en/examples/results/template.svnstyle.simplest.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat svn.style</userinput>
-changeset = "{node|short}\n"
-<prompt>$</prompt> <userinput>hg log -r1 --style svn.style</userinput>
-
-</screen>
--- a/en/examples/results/template.svnstyle.style.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat svn.style</userinput>
-header = '------------------------------------------------------------------------\n\n'
-changeset = svn.template
-</screen>
--- a/en/examples/results/template.svnstyle.syntax.error.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -r1 --style broken.style</userinput>
-abort: broken.style:1: parse error
-</screen>
--- a/en/examples/results/template.svnstyle.syntax.input.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat broken.style</userinput>
-changeset =
-</screen>
--- a/en/examples/results/template.svnstyle.template.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat svn.template</userinput>
-r{rev} | {author|user} | {date|isodate} ({date|rfc822date})
-
-{desc|strip|fill76}
-
-------------------------------------------------------------------------
-</screen>
--- a/en/examples/results/tour-merge-conflict.commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat &gt; letter.txt &lt;&lt;EOF</userinput>
-<prompt>></prompt> <userinput>Greetings!</userinput>
-<prompt>></prompt> <userinput>I am Bryan O'Sullivan, no relation of the former</userinput>
-<prompt>></prompt> <userinput>Nigerian dictator Sani Abacha.</userinput>
-<prompt>></prompt> <userinput>EOF</userinput>
-<prompt>$</prompt> <userinput>hg resolve -m letter.txt</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'Send me your money'</userinput>
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Send me your money
-
-</screen>
--- a/en/examples/results/tour-merge-conflict.cousin.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone scam scam-cousin</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd scam-cousin</userinput>
-<prompt>$</prompt> <userinput>cat &gt; letter.txt &lt;&lt;EOF</userinput>
-<prompt>></prompt> <userinput>Greetings!</userinput>
-<prompt>></prompt> <userinput>I am Shehu Musa Abacha, cousin to the former</userinput>
-<prompt>></prompt> <userinput>Nigerian dictator Sani Abacha.</userinput>
-<prompt>></prompt> <userinput>EOF</userinput>
-<prompt>$</prompt> <userinput>hg commit -m '419 scam, with cousin'</userinput>
-</screen>
--- a/en/examples/results/tour-merge-conflict.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<screen><prompt>$</prompt> <userinput>export HGMERGE=merge</userinput>
-<prompt>$</prompt> <userinput>echo 'XXX this is broken and must be fixed'</userinput>
-XXX this is broken and must be fixed
-<prompt>$</prompt> <userinput>hg merge</userinput>
-merging letter.txt
-merge: warning: conflicts during merge
-merging letter.txt failed!
-0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges
-<prompt>$</prompt> <userinput>cat letter.txt</userinput>
-Greetings!
-&lt;&lt;&lt;&lt;&lt;&lt;&lt; /tmp/tour-merge-conflictBrdfE0/scam-merge/letter.txt
-I am Shehu Musa Abacha, cousin to the former
-=======
-I am Alhaji Abba Abacha, son of the former
-&gt;&gt;&gt;&gt;&gt;&gt;&gt; /tmp/letter.txt~other.1ctEYy
-Nigerian dictator Sani Abacha.
-</screen>
--- a/en/examples/results/tour-merge-conflict.pull.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone scam-cousin scam-merge</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd scam-merge</userinput>
-<prompt>$</prompt> <userinput>hg pull -u ../scam-son</userinput>
-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)
-</screen>
--- a/en/examples/results/tour-merge-conflict.son.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone scam scam-son</userinput>
-updating working directory
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd scam-son</userinput>
-<prompt>$</prompt> <userinput>cat &gt; letter.txt &lt;&lt;EOF</userinput>
-<prompt>></prompt> <userinput>Greetings!</userinput>
-<prompt>></prompt> <userinput>I am Alhaji Abba Abacha, son of the former</userinput>
-<prompt>></prompt> <userinput>Nigerian dictator Sani Abacha.</userinput>
-<prompt>></prompt> <userinput>EOF</userinput>
-<prompt>$</prompt> <userinput>hg commit -m '419 scam, with son'</userinput>
-</screen>
--- a/en/examples/results/tour-merge-conflict.wife.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat &gt; letter.txt &lt;&lt;EOF</userinput>
-<prompt>></prompt> <userinput>Greetings!</userinput>
-<prompt>></prompt> <userinput>I am Mariam Abacha, the wife of former</userinput>
-<prompt>></prompt> <userinput>Nigerian dictator Sani Abacha.</userinput>
-<prompt>></prompt> <userinput>EOF</userinput>
-<prompt>$</prompt> <userinput>hg add letter.txt</userinput>
-<prompt>$</prompt> <userinput>hg commit -m '419 scam, first draft'</userinput>
-</screen>
--- a/en/examples/results/tour.clone-pull.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone hello hello-pull</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/tour.clone-push.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone hello hello-push</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/tour.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg clone http://hg.serpentine.com/tutorial/hello</userinput>
-destination directory: hello
-requesting all changes
-adding changesets
-adding manifests
-adding file changes
-added 5 changesets with 5 changes to 2 files
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/tour.commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg commit</userinput>
-</screen>
--- a/en/examples/results/tour.diff.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg diff</userinput>
-diff -r  hello.c
-
-
-@@ -8,5 +8,6 @@
- int main(int argc, char **argv)
- {
- 	printf("hello, world!\");
-+	printf("hello again!\n");
- 	return 0;
- }
-</screen>
--- a/en/examples/results/tour.help.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg help init</userinput>
-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.
-    See 'hg help urls' for more information.
-
-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
-</screen>
--- a/en/examples/results/tour.incoming.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd hello-pull</userinput>
-<prompt>$</prompt> <userinput>hg incoming ../my-hello</userinput>
-comparing with ../my-hello
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-</screen>
--- a/en/examples/results/tour.log-r.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -r 3</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Get make to generate the final binary from a .o file.
-
-<prompt>$</prompt> <userinput>hg log -r </userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Get make to generate the final binary from a .o file.
-
-<prompt>$</prompt> <userinput>hg log -r 1 -r 4</userinput>
-changeset:   
-user:        mpm@selenic.com
-
-summary:     Create a makefile
-
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Trim comments.
-
-</screen>
--- a/en/examples/results/tour.log-v.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -v -r 3</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-files:       Makefile
-description:
-Get make to generate the final binary from a .o file.
-
-
-</screen>
--- a/en/examples/results/tour.log-vp.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -v -p -r 2</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-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!\n");
-+	printf("hello, world!\");
- 	return 0;
- }
-
-</screen>
--- a/en/examples/results/tour.log.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Trim comments.
-
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Get make to generate the final binary from a .o file.
-
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-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
-
-</screen>
--- a/en/examples/results/tour.log.range.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg log -r 2:4</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Introduce a typo into hello.c.
-
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Get make to generate the final binary from a .o file.
-
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Trim comments.
-
-</screen>
--- a/en/examples/results/tour.ls-a.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd hello</userinput>
-<prompt>$</prompt> <userinput>ls -a</userinput>
-.  ..  .hg  Makefile  hello.c
-</screen>
--- a/en/examples/results/tour.ls.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>ls -l</userinput>
-
-
-<prompt>$</prompt> <userinput>ls hello</userinput>
-Makefile  hello.c
-</screen>
--- a/en/examples/results/tour.merge.cat.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cat hello.c</userinput>
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include &lt;stdio.h&gt;
-
-int main(int argc, char **argv)
-{
-	printf("once more, hello.\n");
-	printf("hello, world!\");
-	return 0;
-}
-<prompt>$</prompt> <userinput>cat ../my-hello/hello.c</userinput>
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include &lt;stdio.h&gt;
-
-int main(int argc, char **argv)
-{
-	printf("hello, world!\");
-	printf("hello again!\n");
-	return 0;
-}
-</screen>
--- a/en/examples/results/tour.merge.clone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone hello my-new-hello</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd my-new-hello</userinput>
-<prompt>$</prompt> <userinput>sed -i '/printf/i\\tprintf("once more, hello.\\n");' hello.c</userinput>
-<prompt>$</prompt> <userinput>hg commit -m 'A new hello for a new day.'</userinput>
-</screen>
--- a/en/examples/results/tour.merge.commit.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg commit -m 'Merged changes'</userinput>
-</screen>
--- a/en/examples/results/tour.merge.heads.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg heads</userinput>
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     A new hello for a new day.
-
-</screen>
--- a/en/examples/results/tour.merge.merge.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg merge</userinput>
-merging hello.c
-0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-</screen>
--- a/en/examples/results/tour.merge.parents.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     A new hello for a new day.
-
-changeset:   
-tag:         tip
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-<prompt>$</prompt> <userinput>cat hello.c</userinput>
-/*
- * Placed in the public domain by Bryan O'Sullivan.  This program is
- * not covered by patents in the United States or other countries.
- */
-
-#include &lt;stdio.h&gt;
-
-int main(int argc, char **argv)
-{
-	printf("once more, hello.\n");
-	printf("hello, world!\");
-	printf("hello again!\n");
-	return 0;
-}
-</screen>
--- a/en/examples/results/tour.merge.pull.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg pull ../my-hello</userinput>
-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)
-</screen>
--- a/en/examples/results/tour.merge.tip.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-parent:      
-parent:      
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Merged changes
-
-</screen>
--- a/en/examples/results/tour.merge.update.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg update</userinput>
-abort: crosses branches (use 'hg merge' or 'hg update -C')
-</screen>
--- a/en/examples/results/tour.older.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg update 2</userinput>
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Introduce a typo into hello.c.
-
-<prompt>$</prompt> <userinput>hg update</userinput>
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-</screen>
--- a/en/examples/results/tour.outgoing.net.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg outgoing http://hg.serpentine.com/tutorial/hello</userinput>
-comparing with http://hg.serpentine.com/tutorial/hello
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-</screen>
--- a/en/examples/results/tour.outgoing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd my-hello</userinput>
-<prompt>$</prompt> <userinput>hg outgoing ../hello-push</userinput>
-comparing with ../hello-push
-searching for changes
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-</screen>
--- a/en/examples/results/tour.parents.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg parents</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-</screen>
--- a/en/examples/results/tour.pull.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Trim comments.
-
-<prompt>$</prompt> <userinput>hg pull ../my-hello</userinput>
-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)
-<prompt>$</prompt> <userinput>hg tip</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-summary:     Added an extra line of output
-
-</screen>
--- a/en/examples/results/tour.push.net.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg push http://hg.serpentine.com/tutorial/hello</userinput>
-pushing to http://hg.serpentine.com/tutorial/hello
-searching for changes
-ssl required
-</screen>
--- a/en/examples/results/tour.push.nothing.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg push ../hello-push</userinput>
-pushing to ../hello-push
-searching for changes
-no changes found
-</screen>
--- a/en/examples/results/tour.push.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg push ../hello-push</userinput>
-pushing to ../hello-push
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
-</screen>
--- a/en/examples/results/tour.reclone.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<screen><prompt>$</prompt> <userinput>cd ..</userinput>
-<prompt>$</prompt> <userinput>hg clone hello my-hello</userinput>
-updating working directory
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>cd my-hello</userinput>
-</screen>
--- a/en/examples/results/tour.sed.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<screen><prompt>$</prompt> <userinput>sed -i '/printf/a\\tprintf("hello again!\\n");' hello.c</userinput>
-</screen>
--- a/en/examples/results/tour.status.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<screen><prompt>$</prompt> <userinput>ls</userinput>
-Makefile  hello.c
-<prompt>$</prompt> <userinput>hg status</userinput>
-M hello.c
-</screen>
--- a/en/examples/results/tour.tip.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg tip -vp</userinput>
-changeset:   
-tag:         tip
-user:        Bryan O'Sullivan &lt;bos@serpentine.com&gt;
-
-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)
- {
- 	printf("hello, world!\");
-+	printf("hello again!\n");
- 	return 0;
- }
-
-</screen>
--- a/en/examples/results/tour.update.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<screen><prompt>$</prompt> <userinput>grep printf hello.c</userinput>
-	printf("hello, world!\");
-<prompt>$</prompt> <userinput>hg update tip</userinput>
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-<prompt>$</prompt> <userinput>grep printf hello.c</userinput>
-	printf("hello, world!\");
-	printf("hello again!\n");
-</screen>
--- a/en/examples/results/tour.version.out	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<screen><prompt>$</prompt> <userinput>hg version</userinput>
-Mercurial Distributed SCM (version )
-
-Copyright (C) 2005-2008 Matt Mackall &lt;mpm@selenic.com&gt; 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.
-</screen>
Binary file en/figs/kdiff3.png has changed
Binary file en/figs/note.png has changed
--- a/examples/hg-interdiff	Fri Mar 27 00:41:15 2009 -0700
+++ /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	Fri Mar 27 00:41:15 2009 -0700
+++ /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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Fri Mar 27 00:41:15 2009 -0700
+++ /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.es.html	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-<!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>
--- a/html/index.html.var	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/po/zh.po	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,16668 @@
+#
+# Simplified Chinese translation for hgbook
+# This file is distributed under the same license as the hgbook.
+#
+# Authors:
+# Dongsheng Song <dongsheng.song@gmail.com>, 2009
+#
+# Update to new pot:
+#    msgmerge --update zh.po hgbook.pot
+#
+# 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            删除(只从文件系统删除)
+# patchset          补丁集
+# pushing to        推到
+# pulling from      拉自,抓取
+# rename            改名
+# repository        版本库
+# revert            恢复
+# revision          版本
+# tag               标签
+# tip               顶点
+# undo              撤销
+# unversioned       未版本控制
+# versioned         受版本控制
+# working copy      工作副本
+# ...
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: hgbook 1.2\n"
+"POT-Creation-Date: 2009-03-20 17:12+0800\n"
+"PO-Revision-Date: 2009-03-20 17:12+0800\n"
+"Last-Translator: \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><authorgroup><author><firstname>
+#: ../en/00book.xml:50
+msgid "Bryan"
+msgstr "Bryan"
+
+#. type: Content of: <book><bookinfo><authorgroup><author><surname>
+#: ../en/00book.xml:51
+msgid "O'Sullivan"
+msgstr "O'Sullivan"
+
+#. type: Content of: <book><bookinfo>
+#: ../en/00book.xml:55
+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/appA-cmdref.xml:4
+msgid "Command reference"
+msgstr "命令参考"
+
+#. type: Content of: <book><appendix><para>
+#: ../en/appA-cmdref.xml:6
+msgid ""
+"\\cmdref{add}{add files at the next commit} \\optref{add}{I}{include} \\optref"
+"{add}{X}{exclude} \\optref{add}{n}{dry-run}"
+msgstr ""
+
+#. type: Content of: <book><appendix><para>
+#: ../en/appA-cmdref.xml:11
+msgid "\\cmdref{diff}{print changes in history or working directory}"
+msgstr ""
+
+#. type: Content of: <book><appendix><para>
+#: ../en/appA-cmdref.xml:13
+msgid ""
+"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 <xref linkend=\"sec.mq.patch\"/>."
+msgstr ""
+
+#. type: Content of: <book><appendix><para>
+#: ../en/appA-cmdref.xml:17
+msgid ""
+"By default, this command does not print diffs for files that Mercurial "
+"considers to contain binary data.  To control this behaviour, see the <option "
+"role=\"hg-opt-diff\">-a</option> and <option role=\"hg-opt-diff\">--git</"
+"option> options."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><title>
+#: ../en/appA-cmdref.xml:22
+msgid "Options"
+msgstr "选项"
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:24
+msgid "\\loptref{diff}{nodates}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:26
+msgid "Omit date and time information when printing diff headers."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:28
+msgid "\\optref{diff}{B}{ignore-blank-lines}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:30
+msgid ""
+"Do not print changes that only insert or delete blank lines.  A line that "
+"contains only whitespace is not considered blank."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:34
+msgid "\\optref{diff}{I}{include}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:37
+msgid "Include files and directories whose names match the given patterns."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:40
+msgid "\\optref{diff}{X}{exclude}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:43
+msgid "Exclude files and directories whose names match the given patterns."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:46
+msgid "\\optref{diff}{a}{text}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:49
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:55
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:60
+msgid "\\optref{diff}{b}{ignore-space-change}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:63
+msgid ""
+"Do not print a line if the only change to that line is in the amount of white "
+"space it contains."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:67
+msgid "\\optref{diff}{g}{git}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:70
+msgid ""
+"Print <command>git</command>-compatible diffs.  XXX reference a format "
+"description."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:74
+msgid "\\optref{diff}{p}{show-function}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:77
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:84
+msgid "\\optref{diff}{r}{rev}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:87
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><orderedlist><listitem><para>
+#: ../en/appA-cmdref.xml:93
+msgid ""
+"Display the differences between the parent revision of the working directory "
+"and the working directory."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><orderedlist><listitem><para>
+#: ../en/appA-cmdref.xml:97
+msgid ""
+"Display the differences between the specified changeset and the working "
+"directory."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><orderedlist><listitem><para>
+#: ../en/appA-cmdref.xml:101
+msgid "Display the differences between the two specified changesets."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:105
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:112
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:122
+msgid "\\optref{diff}{w}{ignore-all-space}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:125
+msgid "\\cmdref{version}{print version and copyright information}"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><para>
+#: ../en/appA-cmdref.xml:128
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para>
+#: ../en/appA-cmdref.xml:133
+msgid ""
+"The string <quote><literal>unknown</literal></quote>. This version of "
+"Mercurial was not built in a Mercurial repository, and cannot determine its "
+"own version."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para>
+#: ../en/appA-cmdref.xml:138
+msgid ""
+"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.)"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para>
+#: ../en/appA-cmdref.xml:146
+msgid ""
+"A hexadecimal string, such as <quote><literal>875489e31abe</literal></"
+"quote>.  This is a build of the given revision of Mercurial."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para>
+#: ../en/appA-cmdref.xml:150
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><title>
+#: ../en/appA-cmdref.xml:159
+msgid "Tips and tricks"
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><title>
+#: ../en/appA-cmdref.xml:162
+msgid ""
+"Why do the results of <command role=\"hg-cmd\">hg diff</command> and <command "
+"role=\"hg-cmd\">hg status</command> differ?"
+msgstr ""
+"为什么 <command role=\"hg-cmd\">hg diff</command> 与 <command role=\"hg-cmd"
+"\">hg status</command> 的结果不同 ?"
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:164
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:171
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:179
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:184
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><title>
+#: ../en/appA-cmdref.xml:200
+msgid "Generating safe binary diffs"
+msgstr "生成安全的二进制差异"
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:202
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><appendix><sect2><sect3><para>
+#: ../en/appA-cmdref.xml:209
+msgid ""
+"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."
+msgstr ""
+
+#. 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>&emdash;显示已应用的补丁"
+
+#. 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>&emdash;提交队列中的修改"
+
+#. 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>&emdash;从文件 <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>&emdash;显示最新应用补丁的差异"
+
+#. 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>&emdash;将多个补丁合并(<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>&emdash;显示补丁头部描述"
+
+#. 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>&emdash;将第三方补丁导入队列"
+
+#. 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>&emdash;为使用 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>&emdash;创建新补丁"
+
+#. 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>&emdash;显示下个补丁的名称"
+
+#. 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>&emdash;删除堆栈顶部的补丁"
+
+#. 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>&emdash;显示上个补丁的名称"
+
+#. 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>&emdash;增加补丁到堆栈"
+
+#. 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>&emdash;更新最新的补丁"
+
+#. 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>&emdash;改名补丁"
+
+#. 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>&emdash;恢复保存的队列"
+
+#. 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>&emdash;保存当前的队列状态"
+
+#. 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>&emdash;显示补丁序列"
+
+#. 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>&emdash;显示当前补丁的名称"
+
+#. 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>&emdash;显示尚未应用的补丁"
+
+#. 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>&emdash;删除一个版本及其后继"
+
+#. 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 section <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 section <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---at least in theory---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:75
+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:83
+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:90
+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:95
+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:105
+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:112
+msgid "The many names of revision control"
+msgstr "版本控制的别名"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:114
+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:118
+msgid "Revision control (RCS)"
+msgstr "版本控制(RCS)"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:119
+msgid "Software configuration management (SCM), or configuration management"
+msgstr "软件配置管理(SCM),或配置管理"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:121
+msgid "Source code management"
+msgstr "源代码管理"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:122
+msgid "Source code control, or source control"
+msgstr "源代码控制,或源控制"
+
+#. type: Content of: <book><preface><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:124
+msgid "Version control (VCS)"
+msgstr "版本控制(VCS)"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:126
+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:134
+msgid "This book is a work in progress"
+msgstr "本书正在编写中"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:136
+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:143
+msgid "About the examples in this book"
+msgstr "本书的例子"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:145
+msgid ""
+"This book takes an unusual approach to code samples.  Every example is "
+"<quote>live</quote>---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:152
+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:159
+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:167
+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 section <xref linkend="
+"\"sec.undo.bisect\"/>, for instance."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:173
+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:181
+msgid "Trends in the field"
+msgstr "版本控制的发展趋势"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:183
+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:188
+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:194
+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:206
+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:218
+msgid "A few of the advantages of distributed revision control"
+msgstr "分布版本控制的优点"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:221
+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:228
+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:239
+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:247
+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:258
+msgid "Advantages for open source projects"
+msgstr "开源项目的优点"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:260
+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:276
+msgid "The forking non-problem"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><sect3><para>
+#: ../en/ch00-preface.xml:278
+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:288
+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:297
+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:306
+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:313
+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:317
+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:322
+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:337
+msgid "Advantages for commercial projects"
+msgstr "商业项目的优点"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:339
+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:351
+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---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."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:363
+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:374
+msgid "Why choose Mercurial?"
+msgstr "为什么选择 Mercurial?"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:376
+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:379
+msgid "It is easy to learn and use."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:380
+msgid "It is lightweight."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:381
+msgid "It scales excellently."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:382
+msgid "It is easy to customise."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:385
+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:392
+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:399
+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:404
+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:414
+msgid "Mercurial compared with other tools"
+msgstr "Mercurial 与其它工具的比较"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:416
+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:424 ../en/ch00-preface.xml:635
+msgid "Subversion"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:426
+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:430
+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:435
+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:441
+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:454
+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:464
+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:470
+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:479
+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:486
+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:498 ../en/ch00-preface.xml:637
+msgid "Git"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:500
+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:505
+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:510
+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:517
+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:528
+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:534
+msgid "Mercurial can import revision history from a Git repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><itemizedlist><listitem><para>
+#: ../en/ch00-preface.xml:540 ../en/ch00-preface.xml:636
+msgid "CVS"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:542
+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:546
+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:558
+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:566
+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:580
+msgid "Mercurial can import revision history from a CVS repository."
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><sect2><title>
+#: ../en/ch00-preface.xml:586
+msgid "Commercial tools"
+msgstr "商业工具"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:588
+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:594
+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:603
+msgid "Choosing a revision control tool"
+msgstr "选择版本控制工具"
+
+#. type: Content of: <book><preface><sect1><sect2><para>
+#: ../en/ch00-preface.xml:605
+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:610
+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:614
+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:622
+msgid "Switching from another tool to Mercurial"
+msgstr "从其它工具切换到 Mercurial"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:624
+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:632
+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:638
+msgid "Darcs"
+msgstr ""
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:640
+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:646
+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:655
+msgid "A short history of revision control"
+msgstr "版本控制简史"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:657
+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:668
+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:674
+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:685
+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:696
+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:703
+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:713
+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:722
+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:731
+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:739
+msgid "Colophon&emdash;this book is Free"
+msgstr "后记&emdash;本书是自由的!"
+
+#. type: Content of: <book><preface><sect1><para>
+#: ../en/ch00-preface.xml:741
+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:746
+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 "Linux"
+msgstr "Linux"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:17
+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:24
+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:32
+msgid "Debian:"
+msgstr "Debian:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:34
+msgid "Fedora Core:"
+msgstr "Fedora Core:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:36
+msgid "Gentoo:"
+msgstr "Gentoo:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:38
+msgid "OpenSUSE:"
+msgstr "OpenSUSE:"
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:40
+msgid ""
+"Ubuntu: Ubuntu's Mercurial package is based on Debian's.  To install it, run "
+"the following command."
+msgstr "Ubuntu: Ubuntu 的 Mercurial 包基于 Debian。安装时,使用如下命令:"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:48
+msgid "Solaris"
+msgstr "Solaris"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:50
+msgid ""
+"SunFreeWare, at <ulink url=\"http://www.sunfreeware.com\">http://www."
+"sunfreeware.com</ulink>, is a good source for a large number of pre-built "
+"Solaris packages for 32 and 64 bit Intel and Sparc architectures, including "
+"current versions of Mercurial."
+msgstr ""
+"位于 <ulink url=\"http://www.sunfreeware.com\">http://www.sunfreeware.com</"
+"ulink> 的 SunFreeWare 是很好的二进制安装源,它包含 Intel 和 Sparc 架构的 32 位"
+"和 64 位包,包含 Mercurial 的当前版本。"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:58
+msgid "Mac OS X"
+msgstr "Mac OS X"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:60
+msgid ""
+"Lee Cantey publishes an installer of Mercurial for Mac OS X at <ulink url="
+"\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>.  "
+"This package works on both Intel- and Power-based Macs. Before you can use "
+"it, you must install a compatible version of Universal MacPython "
+"<citation>web:macpython</citation>. This is easy to do; simply follow the "
+"instructions on Lee's site."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:69
+msgid ""
+"It's also possible to install Mercurial using Fink or MacPorts, two popular "
+"free package managers for Mac OS X.  If you have Fink, use <command>sudo apt-"
+"get install mercurial-py25</command>.  If MacPorts, <command>sudo port "
+"install mercurial</command>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:77
+msgid "Windows"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:79
+msgid ""
+"Lee Cantey publishes an installer of Mercurial for Windows at <ulink url="
+"\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>.  "
+"This package has no external dependencies; it <quote>just works</quote>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch01-tour-basic.xml:86
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:96
+msgid "Getting started"
+msgstr "开始"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:98
+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:107
+msgid "Built-in help"
+msgstr "内置帮助"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:109
+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:120
+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:131
+msgid "Working with a repository"
+msgstr "使用版本库"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:133
+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:139
+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:146
+msgid "Making a local copy of a repository"
+msgstr "创建版本库的工作副本"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:148
+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 creates an identical copy of an existing repository."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:157
+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:163
+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:166
+msgid ""
+"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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:173
+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:179
+msgid "What's in a repository?"
+msgstr "什么是版本库?"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:181
+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:188
+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:194
+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:209
+msgid "A tour through history"
+msgstr "回溯历史"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:211
+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 history."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:218
+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:224
+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:227
+msgid ""
+"<literal>changeset</literal>: This field has the format of a number, followed "
+"by a colon, followed by a hexadecimal string.  These are "
+"<emphasis>identifiers</emphasis> for the changeset.  There are two "
+"identifiers because the number is shorter and easier to type than the hex "
+"string."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:233
+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:237
+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:242
+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><para>
+#: ../en/ch01-tour-basic.xml:245
+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:249
+msgid ""
+"Figure <xref endterm=\"fig.tour-basic.history.caption\" 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><informalfigure><mediaobject>
+#: ../en/ch01-tour-basic.xml:260
+msgid ""
+"<imageobject><imagedata fileref=\"images/tour-history.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><textobject><phrase>
+#: ../en/ch01-tour-basic.xml:261 ../en/ch02-tour-merge.xml:48
+#: ../en/ch02-tour-merge.xml:78 ../en/ch02-tour-merge.xml:126
+#: ../en/ch02-tour-merge.xml:182 ../en/ch02-tour-merge.xml:254
+#: ../en/ch03-concepts.xml:56 ../en/ch03-concepts.xml:108
+#: ../en/ch03-concepts.xml:194 ../en/ch03-concepts.xml:301
+#: ../en/ch03-concepts.xml:353 ../en/ch03-concepts.xml:370
+#: ../en/ch03-concepts.xml:414 ../en/ch03-concepts.xml:436
+#: ../en/ch03-concepts.xml:480 ../en/ch05-collab.xml:277
+#: ../en/ch08-undo.xml:366 ../en/ch08-undo.xml:417 ../en/ch08-undo.xml:485
+#: ../en/ch08-undo.xml:527 ../en/ch11-mq.xml:410
+msgid "XXX add text"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
+#: ../en/ch01-tour-basic.xml:262
+msgid ""
+"Graphical history of the <filename class=\"directory\">hello</filename> "
+"repository"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch01-tour-basic.xml:269
+msgid "Changesets, revisions, and talking to other people"
+msgstr "改变集,版本,与其它用户交互"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:272
+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:282
+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:291
+msgid ""
+"The revision number is <emphasis>only valid in that repository</emphasis>,"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:293
+msgid ""
+"while the hex 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:298
+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 $a,b,c$ can easily "
+"appear in one repository as $0,1,2$, while in another as $1,0,2$."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:308
+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:316
+msgid "Viewing specific revisions"
+msgstr "察看指定版本"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:318
+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 long-form changeset 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:327
+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:335
+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:342
+msgid "More detailed information"
+msgstr "更详细的信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:344
+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:356
+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 section <xref linkend=\"sec.mq.patch\"/> for an overview)."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:369
+msgid "All about command options"
+msgstr "命令选项"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:371
+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:375
+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:380
+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:384
+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:389
+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:393
+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><para>
+#: ../en/ch01-tour-basic.xml:399
+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:403
+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><title>
+#: ../en/ch01-tour-basic.xml:411
+msgid "Making and reviewing changes"
+msgstr "创建和复审修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:413
+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:417
+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."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:427
+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:436
+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. Let's use the ancient and venerable <command>sed</"
+"command> command to edit this file so that it prints a second line of "
+"output.  (I'm only using <command>sed</command> 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</command>; simply use "
+"your preferred text editor to do the same thing.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:449
+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:455
+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:462
+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:470
+msgid ""
+"It's a little bit 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:480
+msgid "Recording changes in a new changeset"
+msgstr "在新修改集中记录修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:482
+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:489
+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:495
+msgid "Setting up a username"
+msgstr "配置用户名称"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:497
+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:506
+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:511
+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:514
+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 section <xref linkend=\"sec.tour-basic.username\"/> below."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch01-tour-basic.xml:521
+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:524
+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:531
+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:535
+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:544
+msgid "Creating a Mercurial configuration file"
+msgstr "创建 Mercurial 的配置文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch01-tour-basic.xml:546
+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><para>
+#: ../en/ch01-tour-basic.xml:558
+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:571
+msgid "Choosing a user name"
+msgstr "选择用户名称"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch01-tour-basic.xml:573
+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 for "
+"interpreting 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:580
+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:590
+msgid "Writing a commit message"
+msgstr "写提交日志"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:592
+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:602
+msgid ""
+"The editor that the <command role=\"hg-cmd\">hg commit</command> command "
+"drops us into will contain an empty line, 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:609
+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:615
+msgid "Writing a good commit message"
+msgstr "写好提交日志"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:617
+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:631
+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:637
+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:644
+msgid "Aborting a commit"
+msgstr "终止提交"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:646
+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:651
+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:658
+msgid "Admiring our new handiwork"
+msgstr "欣赏我们的新手艺"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:660
+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:669
+msgid ""
+"We refer to the newest revision in the repository as the tip revision, or "
+"simply the tip."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch01-tour-basic.xml:676
+msgid "Sharing changes"
+msgstr "共享修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch01-tour-basic.xml:678
+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:686
+msgid "Pulling changes from another repository"
+msgstr "从其它版本库取得修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:687
+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:695
+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:708
+msgid ""
+"(Of course, someone could cause more changesets to appear in the repository "
+"that we ran <command role=\"hg-cmd\">hg incoming</command> in, before we get "
+"a chance to <command role=\"hg-cmd\">hg pull</command> the changes, so that "
+"we could end up pulling changes that we didn't expect.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:715
+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:722
+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:730
+msgid "Updating the working directory"
+msgstr "更新工作目录"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:732
+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 section <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:744
+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---to hunt down the origin of a bug, "
+"say---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:755
+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:760
+msgid ""
+"If you look back at the output of <command role=\"hg-cmd\">hg pull</command> "
+"in section <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:769
+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:775
+msgid ""
+"If you look back at figure <xref endterm=\"fig.tour-basic.history.caption\" "
+"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:785
+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:792
+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:800
+msgid "Pushing changes to another repository"
+msgstr "发布修改到其它版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:802
+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:810
+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:816
+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:822
+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.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:831
+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:838
+msgid "Sharing changes over a network"
+msgstr "通过网络共享修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch01-tour-basic.xml:840
+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:848
+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 figure <xref endterm=\"fig.tour-merge.sep-repos.caption\" "
+"linkend=\"fig.tour-merge.sep-repos\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><informalfigure><mediaobject>
+#: ../en/ch02-tour-merge.xml:47
+msgid ""
+"<imageobject><imagedata fileref=\"images/tour-merge-sep-repos.png\"/></"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
+#: ../en/ch02-tour-merge.xml:49
+msgid ""
+"Divergent recent histories of the <filename class=\"directory\">my-hello</"
+"filename> and <filename class=\"directory\">my-new-hello</filename> "
+"repositories"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:57
+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:63
+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:67
+msgid "Head changesets"
+msgstr "顶点改变集"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:69
+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><informalfigure><mediaobject>
+#: ../en/ch02-tour-merge.xml:77
+msgid ""
+"<imageobject><imagedata fileref=\"images/tour-merge-pull.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch02-tour-merge.xml:79
+msgid ""
+"Repository contents after pulling from <filename class=\"directory\">my-"
+"hello</filename> into <filename class=\"directory\">my-new-hello</filename>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:85
+msgid ""
+"In figure <xref endterm=\"fig.tour-merge.pull.caption\" 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 figure <xref endterm=\"fig.tour-merge.sep-repos."
+"caption\" 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:106
+msgid "Performing the merge"
+msgstr "执行合并"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:108
+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:114
+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><informalfigure><mediaobject>
+#: ../en/ch02-tour-merge.xml:125
+msgid ""
+"<imageobject><imagedata fileref=\"images/tour-merge-merge.png\"/></"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch02-tour-merge.xml:127
+msgid "Working directory and repository during merge, and following commit"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:132
+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:142
+msgid "Committing the results of the merge"
+msgstr "提交合并结果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:144
+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:151
+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:158
+msgid ""
+"In figure <xref endterm=\"fig.tour-merge.merge.caption\" 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:169
+msgid "Merging conflicting changes"
+msgstr "合并有冲突的改变"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:171
+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><informalfigure><mediaobject>
+#: ../en/ch02-tour-merge.xml:180
+msgid ""
+"<imageobject><imagedata fileref=\"images/tour-merge-conflict.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
+#: ../en/ch02-tour-merge.xml:183
+msgid "Conflicting changes to a document"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:188
+msgid ""
+"Figure <xref endterm=\"fig.tour-merge.conflict.caption\" 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:196
+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:207
+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:213
+msgid "Using a graphical merge tool"
+msgstr "使用图形合并工具"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:215
+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 "
+"figure <xref endterm=\"fig.tour-merge.kdiff3.caption\" 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:226
+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:231
+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:234
+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:238
+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:245
+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><informalfigure><mediaobject>
+#: ../en/ch02-tour-merge.xml:252
+msgid ""
+"<imageobject><imagedata width=\"100%\" fileref=\"images/kdiff3.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch02-tour-merge.xml:255
+msgid "Using <command>kdiff3</command> to merge versions of a file"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:261
+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:267
+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:276
+msgid "A worked example"
+msgstr "合并实例"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:278
+msgid ""
+"In this example, we will reproduce the file modification history of figure "
+"<xref endterm=\"fig.tour-merge.conflict.caption\" 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:286
+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:291
+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:299
+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:305
+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:315
+msgid "<emphasis role=\"bold\">XXX FIX THIS EXAMPLE.</emphasis>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch02-tour-merge.xml:320
+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:326
+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:333
+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:342
+msgid "Simplifying the pull-merge-commit sequence"
+msgstr "简化拉-合并-提交程序"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch02-tour-merge.xml:344
+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:350
+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:354
+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:359
+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:366
+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:379
+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:388
+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 figure <xref endterm=\"fig.concepts.filelog."
+"caption\" linkend=\"fig.concepts.filelog\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:55
+msgid "<imageobject><imagedata fileref=\"images/filelog.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:57
+msgid ""
+"Relationships between files in working directory and filelogs in repository"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch03-concepts.xml:65
+msgid "Managing tracked files"
+msgstr "管理跟踪的文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:67
+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:77
+msgid "Recording changeset information"
+msgstr "记录修改集信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:79
+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:87
+msgid "Relationships between revisions"
+msgstr "版本之间的关系"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:89
+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:96
+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 figure <xref endterm=\"fig.concepts."
+"metadata.caption\" linkend=\"fig.concepts.metadata\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:107
+msgid "<imageobject><imagedata fileref=\"images/metadata.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:109
+msgid "Metadata relationships"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:114
+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:127
+msgid "Safe, efficient storage"
+msgstr "安全,高效的存储"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:129
+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:134
+msgid "Efficient storage"
+msgstr "高效存储"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:136
+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:144
+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:153
+msgid "Safe operation"
+msgstr "安全操作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:155
+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:161
+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:171
+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:178
+msgid "Fast retrieval"
+msgstr "快速检索"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:180
+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><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:193
+msgid "<imageobject><imagedata fileref=\"images/snapshot.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:195
+msgid "Snapshot of a revlog, with incremental deltas"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:200
+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:209
+msgid ""
+"Figure <xref endterm=\"fig.concepts.snapshot.caption\" 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:216
+msgid "Aside: the influence of video compression"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:218
+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:227
+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:241
+msgid "Identification and strong integrity"
+msgstr "鉴别和强完整性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:243
+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:248
+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:255
+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:260
+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:272
+msgid "Revision history, branching, and merging"
+msgstr "修订历史,分支与合并"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:274
+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:282
+msgid ""
+"In figure <xref endterm=\"fig.concepts.revlog.caption\" 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:289
+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><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:300
+msgid "<imageobject><imagedata fileref=\"images/revlog.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:302
+msgid "Revision in revlog"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch03-concepts.xml:309
+msgid "The working directory"
+msgstr "工作目录"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:311
+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:314
+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:323
+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:329
+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:343
+msgid "What happens when you commit"
+msgstr "当你提交时发生的事情"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:345
+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><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:352
+msgid "<imageobject><imagedata fileref=\"images/wdir.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:354
+msgid "The working directory can have two parents"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:359
+msgid ""
+"Figure <xref endterm=\"fig.concepts.wdir.caption\" 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><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:368
+msgid ""
+"<imageobject><imagedata fileref=\"images/wdir-after-commit.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:371
+msgid "The working directory gains new parents after a commit"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:376
+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:384
+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 figure <xref endterm=\"fig.concepts.wdir-after-"
+"commit.caption\" 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:396
+msgid "Creating a new head"
+msgstr "创建新顶点"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:398
+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 "
+"figure <xref endterm=\"fig.concepts.wdir-pre-branch.caption\" linkend=\"fig."
+"concepts.wdir-pre-branch\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:412
+msgid ""
+"<imageobject><imagedata fileref=\"images/wdir-pre-branch.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:415
+msgid "The working directory, updated to an older changeset"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:420
+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 figure <xref endterm=\"fig.concepts.wdir-branch.caption\" "
+"linkend=\"fig.concepts.wdir-branch\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:434
+msgid ""
+"<imageobject><imagedata fileref=\"images/wdir-branch.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:437
+msgid "After a commit made while synced to an older changeset"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><note><para>
+#: ../en/ch03-concepts.xml:443
+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:455
+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:467
+msgid "Merging heads"
+msgstr "合并顶点"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:469
+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 "
+"figure <xref endterm=\"fig.concepts.wdir-merge.caption\" linkend=\"fig."
+"concepts.wdir-merge\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch03-concepts.xml:478
+msgid ""
+"<imageobject><imagedata fileref=\"images/wdir-merge.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch03-concepts.xml:481
+msgid "Merging two heads"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:486
+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:491
+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:494
+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:498
+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:502
+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:506
+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:511
+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:515
+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:522
+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:529
+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:540
+msgid "Other interesting design features"
+msgstr "其它有趣的设计特性"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch03-concepts.xml:542
+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:553
+msgid "Clever compression"
+msgstr "智能压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:555
+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:561
+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:569
+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:578
+msgid "Network recompression"
+msgstr "网络重新压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:580
+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:588
+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:598
+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:606
+msgid "Read/write ordering and atomicity"
+msgstr "读写顺序与原子性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:608
+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 figure <xref endterm=\"fig."
+"concepts.metadata.caption\" 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:616
+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:621
+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:629
+msgid "Concurrent access"
+msgstr "并发访问"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:631
+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:640
+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:653
+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:665
+msgid "Safe dirstate access"
+msgstr "安全的目录状态访问"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch03-concepts.xml:667
+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:680
+msgid "Avoiding seeks"
+msgstr "避免查找"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:682
+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:686
+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:692
+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:703
+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:715
+msgid "Other contents of the dirstate"
+msgstr "目录状态的其它内容"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch03-concepts.xml:717
+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:724
+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:731
+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 "有用的速记&emdash;一个步骤添加和删除文件"
+
+#. 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 section <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 chapter <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 section <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 section <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 section <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 "
+"section <xref linkend=\"sec.collab.ssh\"/>.  It's also usual to publish a "
+"read-only copy of the repository over HTTP using CGI, as in section <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:178
+msgid "Working with multiple branches"
+msgstr "使用多个分支工作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:180
+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:193
+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:202
+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:208
+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:211
+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:217
+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:222
+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:230
+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:236
+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:242
+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:249
+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:257
+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><informalfigure><mediaobject><caption><para>
+#: ../en/ch05-collab.xml:264 ../en/ch05-collab.xml:278
+msgid "Feature branches"
+msgstr "特性分支"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:266
+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><informalfigure><mediaobject>
+#: ../en/ch05-collab.xml:275
+msgid ""
+"<imageobject><imagedata fileref=\"images/feature-branches.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:283
+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:290
+msgid "The release train"
+msgstr "发布列车"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:292
+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:297
+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:306
+msgid "The Linux kernel model"
+msgstr "Linux 内核模型"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:308
+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:316
+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:323
+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:335
+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:346
+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:353
+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:364
+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:371
+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:381
+msgid "Pull-only versus shared-push collaboration"
+msgstr "只读与共享写协作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:383
+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:389
+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:397
+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:405
+msgid "Where collaboration meets branch management"
+msgstr "协作与分支管理"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:407
+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 chapter <xref linkend=\"chap.branch"
+"\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch05-collab.xml:419
+msgid "The technical side of sharing"
+msgstr "共享的技术因素"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:421
+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:426
+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:429
+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:434
+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:445
+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:449
+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:453
+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:458
+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:462
+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:472
+msgid "A few things to keep in mind"
+msgstr "要牢记的几件事"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:474
+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:480
+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:489
+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:495
+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:505
+msgid "Using the Secure Shell (ssh) protocol"
+msgstr "使用 ssh 协议"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:507
+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:512
+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:518
+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:523
+msgid "How to read and write ssh URLs"
+msgstr "如何读写 ssh 路径"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:525
+msgid "An ssh URL tends to look like this:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para>
+#: ../en/ch05-collab.xml:528
+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:531
+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:536
+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:540
+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:545
+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:549
+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:556
+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:565
+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:571
+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:578
+msgid "Finding an ssh client for your system"
+msgstr "为你的系统寻找 ssh 客户端"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:580
+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:588
+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:591
+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:595
+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:598
+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:608
+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:617
+msgid "Generating a key pair"
+msgstr "产生密钥对"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:619
+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:627
+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:633
+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:642
+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:651
+msgid "Using an authentication agent"
+msgstr "使用认证代理"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:653
+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:662
+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:669
+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:680
+msgid "Configuring the server side properly"
+msgstr "正确配置服务器端"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:682
+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:690
+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:701
+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:708
+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:713
+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:718
+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:723
+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:733
+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:739
+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:743
+msgid "You might have stored the passphrase for the wrong key."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:746
+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:749
+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:758
+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:765
+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:770
+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:784
+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:791
+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:798
+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:802
+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:806
+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:813
+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:820
+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:830
+msgid "Using compression with ssh"
+msgstr "通过 ssh 使用压缩"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:832
+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:837
+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:844
+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:852
+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:860
+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:871
+msgid "Serving over HTTP using CGI"
+msgstr "使用 CGI 通过 HTTP 提供服务"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch05-collab.xml:873
+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:877
+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:883
+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:893
+msgid "Web server configuration checklist"
+msgstr "Web 服务器配置检查表"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:895
+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:899
+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:903
+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:907
+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:913
+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:926
+msgid "Basic CGI configuration"
+msgstr "基本 CGI 配置"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:928
+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:936
+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:943 ../en/ch05-collab.xml:1112
+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:948
+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:962
+msgid "What could <emphasis>possibly</emphasis> go wrong?"
+msgstr "什么<emphasis>可能</emphasis>会出错?"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:965
+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:979
+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:990
+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:1000
+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:1007
+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: CDATA
+#: ../en/ch05-collab.xml:1012
+#, no-wrap
+msgid "&ch06-apache-config.lst;]]"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1014
+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:1021
+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:1027
+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:1041
+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:1051
+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:1057
+msgid "Configuring lighttpd"
+msgstr "配置 lighttpd"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1059
+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:1069
+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:1081
+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:1094
+msgid "Sharing multiple repositories with one CGI script"
+msgstr "使用一个 CGI 脚本共享多个版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1096
+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:1104
+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:1117
+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 section <xref linkend=\"sec.collab.wtf\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1126
+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:1136
+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:1144
+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:1153
+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:1167
+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:1177
+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:1183
+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:1193
+msgid "Explicitly specifying which repositories to publish"
+msgstr "明确指出要发布的版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch05-collab.xml:1196
+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:1205
+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:1212
+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:1218
+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:1227
+msgid "Downloading source archives"
+msgstr "下载源代码档案包"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1229
+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:1234
+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:1242
+msgid "Web configuration options"
+msgstr "Web 配置选项"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch05-collab.xml:1244
+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:1252
+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:1261
+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:1267
+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:1271
+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:1277
+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:1284
+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:1293
+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:1304
+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:1308
+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:1312
+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:1318
+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 chapter <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 "修改流程&emdash;宏观与微观"
+
+#. 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 section <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 section <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 "
+"section <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 figure <xref endterm=\"fig.undo.backout.caption\" 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><informalfigure><mediaobject>
+#: ../en/ch08-undo.xml:364
+msgid ""
+"<imageobject><imagedata fileref=\"images/undo-simple.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch08-undo.xml:367 ../en/ch08-undo.xml:486
+msgid ""
+"Backing out a change using the <command role=\"hg-cmd\">hg backout</command> "
+"command"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:376
+msgid "Backing out a non-tip change"
+msgstr "恢复非顶点的修改"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:378
+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:385
+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:391
+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:398
+msgid ""
+"As the graphical history in figure <xref endterm=\"fig.undo.backout-non-tip."
+"caption\" 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:410
+msgid ""
+"% TODO: to me it looks like mercurial doesn't commit the second merge "
+"automatically!"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch08-undo.xml:415
+msgid ""
+"<imageobject><imagedata fileref=\"images/undo-non-tip.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch08-undo.xml:418
+msgid ""
+"Automated backout of a non-tip change using the <command role=\"hg-cmd\">hg "
+"backout</command> command"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:424
+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:429
+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:432
+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:443
+msgid "Gaining more control of the backout process"
+msgstr "在恢复处理中获得更多控制"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:445
+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:458
+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:464
+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:472
+msgid ""
+"Again, it's easier to see what has happened by looking at a graph of the "
+"revision history, in figure <xref endterm=\"fig.undo.backout-manual.caption\" "
+"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><informalfigure><mediaobject>
+#: ../en/ch08-undo.xml:483
+msgid ""
+"<imageobject><imagedata fileref=\"images/undo-manual.png\"/> </imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:492
+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:499
+msgid "Now we have two isolated sets of changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:503
+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:513
+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:518
+msgid ""
+"Afterwards, the graphical history of our repository looks like figure <xref "
+"endterm=\"fig.undo.backout-manual-merge.caption\" linkend=\"fig.undo.backout-"
+"manual-merge\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch08-undo.xml:525
+msgid ""
+"<imageobject><imagedata fileref=\"images/undo-manual-merge.png\"/> </"
+"imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch08-undo.xml:528
+msgid "Manually merging a backout change"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:535
+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:538
+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:541
+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:545
+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:549
+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:554
+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:557
+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:564
+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:568
+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:574
+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:584
+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:591
+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:608
+msgid "Changes that should never have been"
+msgstr "不该发生的修改"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:610
+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:616
+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:625
+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:630
+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 section <xref linkend=\"sec.undo."
+"rollback\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:639
+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:647
+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:655
+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:661
+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:667
+msgid "Protect yourself from <quote>escaped</quote> changes"
+msgstr "使用<quote>校验</quote>修改来保护你自己"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:670
+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:677
+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:687
+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:694
+msgid "Finding the source of a bug"
+msgstr "查找问题的根源"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch08-undo.xml:696
+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:703
+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:712
+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:715
+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:720
+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:727
+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:734
+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:739
+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:746
+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:759
+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:769
+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:780
+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:788
+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:791
+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:795
+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:802
+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:808
+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:818
+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:825
+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:828
+msgid "You run your binary test."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:830
+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:835
+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:839
+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:842
+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:845
+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:850
+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:855
+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:863
+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:870
+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:880
+msgid "Notice that this command printed some output."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:882
+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:886
+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:891
+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:897
+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:901
+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:906
+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:911
+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:922
+msgid "Cleaning up after your search"
+msgstr "搜索后的清理"
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:924
+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:939
+msgid "Tips for finding bugs effectively"
+msgstr "有效查找问题的技巧"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch08-undo.xml:942
+msgid "Give consistent input"
+msgstr "给出一致的输入"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:944
+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:956
+msgid "Automate as much as possible"
+msgstr "尽量自动"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:958
+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:966
+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:975
+msgid "The key to automated testing is twofold:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:977
+msgid "always test for the same symptom, and"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch08-undo.xml:979
+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:982
+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:992
+msgid "Check your results"
+msgstr "检查你的结果"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:994
+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:1000
+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:1004
+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:1008
+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:1014
+msgid "Beware interference between bugs"
+msgstr "谨防问题之间的冲突"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1016
+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:1024
+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:1034
+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:1041
+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:1050
+msgid "Bracket your search lazily"
+msgstr "减少你的查找工作"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch08-undo.xml:1052
+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:1060
+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:1069
+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 section <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 section <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>&emdash;版本库的访问控制"
+
+#. 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:1280
+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>&emdash;与 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 section <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>&emdash;邮件通知"
+
+#. 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 section <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:1260
+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:1266
+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:1272
+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:1282
+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:1294
+msgid "Information for writers of hooks"
+msgstr "编写钩子的信息"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1297
+msgid "In-process hook execution"
+msgstr "进程内钩子的执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1299
+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:1303
+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:1312
+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:1319
+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:1324
+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:1329
+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:1336
+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:1343
+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:1351
+msgid "External hook execution"
+msgstr "外部钩子的执行"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1353
+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:1361
+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:1370
+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:1382
+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:1389
+msgid "Finding out where changesets come from"
+msgstr "检查修改集来自何处"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1391
+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:1400
+msgid "Sources of changesets"
+msgstr "修改集的来源"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1402
+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:1410
+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:1415
+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:1420
+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:1425
+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:1432
+msgid "Where changes are going&emdash;remote repository URLs"
+msgstr "修改集要到哪里&emdash;远程版本库的地址"
+
+#. type: Content of: <book><chapter><sect1><sect2><sect3><para>
+#: ../en/ch09-hook.xml:1435
+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:1443
+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:1450
+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:1455
+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:1462
+msgid "Empty&emdash;no information could be discovered about the remote client."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch09-hook.xml:1471
+msgid "Hook reference"
+msgstr "钩子参考"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1474
+msgid ""
+"<literal role=\"hook\">changegroup</literal>&emdash;after remote changesets "
+"added"
+msgstr "<literal role=\"hook\">changegroup</literal>&emdash;增加远程修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1477
+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:1487
+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:1493 ../en/ch09-hook.xml:1533 ../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:1784 ../en/ch09-hook.xml:1846
+#: ../en/ch09-hook.xml:1904 ../en/ch09-hook.xml:1938 ../en/ch09-hook.xml:1966
+msgid "Parameters to this hook:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1496 ../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:1505 ../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 "
+"section <xref linkend=\"sec.hook.sources\"/> for details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch09-hook.xml:1510 ../en/ch09-hook.xml:1588 ../en/ch09-hook.xml:1639
+#: ../en/ch09-hook.xml:1681 ../en/ch09-hook.xml:1763 ../en/ch09-hook.xml:1864
+msgid ""
+"<literal>url</literal>: A URL.  The location of the remote repository, if "
+"known.  See section <xref linkend=\"sec.hook.url\"/> for more information."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1517
+msgid ""
+"See also: <literal role=\"hook\">incoming</literal> (section <xref linkend="
+"\"sec.hook.incoming\"/>), <literal role=\"hook\">prechangegroup</literal> "
+"(section <xref linkend=\"sec.hook.prechangegroup\"/>), <literal role=\"hook"
+"\">pretxnchangegroup</literal> (section <xref linkend=\"sec.hook."
+"pretxnchangegroup\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1527
+msgid ""
+"<literal role=\"hook\">commit</literal>&emdash;after a new changeset is "
+"created"
+msgstr "<literal role=\"hook\">commit</literal>&emdash;创建新修改集之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1530
+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:1536 ../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:1540 ../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:1545 ../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:1551
+msgid ""
+"See also: <literal role=\"hook\">precommit</literal> (section <xref linkend="
+"\"sec.hook.precommit\"/>), <literal role=\"hook\">pretxncommit</literal> "
+"(section <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>&emdash;增加远程修改集之后"
+
+#. 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 (section <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:1595
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
+"\"sec.hook.changegroup\"/>) <literal role=\"hook\">prechangegroup</literal> "
+"(section <xref linkend=\"sec.hook.prechangegroup\"/>), <literal role=\"hook"
+"\">pretxnchangegroup</literal> (section <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>&emdash;传播修改集之后"
+
+#. 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 "
+"section <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:1646
+msgid ""
+"See also: <literal role=\"hook\">preoutgoing</literal> (section <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>&emdash;增加远程修改集之前"
+
+#. 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:1688
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
+"\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> "
+"(section <xref linkend=\"sec.hook.incoming\"/>), , <literal role=\"hook"
+"\">pretxnchangegroup</literal> (section <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>&emdash;提交修改集之前"
+
+#. 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> (section <xref linkend="
+"\"sec.hook.commit\"/>), <literal role=\"hook\">pretxncommit</literal> "
+"(section <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>&emdash;传播修改集之前"
+
+#. 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 section <xref linkend="
+"\"sec.hook.sources\"/>).  See the documentation for the <literal>source</"
+"literal> parameter to the <literal role=\"hook\">outgoing</literal> hook, in "
+"section <xref linkend=\"sec.hook.outgoing\"/>, for possible values of this "
+"parameter."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1770
+msgid ""
+"See also: <literal role=\"hook\">outgoing</literal> (section <xref linkend="
+"\"sec.hook.outgoing\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1776
+msgid ""
+"<literal role=\"hook\">pretag</literal>&emdash;before tagging a changeset"
+msgstr "<literal role=\"hook\">pretag</literal>&emdash;创建标签之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1779
+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:1787
+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:1794
+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:1798
+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:1803
+msgid ""
+"If the tag to be created is revision-controlled, the <literal role=\"hook"
+"\">precommit</literal> and <literal role=\"hook\">pretxncommit</literal> "
+"hooks (sections <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> (section <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>&emdash;完成增加远程修改集之"
+"前"
+
+#. 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:1871
+msgid ""
+"See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend="
+"\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> "
+"(section <xref linkend=\"sec.hook.incoming\"/>), <literal role=\"hook"
+"\">prechangegroup</literal> (section <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>&emdash;完成提交之前"
+
+#. 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> (section <xref linkend="
+"\"sec.hook.precommit\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1928
+msgid ""
+"<literal role=\"hook\">preupdate</literal>&emdash;before updating or merging "
+"working directory"
+msgstr ""
+"<literal role=\"hook\">preupdate</literal>&emdash;更新或合并工作目录之前"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1931
+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:1941
+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:1947
+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:1954
+msgid ""
+"See also: <literal role=\"hook\">update</literal> (section <xref linkend="
+"\"sec.hook.update\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1960
+msgid "<literal role=\"hook\">tag</literal>&emdash;after tagging a changeset"
+msgstr "<literal role=\"hook\">tag</literal>&emdash;创建标签之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:1963
+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:1969
+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:1977
+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:1981
+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:1986
+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:1991
+msgid ""
+"See also: <literal role=\"hook\">pretag</literal> (section <xref linkend="
+"\"sec.hook.pretag\"/>)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch09-hook.xml:1997
+msgid ""
+"<literal role=\"hook\">update</literal>&emdash;after updating or merging "
+"working directory"
+msgstr "<literal role=\"hook\">update</literal>&emdash;更新或合并工作目录之后"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch09-hook.xml:2000
+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:2008
+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:2013
+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:2019
+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:2025
+msgid ""
+"See also: <literal role=\"hook\">preupdate</literal> (section <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 section "
+"<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 section <xref linkend=\"sec.template.escape\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:132
+msgid "Common template keywords"
+msgstr "模版关键字"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:134
+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:138
+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:142
+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:148
+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 section <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:159
+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:162
+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:167
+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:171
+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:175
+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:179
+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:183
+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:187
+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:192
+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:197
+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 section <xref linkend=\"sec.template.filter\"/"
+">."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch10-template.xml:207
+msgid "Escape sequences"
+msgstr "转义序列"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:209
+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:216
+msgid ""
+"<literal>\\</literal>: Backslash, <quote><literal>\\</literal></quote>, ASCII "
+"134."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:220
+msgid "<literal>\\n</literal>: Newline, ASCII 12."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:223
+msgid "<literal>\\r</literal>: Carriage return, ASCII 15."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:226
+msgid "<literal>\\t</literal>: Tab, ASCII 11."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:229
+msgid "<literal>\\v</literal>: Vertical tab, ASCII 13."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:232
+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:236
+msgid ""
+"<literal>}</literal>: Close curly brace, <quote><literal>}</literal></quote>, "
+"ASCII 175."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:241
+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:249
+msgid "Filtering keywords to change their results"
+msgstr "通过过滤关键字来修改输出结果"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:251
+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:258
+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:265
+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:272
+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:279
+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:288
+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:296
+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:306
+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:315
+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:323
+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:331
+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:335
+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:340
+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:347
+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:354
+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:362
+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:371
+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:378
+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:383
+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:389
+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:393
+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:398
+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:405
+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:418
+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:427
+msgid "Combining filters"
+msgstr "组合过滤器"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:429
+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:438
+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:444
+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:455
+msgid "From templates to styles"
+msgstr "从模版到样式"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:457
+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:462
+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:468
+msgid "The simplest of style files"
+msgstr "最简单的样式文件"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:470
+msgid "Our simple style file contains just one line:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:474
+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:480
+msgid "Style file syntax"
+msgstr "样式文件语法"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:482
+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:485
+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:488
+msgid "Leading and trailing white space are ignored."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:491
+msgid "Empty lines are skipped."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:493
+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:498
+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:504
+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:509
+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:513
+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:522
+msgid "Style files by example"
+msgstr "样式文件例子"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch10-template.xml:524
+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:531
+msgid "Identifying mistakes in style files"
+msgstr "在样式文件中定位错误"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:533
+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:539
+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:546
+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:550
+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:554
+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:558
+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:562
+msgid "Finally, a description of what went wrong."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch10-template.xml:566
+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:574
+msgid "Uniquely identifying a repository"
+msgstr "版本库的唯一标识"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:576
+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:583
+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:586
+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:590
+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:595
+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:598
+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:601
+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:610
+msgid "Mimicking Subversion's output"
+msgstr "模仿 Subversion 的输出"
+
+#
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch10-template.xml:612
+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:617
+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:624
+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:627
+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:634
+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:643
+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:649
+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:656
+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 section <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><title>
+#: ../en/ch11-mq.xml:187
+msgid "Understanding patches"
+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 "
+"section <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.  Figure <xref endterm=\"fig.mq.stack."
+"caption\" linkend=\"fig.mq.stack\"/> illustrates the difference between "
+"applied and tracked patches."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject>
+#: ../en/ch11-mq.xml:409
+msgid "<imageobject><imagedata fileref=\"images/mq-stack.png\"/></imageobject>"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para>
+#: ../en/ch11-mq.xml:411
+msgid "Applied and unapplied patches in the MQ patch stack"
+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 section <xref linkend=\"sec.mq.perf\"/> below.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:452
+msgid "Safety checks, and overriding them"
+msgstr "安全的检查,然后覆盖它们"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:454
+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:466
+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:481
+msgid "Working on several patches at once"
+msgstr "同时处理多个补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:483
+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:490
+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:507
+msgid "More about patches"
+msgstr "关于补丁的更多信息"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:509
+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:515
+msgid "The strip count"
+msgstr "修剪计数"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:517
+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:524
+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:537
+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:545
+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:558
+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:566
+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:585
+msgid "Strategies for applying a patch"
+msgstr "应用补丁的策略"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:587
+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:594
+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:603
+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:612
+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:630
+msgid "Some quirks of patch representation"
+msgstr "补丁的一些特性"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:632
+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:635
+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:639
+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:643
+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:649
+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:655
+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:661
+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:668
+msgid "Beware the fuzz"
+msgstr "当心毛刺"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:670
+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:680
+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:693
+msgid "Handling rejection"
+msgstr "处理拒绝"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:695
+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:701
+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 section <xref linkend=\"sec.mq.merge\"/> for "
+"details."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:707
+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:712
+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:718
+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:727
+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:730
+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:733
+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:737
+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:741
+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:753
+msgid "Getting the best performance out of MQ"
+msgstr "MQ 的性能"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:755
+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:764
+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:775
+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:779
+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:790
+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:800
+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:807
+msgid "Updating your patches when the underlying code changes"
+msgstr "当基础代码改变时,更新补丁的方法"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:810
+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:819
+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:831
+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:838
+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:844
+msgid "The process is a little involved."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><orderedlist><listitem><para>
+#: ../en/ch11-mq.xml:846
+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:850
+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:864
+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:869
+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:874
+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:882
+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:892
+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:895
+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:907
+msgid "Identifying patches"
+msgstr "标识补丁"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:909
+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:916
+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:922
+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:928
+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:938
+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:941
+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:944
+msgid ""
+"(Don't know what <quote>patchbombing</quote> is? See section <xref linkend="
+"\"sec.hgext.patchbomb\"/>.)"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:947
+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:954
+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:959
+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:972
+msgid "Useful things to know about"
+msgstr "其它需要了解的东西"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:974
+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:979
+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 section <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:988
+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:999
+msgid "Managing patches in a repository"
+msgstr "在版本库管理补丁"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1001
+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:1007
+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:1016
+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:1026
+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:1032
+msgid "MQ support for patch repositories"
+msgstr "MQ 支持补丁版本库"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1034
+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:1044
+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:1053
+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:1060
+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:1065
+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:1071
+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:1080
+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:1085
+msgid "A few things to watch out for"
+msgstr "需要注意的事情"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1087
+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:1090
+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:1106
+msgid "Third party tools for working with patches"
+msgstr "操作补丁的第三方工具"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1108
+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:1112
+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:1126
+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 section <xref linkend=\"mq-collab.tips."
+"interdiff\"/> for another example."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1142
+msgid "Good ways to work with patches"
+msgstr "操作补丁的好习惯"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1144
+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:1150
+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:1162
+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:1172
+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 section <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:1183
+msgid "MQ cookbook"
+msgstr "MQ 手册"
+
+#. type: Content of: <book><chapter><sect1><sect2><title>
+#: ../en/ch11-mq.xml:1186
+msgid "Manage <quote>trivial</quote> patches"
+msgstr "管理<quote>琐碎的</quote>补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1188
+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:1193
+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:1198
+msgid "Continue by creating a patch stack and making your changes."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1203
+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:1209
+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:1217
+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:1224
+msgid "Combining entire patches"
+msgstr "组合全部的补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1226
+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:1234
+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:1245
+msgid "Merging part of one patch into another"
+msgstr "合并补丁的部分内容到其它补丁"
+
+#. type: Content of: <book><chapter><sect1><sect2><para>
+#: ../en/ch11-mq.xml:1247
+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:1251
+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:1264
+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:1272
+msgid "This command prints three different kinds of number:"
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para>
+#: ../en/ch11-mq.xml:1275
+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:1279
+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:1282
+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:1286
+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:1294
+msgid ""
+"Once you have this hunk, you can concatenate it onto the end of your "
+"destination patch and continue with the remainder of section <xref linkend="
+"\"sec.mq.combine\"/>."
+msgstr ""
+
+#. type: Content of: <book><chapter><sect1><title>
+#: ../en/ch11-mq.xml:1301
+msgid "Differences between quilt and MQ"
+msgstr "MQ 与 quilt 的区别"
+
+#. type: Content of: <book><chapter><sect1><para>
+#: ../en/ch11-mq.xml:1303
+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:1307
+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 section <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 section <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 ""
+"Section <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 chapter <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. Chapter <xref linkend="
+"\"chap.mq\"/> covers the basics; chapter <xref linkend=\"chap.mq-collab\"/> "
+"discusses advanced topics; and appendix <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 section <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 section <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 section <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 section <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	Fri Mar 27 00:41:15 2009 -0700
+++ /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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,120 @@
+<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 src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
+    <script type="text/javascript">_uacct = "UA-1805907-3"; urchinTracker();</script>
+  </xsl:template>
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/chunk-stylesheet.xsl	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,79 @@
+<?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="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</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">1</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	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,441 @@
+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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stylesheets/html-single.xsl	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,30 @@
+<?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="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</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	Mon Mar 30 16:23:33 2009 +0800
@@ -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/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="callout.graphics" select="1" />
+  <xsl:param name="callout.graphics.extension">.png</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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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	Mon Mar 30 16:23:33 2009 +0800
@@ -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>
--- a/tools/latex-to-docbook	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-#!/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/tools/po4a/lib/Locale/Po4a/Chooser.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,148 @@
+# Locale::Po4a::Pod -- Convert POD data to PO file, for translation.
+# $Id: Chooser.pm,v 1.41 2008-07-20 16:31:55 nekral-guest Exp $
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the terms of GPL (see COPYING).
+#
+# This module converts POD to PO file, so that it becomes possible to 
+# translate POD formatted documentation. See gettext documentation for
+# more info about PO files.
+
+############################################################################
+# Modules and declarations
+############################################################################
+
+
+package Locale::Po4a::Chooser;
+
+use 5.006;
+use strict;
+use warnings;
+use Locale::Po4a::Common;
+
+sub new {
+    my ($module)=shift;
+    my (%options)=@_;
+
+    die wrap_mod("po4a::chooser", gettext("Need to provide a module name"))
+      unless defined $module;
+
+    my $modname;
+    if ($module eq 'kernelhelp') {
+        $modname = 'KernelHelp';
+    } elsif ($module eq 'newsdebian') {
+        $modname = 'NewsDebian';
+    } elsif ($module eq 'latex') {
+        $modname = 'LaTeX';
+    } elsif ($module eq 'bibtex') {
+        $modname = 'BibTex';
+    } elsif ($module eq 'tex') {
+        $modname = 'TeX';
+    } else {
+        $modname = ucfirst($module);
+    }
+    if (! UNIVERSAL::can("Locale::Po4a::$modname", 'new')) {
+        eval qq{use Locale::Po4a::$modname};
+        if ($@) {
+            my $error=$@;
+            warn wrap_msg(gettext("Unknown format type: %s."), $module);
+	    warn wrap_mod("po4a::chooser",
+		gettext("Module loading error: %s"), $error)
+	      if defined $options{'verbose'} && $options{'verbose'} > 0;
+            list(1);
+        }
+    }
+    return "Locale::Po4a::$modname"->new(%options);
+}
+
+sub list {
+    warn wrap_msg(gettext("List of valid formats:")
+#	."\n  - ".gettext("bibtex: BibTex bibliography format.")
+	."\n  - ".gettext("dia: uncompressed Dia diagrams.")
+	."\n  - ".gettext("docbook: Docbook XML.")
+	."\n  - ".gettext("guide: Gentoo Linux's xml documentation format.")
+#	."\n  - ".gettext("html: HTML documents (EXPERIMENTAL).")
+	."\n  - ".gettext("ini: .INI format.")
+	."\n  - ".gettext("kernelhelp: Help messages of each kernel compilation option.")
+	."\n  - ".gettext("latex: LaTeX format.")
+	."\n  - ".gettext("man: Good old manual page format.")
+	."\n  - ".gettext("pod: Perl Online Documentation format.")
+	."\n  - ".gettext("sgml: either debiandoc or docbook DTD.")
+	."\n  - ".gettext("texinfo: The info page format.")
+	."\n  - ".gettext("tex: generic TeX documents (see also latex).")
+	."\n  - ".gettext("text: simple text document.")
+	."\n  - ".gettext("wml: WML documents.")
+	."\n  - ".gettext("xhtml: XHTML documents.")
+	."\n  - ".gettext("xml: generic XML documents (see also docbook).")
+    );
+    exit shift;
+}
+##############################################################################
+# Module return value and documentation
+##############################################################################
+
+1;
+__END__
+
+=head1 NAME
+
+Locale::Po4a::Chooser - Manage po4a modules
+
+=head1 DESCRIPTION
+
+Locale::Po4a::Chooser is a module to manage po4a modules. Before, all po4a
+binaries used to know all po4a modules (pod, man, sgml, etc). This made the
+add of a new module boring, to make sure the documentation is synchronized
+in all modules, and that each of them can access the new module.
+
+Now, you just have to call the Locale::Po4a::Chooser::new() function,
+passing the name of module as argument.
+
+You also have the Locale::Po4a::Chooser::list() function which lists the
+available format and exits on the value passed as argument.
+
+=head1 SEE ALSO
+
+=over 4
+
+=item About po4a:
+
+L<po4a(7)|po4a.7>, 
+L<Locale::Po4a::TransTractor(3pm)>,
+L<Locale::Po4a::Po(3pm)>
+
+=item About modules:
+
+L<Locale::Po4a::Dia(3pm)>,
+L<Locale::Po4a::Docbook(3pm)>,
+L<Locale::Po4a::Guide(3pm)>,
+L<Locale::Po4a::Halibut(3pm)>,
+L<Locale::Po4a::Ini(3pm)>,
+L<Locale::Po4a::KernelHelp(3pm)>,
+L<Locale::Po4a::LaTeX(3pm)>,
+L<Locale::Po4a::Man(3pm)>,
+L<Locale::Po4a::Pod(3pm)>,
+L<Locale::Po4a::Sgml(3pm)>,
+L<Locale::Po4a::TeX(3pm)>,
+L<Locale::Po4a::Texinfo(3pm)>,
+L<Locale::Po4a::Text(3pm)>,
+L<Locale::Po4a::Wml(3pm)>.
+L<Locale::Po4a::Xhtml(3pm)>,
+L<Locale::Po4a::Xml(3pm)>,
+L<Locale::Po4a::Wml(3pm)>.
+
+=back
+
+=head1 AUTHORS
+
+ Denis Barbier <barbier@linuxfr.org>
+ Martin Quinson (mquinson#debian.org)
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2002,2003,2004,2005 by SPI, inc.
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/lib/Locale/Po4a/Common.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,246 @@
+# Locale::Po4a::Common -- Common parts of the po4a scripts and utils
+# $Id: Common.pm,v 1.20 2009-02-13 23:16:44 nekral-guest Exp $
+#
+# Copyright 2005 by Jordi Vilalta <jvprat@gmail.com>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the terms of GPL (see COPYING).
+#
+# This module has common utilities for the various scripts of po4a
+
+=head1 NAME
+
+Locale::Po4a::Common - Common parts of the po4a scripts and utils
+
+=head1 DESCRIPTION
+
+Locale::Po4a::Common contains common parts of the po4a scripts and some useful
+functions used along the other modules.
+
+In order to use Locale::Po4a programatically, one may want to disable
+the use of Text::WrapI18N, by writing e.g.
+
+    use Locale::Po4a::Common qw(nowrapi18n);
+    use Locale::Po4a::Text;
+
+instead of:
+
+    use Locale::Po4a::Text;
+
+Ordering is important here: as most Locale::Po4a modules themselves
+load Locale::Po4a::Common, the first time this module is loaded
+determines whether Text::WrapI18N is used.
+
+=cut
+
+package Locale::Po4a::Common;
+
+require Exporter;
+use vars qw(@ISA @EXPORT);
+@ISA = qw(Exporter);
+@EXPORT = qw(wrap_msg wrap_mod wrap_ref_mod textdomain gettext dgettext);
+
+use 5.006;
+use strict;
+use warnings;
+
+sub import {
+    my $class=shift;
+
+    my $wrapi18n=1;
+    if (exists $_[0] && defined $_[0] && $_[0] eq 'nowrapi18n') {
+        shift;
+        $wrapi18n=0;
+    }
+    $class->export_to_level(1, $class, @_);
+
+    return if defined &wrapi18n;
+
+    if ($wrapi18n && -t STDERR && -t STDOUT && eval { require Text::WrapI18N }) {
+    
+        # Don't bother determining the wrap column if we cannot wrap.
+        my $col=$ENV{COLUMNS};
+        if (!defined $col) {
+            my @term=eval "use Term::ReadKey; Term::ReadKey::GetTerminalSize()";
+            $col=$term[0] if (!$@);
+            # If GetTerminalSize() failed we will fallback to a safe default.
+            # This can happen if Term::ReadKey is not available
+            # or this is a terminal-less build or such strange condition.
+        }
+        $col=76 if (!defined $col);
+        
+        eval ' use Text::WrapI18N qw($columns);
+               $columns = $col;
+             ';
+       
+        eval ' sub wrapi18n($$$) { Text::WrapI18N::wrap($_[0],$_[1],$_[2]) } '
+    } else {
+    
+        # If we cannot wrap, well, that's too bad. Survive anyway.
+        eval ' sub wrapi18n($$$) { $_[0].$_[2] } '
+    }
+}
+
+sub min($$) {
+    return $_[0] < $_[1] ? $_[0] : $_[1];
+}
+
+=head1 FUNCTIONS
+
+=head2 Showing output messages
+
+=over
+
+=item 
+
+show_version($)
+
+Shows the current version of the script, and a short copyright message. It
+takes the name of the script as an argument.
+
+=cut
+
+sub show_version {
+    my $name = shift;
+
+    print sprintf(gettext(
+	"%s version %s.\n".
+	"written by Martin Quinson and Denis Barbier.\n\n".
+	"Copyright (C) 2002, 2003, 2004 Software of Public Interest, Inc.\n".
+	"This is free software; see source code for copying\n".
+	"conditions. There is NO warranty; not even for\n".
+	"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+	), $name, $Locale::Po4a::TransTractor::VERSION)."\n";
+}
+
+=item 
+
+wrap_msg($@)
+
+This function displays a message the same way than sprintf() does, but wraps
+the result so that they look nice on the terminal.
+
+=cut
+
+sub wrap_msg($@) {
+    my $msg = shift;
+    my @args = @_;
+
+    return wrapi18n("", "", sprintf($msg, @args))."\n";
+}
+
+=item 
+
+wrap_mod($$@)
+
+This function works like wrap_msg(), but it takes a module name as the first
+argument, and leaves a space at the left of the message.
+
+=cut
+
+sub wrap_mod($$@) {
+    my ($mod, $msg) = (shift, shift);
+    my @args = @_;
+
+    $mod .= ": ";
+    my $spaces = " " x min(length($mod), 15);
+    return wrapi18n($mod, $spaces, sprintf($msg, @args))."\n";
+}
+
+=item 
+
+wrap_ref_mod($$$@)
+
+This function works like wrap_msg(), but it takes a file:line reference as the
+first argument, a module name as the second one, and leaves a space at the left
+of the message.
+
+=back
+
+=cut
+
+sub wrap_ref_mod($$$@) {
+    my ($ref, $mod, $msg) = (shift, shift, shift);
+    my @args = @_;
+
+    if (!$mod) {
+	# If we don't get a module name, show the message like wrap_mod does
+	return wrap_mod($ref, $msg, @args);
+    } else {
+	$ref .= ": ";
+	my $spaces = " " x min(length($ref), 15);
+	$msg = "$ref($mod)\n$msg";
+	return wrapi18n("", $spaces, sprintf($msg, @args))."\n";
+    }
+}
+
+=head2 Wrappers for other modules
+
+=over 
+
+=item 
+
+Locale::Gettext
+
+When the Locale::Gettext module cannot be loaded, this module provide dummy
+(empty) implementation of the following functions. In that case, po4a
+messages won't get translated but the program will continue to work.
+
+If Locale::gettext is present, this wrapper also calls
+setlocale(LC_MESSAGES, "") so callers don't depend on the POSIX module
+either.
+
+=over
+
+=item 
+
+bindtextdomain($$)
+
+=item 
+
+textdomain($)
+
+=item 
+
+gettext($)
+
+=item 
+
+dgettext($$)
+
+=back
+
+=back
+
+=cut
+
+BEGIN {
+    if (eval { require Locale::gettext }) {
+       import Locale::gettext;
+       require POSIX;
+       POSIX::setlocale(&POSIX::LC_MESSAGES, '');
+    } else {
+       eval '
+           sub bindtextdomain($$) { }
+           sub textdomain($) { }
+           sub gettext($) { shift }
+           sub dgettext($$) { return $_[1] }
+       '
+    }
+}
+
+1;
+__END__
+
+=head1 AUTHORS
+
+ Jordi Vilalta <jvprat@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2005 by SPI, inc.
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/lib/Locale/Po4a/Docbook.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,2040 @@
+#!/usr/bin/perl
+# aptitude: cmdsynopsis => missing removal of leading spaces
+
+# Po4a::Docbook.pm 
+# 
+# extract and translate translatable strings from Docbook XML documents.
+# 
+# This code extracts plain text from tags and attributes on Docbook XML
+# documents.
+#
+# Copyright (c) 2004 by Jordi Vilalta  <jvprat@gmail.com>
+# Copyright (c) 2007-2009 by Nicolas François <nicolas.francois@centraliens.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+########################################################################
+
+=head1 NAME
+
+Locale::Po4a::Docbook - Convert Docbook XML documents from/to PO files
+
+=head1 DESCRIPTION
+
+The po4a (po for anything) project goal is to ease translations (and more
+interestingly, the maintenance of translations) using gettext tools on
+areas where they were not expected like documentation.
+
+Locale::Po4a::Docbook is a module to help the translation of DocBook XML 
+documents into other [human] languages.
+
+Please note that this module is still under heavy development, and not 
+distributed in official po4a release since we don't feel it to be mature 
+enough. If you insist on trying, check the CVS out.
+
+=head1 STATUS OF THIS MODULE
+
+This module is fully functional, as it relies in the L<Locale::Po4a::Xml>
+module. This only defines the translatable tags and attributes.
+
+The only known issue is that it doesn't handle entities yet, and this includes
+the file inclusion entities, but you can translate most of those files alone
+(except the typical entities files), and it's usually better to maintain them
+separated.
+
+=head1 SEE ALSO
+
+L<po4a(7)|po4a.7>, L<Locale::Po4a::TransTractor(3pm)>, L<Locale::Po4a::Xml(3pm)>.
+
+=head1 AUTHORS
+
+ Jordi Vilalta <jvprat@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+ Copyright (c) 2004 by Jordi Vilalta  <jvprat@gmail.com>
+ Copyright (c) 2007-2009 by Nicolas François <nicolas.francois@centraliens.net>
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
+
+package Locale::Po4a::Docbook;
+
+use 5.006;
+use strict;
+use warnings;
+
+use Locale::Po4a::Xml;
+
+use vars qw(@ISA);
+@ISA = qw(Locale::Po4a::Xml);
+
+sub initialize {
+	my $self = shift;
+	my %options = @_;
+
+	$self->SUPER::initialize(%options);
+	$self->{options}{'wrap'}=1;
+	$self->{options}{'doctype'}=$self->{options}{'doctype'} || 'docbook xml';
+
+# AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+	# abbrev; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <abbrev>";
+	$self->{options}{'_default_inline'} .= " <abbrev>";
+
+	# abstract; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <abstract>";
+	$self->{options}{'_default_break'} .= " <abstract>";
+
+	# accel; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <accel>";
+	$self->{options}{'_default_inline'} .= " <accel>";
+
+	# ackno; does not contain text; Formatted as a displayed block
+	# Replaced by acknowledgements in Docbook v5.0
+	$self->{options}{'_default_untranslated'} .= " <ackno>";
+	$self->{options}{'_default_break'} .= " <ackno>";
+	# acknowledgements; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <acknowledgements>";
+	$self->{options}{'_default_break'} .= " <acknowledgements>";
+
+	# acronym; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <acronym>";
+	$self->{options}{'_default_inline'} .= " <acronym>";
+
+	# action; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <action>";
+	$self->{options}{'_default_inline'} .= " <action>";
+
+	# address; contains text; Formatted as a displayed block; verbatim
+	$self->{options}{'_default_translated'} .= " W<address>";
+	$self->{options}{'_default_placeholder'} .= " <address>";
+
+	# affiliation; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <affiliation>";
+	$self->{options}{'_default_inline'} .= " <affiliation>";
+
+	# alt; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <alt>";
+	$self->{options}{'_default_inline'} .= " <alt>";
+
+	# anchor; does not contain text; Produces no output
+	$self->{options}{'_default_untranslated'} .= " <anchor>";
+	$self->{options}{'_default_inline'} .= " <anchor>";
+
+	# annotation; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <annotation>";
+	$self->{options}{'_default_placeholder'} .= " <annotation>";
+
+	# answer; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <answer>";
+	$self->{options}{'_default_break'} .= " <answer>";
+
+	# appendix; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <appendix>";
+	$self->{options}{'_default_break'} .= " <appendix>";
+
+	# appendixinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <appendixinfo>";
+	$self->{options}{'_default_placeholder'} .= " <appendixinfo>";
+
+	# application; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <application>";
+	$self->{options}{'_default_inline'} .= " <application>";
+
+	# arc; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <arc>";
+	$self->{options}{'_default_inline'} .= " <arc>";
+
+	# area; does not contain text;
+	# NOTE: the area is not translatable as is, but the coords
+	# attribute might be.
+	$self->{options}{'_default_untranslated'} .= " <area>";
+	$self->{options}{'_default_inline'} .= " <area>";
+
+	# areaset; does not contain text;
+	# NOTE: the areaset is not translatable as is. depending on the
+	# language there might be more or less area tags inside.
+	$self->{options}{'_default_untranslated'} .= " <areaset>";
+	$self->{options}{'_default_inline'} .= " <areaset>";
+
+	# areaspec; does not contain text;
+	# NOTE: see area and areaset
+	$self->{options}{'_default_translated'} .= " <areaspec>";
+	$self->{options}{'_default_break'} .= " <areaspec>";
+
+	# arg; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <arg>";
+	$self->{options}{'_default_inline'} .= " <arg>";
+
+	# artheader; does not contain text; renamed to articleinfo in v4.0
+	$self->{options}{'_default_untranslated'} .= " <artheader>";
+	$self->{options}{'_default_placeholder'} .= " <artheader>";
+
+	# article; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <article>";
+	$self->{options}{'_default_break'} .= " <article>";
+
+	# articleinfo; does not contain text; v4 only
+	$self->{options}{'_default_untranslated'} .= " <articleinfo>";
+	$self->{options}{'_default_placeholder'} .= " <articleinfo>";
+
+	# artpagenums; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <artpagenums>";
+	$self->{options}{'_default_inline'} .= " <artpagenums>";
+
+	# attribution; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <attribution>";
+	$self->{options}{'_default_inline'} .= " <attribution>";
+
+	# audiodata; does not contain text;
+	# NOTE: the attributes might be translated
+	$self->{options}{'_default_translated'} .= " <audiodata>";
+	$self->{options}{'_default_placeholder'} .= " <audiodata>";
+	$self->{options}{'_default_attributes'}.=' <audiodata>fileref';
+
+	# audioobject; does not contain text;
+	# NOTE: might be contaioned in a inlinemediaobject
+	$self->{options}{'_default_translated'} .= " <audioobject>";
+	$self->{options}{'_default_placeholder'} .= " <audioobject>";
+
+	# author; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <author>";
+	$self->{options}{'_default_inline'} .= " <author>";
+
+	# authorblurb; does not contain text; Formatted as a displayed block.
+	# v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <authorblurb>";
+	$self->{options}{'_default_placeholder'} .= " <authorblurb>";
+
+	# authorgroup; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	# NOTE: given the possible parents, it is probably very rarely
+	#       inlined
+	$self->{options}{'_default_untranslated'} .= " <authorgroup>";
+	$self->{options}{'_default_break'} .= " <authorgroup>";
+
+	# authorinitials; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <authorinitials>";
+	$self->{options}{'_default_inline'} .= " <authorinitials>";
+
+# BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+
+	# beginpage; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <beginpage>";
+	$self->{options}{'_default_break'} .= " <beginpage>";
+
+	# bibliocoverage; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <bibliocoverage>";
+	$self->{options}{'_default_inline'} .= " <bibliocoverage>";
+
+	# bibliodiv; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <bibliodiv>";
+	$self->{options}{'_default_break'} .= " <bibliodiv>";
+
+	# biblioentry; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <biblioentry>";
+	$self->{options}{'_default_break'} .= " <biblioentry>";
+
+	# bibliography; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <bibliography>";
+	$self->{options}{'_default_break'} .= " <bibliography>";
+
+	# bibliographyinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <bibliographyinfo>";
+	$self->{options}{'_default_placeholder'} .= " <bibliographyinfo>";
+
+	# biblioid; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <biblioid>";
+	$self->{options}{'_default_inline'} .= " <biblioid>";
+
+	# bibliolist; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <bibliolist>";
+	$self->{options}{'_default_break'} .= " <bibliolist>";
+
+	# bibliomisc; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <bibliomisc>";
+	$self->{options}{'_default_inline'} .= " <bibliomisc>";
+
+	# bibliomixed; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <bibliomixed>";
+	$self->{options}{'_default_placeholder'} .= " <bibliomixed>";
+
+	# bibliomset; contains text; Formatted as a displayed block
+	# NOTE: content might need to be inlined, e.g. <bibliomset><title>
+	$self->{options}{'_default_translated'} .= " <bibliomset>";
+	$self->{options}{'_default_placeholder'} .= " <bibliomset>";
+
+	# biblioref; does not contain text; Formatted inline
+	$self->{options}{'_default_untranslated'} .= " <biblioref>";
+	$self->{options}{'_default_inline'} .= " <biblioref>";
+
+	# bibliorelation; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <bibliorelation>";
+	$self->{options}{'_default_inline'} .= " <bibliorelation>";
+
+	# biblioset; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <biblioset>";
+	$self->{options}{'_default_break'} .= " <biblioset>";
+
+	# bibliosource; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <bibliosource>";
+	$self->{options}{'_default_inline'} .= " <bibliosource>";
+
+	# blockinfo; does not contain text; v4.2, not in v5
+	$self->{options}{'_default_untranslated'} .= " <blockinfo>";
+	$self->{options}{'_default_placeholder'} .= " <blockinfo>";
+
+	# blockquote; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <blockquote>";
+	$self->{options}{'_default_break'} .= " <blockquote>";
+
+	# book; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <book>";
+	$self->{options}{'_default_break'} .= " <book>";
+
+	# bookbiblio; does not contain text; Formatted as a displayed block
+	# Removed in v4.0
+	$self->{options}{'_default_untranslated'} .= " <bookbiblio>";
+	$self->{options}{'_default_break'} .= " <bookbiblio>";
+
+	# bookinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <bookinfo>";
+	$self->{options}{'_default_placeholder'} .= " <bookinfo>";
+
+	# bridgehead; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <bridgehead>";
+	$self->{options}{'_default_break'} .= " <bridgehead>";
+
+# CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+
+	# callout; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <callout>";
+	$self->{options}{'_default_break'} .= " <callout>";
+
+	# calloutlist; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <calloutlist>";
+	$self->{options}{'_default_break'} .= " <calloutlist>";
+
+	# caption; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <caption>";
+	$self->{options}{'_default_break'} .= " <caption>";
+
+	# caption (db.html.caption); contains text; Formatted as a displayed block
+	# TODO: Check if this works
+	$self->{options}{'_default_translated'} .= " <table><caption>";
+	$self->{options}{'_default_break'} .= " <table><caption>";
+
+	# caution; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <caution>";
+	$self->{options}{'_default_break'} .= " <caution>";
+
+	# chapter; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <chapter>";
+	$self->{options}{'_default_break'} .= " <chapter>";
+
+	# chapterinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <chapterinfo>";
+	$self->{options}{'_default_placeholder'} .= " <chapterinfo>";
+
+	# citation; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <citation>";
+	$self->{options}{'_default_inline'} .= " <citation>";
+
+	# citebiblioid; contains text; Formatted inline
+	# NOTE: maybe untranslated?
+	$self->{options}{'_default_translated'} .= " <citebiblioid>";
+	$self->{options}{'_default_inline'} .= " <citebiblioid>";
+
+	# citerefentry; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <citerefentry>";
+	$self->{options}{'_default_inline'} .= " <citerefentry>";
+
+	# citetitle; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <citetitle>";
+	$self->{options}{'_default_inline'} .= " <citetitle>";
+
+	# city; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <city>";
+	$self->{options}{'_default_inline'} .= " <city>";
+
+	# classname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <classname>";
+	$self->{options}{'_default_inline'} .= " <classname>";
+
+	# classsynopsis; does not contain text; may be in a para
+	# NOTE: It may contain a classsynopsisinfo, which should be
+	#       verbatim
+	# XXX: since it is in untranslated class, does the W flag takes
+	#      effect?
+	$self->{options}{'_default_untranslated'} .= " W<classsynopsis>";
+	$self->{options}{'_default_placeholder'} .= " <classsynopsis>";
+
+	# classsynopsisinfo; contains text;
+	# NOTE: see above
+	$self->{options}{'_default_translated'} .= " W<classsynopsisinfo>";
+	$self->{options}{'_default_inline'} .= " <classsynopsisinfo>";
+
+	# cmdsynopsis; does not contain text; may be in a para
+	# NOTE: It may be clearer as a verbatim block
+	# XXX: since it is in untranslated class, does the W flag takes
+	#      effect? => not completely. Rewrap afterward?
+	$self->{options}{'_default_untranslated'} .= " W<cmdsynopsis>";
+	$self->{options}{'_default_placeholder'} .= " <cmdsynopsis>";
+
+	# co; does not contain text; Formatted inline
+	# XXX: tranlsated or not? (label attribute)
+	$self->{options}{'_default_translated'} .= " <co>";
+	$self->{options}{'_default_inline'} .= " <co>";
+
+	# code; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <code>";
+	$self->{options}{'_default_inline'} .= " <code>";
+
+	# col; does not contain text;
+	# NOTE: could be translated to change the layout in a translation
+	#       To be done on colgroup in that case.
+	$self->{options}{'_default_untranslated'} .= " <col>";
+	$self->{options}{'_default_break'} .= " <col>";
+
+	# colgroup; does not contain text;
+	# NOTE: could be translated to change the layout in a translation
+	$self->{options}{'_default_untranslated'} .= " <colgroup>";
+	$self->{options}{'_default_break'} .= " <colgroup>";
+
+	# collab; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	# NOTE: could be in the break class
+	$self->{options}{'_default_untranslated'} .= " <collab>";
+	$self->{options}{'_default_inline'} .= " <collab>";
+
+	# collabname; contains text; Formatted inline or as a
+	# displayed block depending on context; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <collabname>";
+	$self->{options}{'_default_inline'} .= " <collabname>";
+
+	# colophon; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <colophon>";
+	$self->{options}{'_default_break'} .= " <colophon>";
+
+	# colspec; does not contain text;
+	# NOTE: could be translated to change the layout in a translation
+	$self->{options}{'_default_untranslated'} .= " <colspec>";
+	$self->{options}{'_default_break'} .= " <colspec>";
+
+	# command; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <command>";
+	$self->{options}{'_default_inline'} .= " <command>";
+
+	# comment; contains text; Formatted inline or as a displayed block
+	# Renamed to remark in v4.0
+	$self->{options}{'_default_translated'} .= " <comment>";
+	$self->{options}{'_default_inline'} .= " <comment>";
+
+	# computeroutput; contains text; Formatted inline
+	# NOTE: "is not a verbatim environment, but an inline."
+	$self->{options}{'_default_translated'} .= " <computeroutput>";
+	$self->{options}{'_default_inline'} .= " <computeroutput>";
+
+	# confdates; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <confdates>";
+	$self->{options}{'_default_inline'} .= " <confdates>";
+
+	# confgroup; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	# NOTE: could be in the break class
+	$self->{options}{'_default_untranslated'} .= " <confgroup>";
+	$self->{options}{'_default_inline'} .= " <confgroup>";
+
+	# confnum; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <confnum>";
+	$self->{options}{'_default_inline'} .= " <confnum>";
+
+	# confsponsor; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <confsponsor>";
+	$self->{options}{'_default_inline'} .= " <confsponsor>";
+
+	# conftitle; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <conftitle>";
+	$self->{options}{'_default_inline'} .= " <conftitle>";
+
+	# constant; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <constant>";
+	$self->{options}{'_default_inline'} .= " <constant>";
+
+	# constraint; does not contain text;
+	# NOTE: it might be better to have the production as verbatim
+	#       Keeping the constrainst inline to have it close to the
+	#       lhs or rhs.
+	#       The attribute is translatable
+	$self->{options}{'_default_untranslated'} .= " <constraint>";
+	$self->{options}{'_default_break'} .= " <constraint>";
+
+	# constraintdef; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <constraintdef>";
+	$self->{options}{'_default_break'} .= " <constraintdef>";
+
+	# constructorsynopsis; does not contain text; may be in a para
+	# NOTE: It may be clearer as a verbatim block
+	# XXX: since it is in untranslated class, does the W flag takes
+	#      effect?
+	$self->{options}{'_default_untranslated'} .= " W<constructorsynopsis>";
+	$self->{options}{'_default_placeholder'} .= " <constructorsynopsis>";
+
+	# contractnum; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <contractnum>";
+	$self->{options}{'_default_inline'} .= " <contractnum>";
+
+	# contractsponsor; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <contractsponsor>";
+	$self->{options}{'_default_inline'} .= " <contractsponsor>";
+
+	# contrib; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_translated'} .= " <contrib>";
+	$self->{options}{'_default_inline'} .= " <contrib>";
+
+	# copyright; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <copyright>";
+	$self->{options}{'_default_inline'} .= " <copyright>";
+
+	# coref; does not contain text; Formatted inline
+	# XXX: tranlsated or not? (label attribute)
+	$self->{options}{'_default_translated'} .= " <coref>";
+	$self->{options}{'_default_inline'} .= " <coref>";
+
+	# corpauthor; contains text; Formatted inline or as a
+	# displayed block depending on context; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <corpauthor>";
+	$self->{options}{'_default_inline'} .= " <corpauthor>";
+
+	# corpcredit; contains text; Formatted inline or as a
+	# displayed block depending on context; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <corpcredit>";
+	$self->{options}{'_default_inline'} .= " <corpcredit>";
+
+	# corpname; contains text; Formatted inline or as a
+	# displayed block depending on context; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <corpname>";
+	$self->{options}{'_default_inline'} .= " <corpname>";
+
+	# country; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <country>";
+	$self->{options}{'_default_inline'} .= " <country>";
+
+	# cover; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <cover>";
+	$self->{options}{'_default_break'} .= " <cover>";
+
+# DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+
+	# database; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <database>";
+	$self->{options}{'_default_inline'} .= " <database>";
+
+	# date; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <date>";
+	$self->{options}{'_default_inline'} .= " <date>";
+
+	# dedication; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <dedication>";
+	$self->{options}{'_default_break'} .= " <dedication>";
+
+	# destructorsynopsis; does not contain text; may be in a para
+	# NOTE: It may be clearer as a verbatim block
+	# XXX: since it is in untranslated class, does the W flag takes
+	#      effect?
+	$self->{options}{'_default_untranslated'} .= " W<destructorsynopsis>";
+	$self->{options}{'_default_placeholder'} .= " <destructorsynopsis>";
+
+	# docinfo; does not contain text; removed in v4.0
+	$self->{options}{'_default_untranslated'} .= " <docinfo>";
+	$self->{options}{'_default_placeholder'} .= " <docinfo>";
+
+# EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+
+	# edition; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <edition>";
+	$self->{options}{'_default_inline'} .= " <edition>";
+
+	# editor; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <editor>";
+	$self->{options}{'_default_inline'} .= " <editor>";
+
+	# email; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <email>";
+	$self->{options}{'_default_inline'} .= " <email>";
+
+	# emphasis; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <emphasis>";
+	$self->{options}{'_default_inline'} .= " <emphasis>";
+
+	# entry; contains text;
+	$self->{options}{'_default_translated'} .= " <entry>";
+	$self->{options}{'_default_break'} .= " <entry>";
+
+	# entrytbl; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <entrytbl>";
+	$self->{options}{'_default_break'} .= " <entrytbl>";
+
+	# envar; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <envar>";
+	$self->{options}{'_default_inline'} .= " <envar>";
+
+	# epigraph; contains text; Formatted as a displayed block.
+	# NOTE: maybe contained in a para
+	$self->{options}{'_default_translated'} .= " <epigraph>";
+	$self->{options}{'_default_placeholder'} .= " <epigraph>";
+
+	# equation; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <equation>";
+	$self->{options}{'_default_break'} .= " <equation>";
+
+	# errorcode; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <errorcode>";
+	$self->{options}{'_default_inline'} .= " <errorcode>";
+
+	# errorname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <errorname>";
+	$self->{options}{'_default_inline'} .= " <errorname>";
+
+	# errortext; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <errortext>";
+	$self->{options}{'_default_inline'} .= " <errortext>";
+
+	# errortype; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <errortype>";
+	$self->{options}{'_default_inline'} .= " <errortype>";
+
+	# example; does not contain text; Formatted as a displayed block.
+	# NOTE: maybe contained in a para
+	$self->{options}{'_default_untranslated'} .= " <example>";
+	$self->{options}{'_default_placeholder'} .= " <example>";
+
+	# exceptionname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <exceptionname>";
+	$self->{options}{'_default_inline'} .= " <exceptionname>";
+
+	# extendedlink; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <extendedlink>";
+	$self->{options}{'_default_inline'} .= " <extendedlink>";
+
+# FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+	# fax; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <fax>";
+	$self->{options}{'_default_inline'} .= " <fax>";
+
+	# fieldsynopsis; does not contain text; may be in a para
+	$self->{options}{'_default_untranslated'} .= " <fieldsynopsis>";
+	$self->{options}{'_default_inline'} .= " <fieldsynopsis>";
+
+	# figure; does not contain text; Formatted as a displayed block.
+	# NOTE: maybe contained in a para
+	$self->{options}{'_default_untranslated'} .= " <figure>";
+	$self->{options}{'_default_placeholder'} .= " <figure>";
+
+	# filename; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <filename>";
+	$self->{options}{'_default_inline'} .= " <filename>";
+
+	# firstname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <firstname>";
+	$self->{options}{'_default_inline'} .= " <firstname>";
+
+	# firstterm; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <firstterm>";
+	$self->{options}{'_default_inline'} .= " <firstterm>";
+
+	# footnote; contains text;
+	$self->{options}{'_default_translated'} .= " <footnote>";
+	$self->{options}{'_default_placeholder'} .= " <footnote>";
+
+	# footnoteref; contains text;
+	$self->{options}{'_default_translated'} .= " <footnoteref>";
+	$self->{options}{'_default_inline'} .= " <footnoteref>";
+
+	# foreignphrase; contains text;
+	$self->{options}{'_default_translated'} .= " <foreignphrase>";
+	$self->{options}{'_default_inline'} .= " <foreignphrase>";
+
+	# formalpara; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <formalpara>";
+	$self->{options}{'_default_break'} .= " <formalpara>";
+
+	# funcdef; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <funcdef>";
+	$self->{options}{'_default_inline'} .= " <funcdef>";
+
+	# funcparams; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <funcparams>";
+	$self->{options}{'_default_inline'} .= " <funcparams>";
+
+	# funcprototype; does not contain text;
+	# NOTE: maybe contained in a funcsynopsis, contained in a para
+	$self->{options}{'_default_untranslated'} .= " <funcprototype>";
+	$self->{options}{'_default_placeholder'} .= " <funcprototype>";
+
+	# funcsynopsis; does not contain text;
+	# NOTE: maybe contained in a para
+	$self->{options}{'_default_untranslated'} .= " <funcsynopsis>";
+	$self->{options}{'_default_placeholder'} .= " <funcsynopsis>";
+
+	# funcsynopsisinfo; contains text; verbatim
+	# NOTE: maybe contained in a funcsynopsis, contained in a para
+	$self->{options}{'_default_translated'} .= " W<funcsynopsisinfo>";
+	$self->{options}{'_default_placeholder'} .= " <funcsynopsisinfo>";
+
+	# function; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <function>";
+	$self->{options}{'_default_inline'} .= " <function>";
+
+# GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
+
+	# glossary; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <glossary>";
+	$self->{options}{'_default_break'} .= " <glossary>";
+
+	# glossaryinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <glossaryinfo>";
+	$self->{options}{'_default_placeholder'} .= " <glossaryinfo>";
+
+	# glossdef; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <glossdef>";
+	$self->{options}{'_default_break'} .= " <glossdef>";
+
+	# glossdiv; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <glossdiv>";
+	$self->{options}{'_default_break'} .= " <glossdiv>";
+
+	# glossentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <glossentry>";
+	$self->{options}{'_default_break'} .= " <glossentry>";
+
+	# glosslist; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <glosslist>";
+	$self->{options}{'_default_break'} .= " <glosslist>";
+
+	# glosssee; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <glosssee>";
+	$self->{options}{'_default_break'} .= " <glosssee>";
+
+	# glossseealso; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <glossseealso>";
+	$self->{options}{'_default_break'} .= " <glossseealso>";
+
+	# glossterm; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <glossterm>";
+	$self->{options}{'_default_inline'} .= " <glossterm>";
+
+	# graphic; does not contain text; Formatted as a displayed block
+	# v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <graphic>";
+	$self->{options}{'_default_inline'} .= " <graphic>";
+	$self->{options}{'_default_attributes'}.=' <graphic>fileref';
+
+	# graphicco; does not contain text; Formatted as a displayed block.
+	# v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <graphicco>";
+	$self->{options}{'_default_placeholder'} .= " <graphicco>";
+
+	# group; does not contain text; Formatted inline
+	$self->{options}{'_default_untranslated'} .= " W<group>";
+	$self->{options}{'_default_inline'} .= " <group>";
+
+	# guibutton; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guibutton>";
+	$self->{options}{'_default_inline'} .= " <guibutton>";
+
+	# guiicon; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guiicon>";
+	$self->{options}{'_default_inline'} .= " <guiicon>";
+
+	# guilabel; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guilabel>";
+	$self->{options}{'_default_inline'} .= " <guilabel>";
+
+	# guimenu; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guimenu>";
+	$self->{options}{'_default_inline'} .= " <guimenu>";
+
+	# guimenuitem; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guimenuitem>";
+	$self->{options}{'_default_inline'} .= " <guimenuitem>";
+
+	# guisubmenu; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <guisubmenu>";
+	$self->{options}{'_default_inline'} .= " <guisubmenu>";
+
+# HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
+
+	# hardware; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <hardware>";
+	$self->{options}{'_default_inline'} .= " <hardware>";
+
+	# highlights; does not contain text; Formatted inline
+	# v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <highlights>";
+	$self->{options}{'_default_break'} .= " <highlights>";
+
+	# holder; contains text;
+	# NOTE: may depend on the copyright container
+	$self->{options}{'_default_translated'} .= " <holder>";
+	$self->{options}{'_default_inline'} .= " <holder>";
+
+	# honorific; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <honorific>";
+	$self->{options}{'_default_inline'} .= " <honorific>";
+
+	# html:button; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:button>";
+	$self->{options}{'_default_inline'} .= " <html:button>";
+
+	# html:fieldset; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:fieldset>";
+	$self->{options}{'_default_inline'} .= " <html:fieldset>";
+
+	# html:form; does not contain text;
+	$self->{options}{'_default_translated'} .= " <html:form>";
+	$self->{options}{'_default_inline'} .= " <html:form>";
+
+	# html:input; does not contain text; Formatted inline
+	# NOTE: attributes are translatable
+	$self->{options}{'_default_translated'} .= " <html:input>";
+	$self->{options}{'_default_inline'} .= " <html:input>";
+
+	# html:label; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:label>";
+	$self->{options}{'_default_inline'} .= " <html:label>";
+
+	# html:legend; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:legend>";
+	$self->{options}{'_default_inline'} .= " <html:legend>";
+
+	# html:option; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:option>";
+	$self->{options}{'_default_inline'} .= " <html:option>";
+
+	# html:select; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <html:select>";
+	$self->{options}{'_default_inline'} .= " <html:select>";
+
+	# html:textarea; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <html:textarea>";
+	$self->{options}{'_default_placeholder'} .= " <html:textarea>";
+
+	# imagedata; does not contain text; May be formatted inline or
+	# as a displayed block, depending on context
+	$self->{options}{'_default_translated'} .= " <imagedata>";
+	$self->{options}{'_default_inline'} .= " <imagedata>";
+	$self->{options}{'_default_attributes'}.=' <imagedata>fileref';
+
+	# imageobject; does not contain text; May be formatted inline or
+	# as a displayed block, depending on context
+	$self->{options}{'_default_untranslated'} .= " <imageobject>";
+	$self->{options}{'_default_inline'} .= " <imageobject>";
+
+	# imageobjectco; does not contain text; Formatted as a displayed block
+	# NOTE: may be in a inlinemediaobject
+	# TODO: check if this works when the inlinemediaobject is defined
+	# as inline
+	$self->{options}{'_default_untranslated'} .= " <imageobjectco>";
+	$self->{options}{'_default_break'} .= " <imageobjectco>";
+
+	# important; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <important>";
+	$self->{options}{'_default_break'} .= " <important>";
+
+	# index; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <index>";
+	$self->{options}{'_default_break'} .= " <index>";
+
+	# indexdiv; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <indexdiv>";
+	$self->{options}{'_default_break'} .= " <indexdiv>";
+
+	# indexentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <indexentry>";
+	$self->{options}{'_default_break'} .= " <indexentry>";
+
+	# indexinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <indexinfo>";
+	$self->{options}{'_default_placeholder'} .= " <indexinfo>";
+
+	# indexterm; does not contain text; 
+	$self->{options}{'_default_untranslated'} .= " <indexterm>";
+	$self->{options}{'_default_placeholder'} .= " <indexterm>";
+
+	# info; does not contain text; 
+	$self->{options}{'_default_untranslated'} .= " <info>";
+	$self->{options}{'_default_placeholder'} .= " <info>";
+
+	# informalequation; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <informalequation>";
+	$self->{options}{'_default_placeholder'} .= " <informalequation>";
+
+	# informalexample; does not contain text; Formatted as a displayed block.
+	# NOTE: can be in a para
+	$self->{options}{'_default_untranslated'} .= " <informalexample>";
+	$self->{options}{'_default_break'} .= " <informalexample>";
+
+	# informalfigure; does not contain text; Formatted as a displayed block.
+	# NOTE: can be in a para
+	$self->{options}{'_default_untranslated'} .= " <informalfigure>";
+	$self->{options}{'_default_break'} .= " <informalfigure>";
+
+	# informaltable; does not contain text; Formatted as a displayed block.
+	# NOTE: can be in a para
+	$self->{options}{'_default_untranslated'} .= " <informaltable>";
+	$self->{options}{'_default_break'} .= " <informaltable>";
+
+	# initializer; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <initializer>";
+	$self->{options}{'_default_inline'} .= " <initializer>";
+
+	# inlineequation; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " W<inlineequation>";
+	$self->{options}{'_default_placeholder'} .= " <inlineequation>";
+
+	# inlinegraphic; does not contain text; Formatted inline
+	# empty; v4, not in v5
+	$self->{options}{'_default_translated'} .= " W<inlinegraphic>";
+	$self->{options}{'_default_inline'} .= " <inlinegraphic>";
+
+	# inlinemediaobject; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <inlinemediaobject>";
+	$self->{options}{'_default_placeholder'} .= " <inlinemediaobject>";
+
+	# interface; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <interface>";
+	$self->{options}{'_default_inline'} .= " <interface>";
+
+	# interfacedefinition; contains text; Formatted inline
+	# Removed in v4.0
+	$self->{options}{'_default_translated'} .= " <interfacedefinition>";
+	$self->{options}{'_default_inline'} .= " <interfacedefinition>";
+
+	# interfacename; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <interfacename>";
+	$self->{options}{'_default_inline'} .= " <interfacename>";
+
+	# invpartnumber; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <invpartnumber>";
+	$self->{options}{'_default_inline'} .= " <invpartnumber>";
+
+	# isbn; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <isbn>";
+	$self->{options}{'_default_inline'} .= " <isbn>";
+
+	# issn; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <issn>";
+	$self->{options}{'_default_inline'} .= " <issn>";
+
+	# issuenum; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <issuenum>";
+	$self->{options}{'_default_inline'} .= " <issuenum>";
+
+	# itemizedlist; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <itemizedlist>";
+	$self->{options}{'_default_break'} .= " <itemizedlist>";
+
+	# itermset; does not contain text;
+	# FIXME
+	$self->{options}{'_default_untranslated'} .= " <itermset>";
+	$self->{options}{'_default_inline'} .= " <itermset>";
+
+# JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+
+	# jobtitle; contains text; Formatted inline or as a displayed block
+	# NOTE: can be in a para
+	$self->{options}{'_default_translated'} .= " <jobtitle>";
+	$self->{options}{'_default_inline'} .= " <jobtitle>";
+
+# KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+
+	# keycap; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <keycap>";
+	$self->{options}{'_default_inline'} .= " <keycap>";
+
+	# keycode; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <keycode>";
+	$self->{options}{'_default_inline'} .= " <keycode>";
+
+	# keycombo; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <keycombo>";
+	$self->{options}{'_default_inline'} .= " <keycombo>";
+
+	# keysym; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <keysym>";
+	$self->{options}{'_default_inline'} .= " <keysym>";
+
+	# keyword; contains text;
+	# NOTE: could be inline
+	$self->{options}{'_default_translated'} .= " <keyword>";
+	$self->{options}{'_default_break'} .= " <keyword>";
+
+	# keywordset; contains text; Formatted inline or as a displayed block
+	# NOTE: could be placeholder/break
+	$self->{options}{'_default_translated'} .= " <keywordset>";
+	$self->{options}{'_default_break'} .= " <keywordset>";
+
+# LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+
+	# label; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <label>";
+	$self->{options}{'_default_break'} .= " <label>";
+
+	# legalnotice; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <legalnotice>";
+	$self->{options}{'_default_break'} .= " <legalnotice>";
+
+	# lhs; contains text; Formatted as a displayed block.
+	# NOTE: it might be better to have the production as verbatim
+	#       Keeping the constrainst inline to have it close to the
+	#       lhs or rhs.
+	$self->{options}{'_default_translated'} .= " <lhs>";
+	$self->{options}{'_default_break'} .= " <lhs>";
+
+	# lineage; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <lineage>";
+	$self->{options}{'_default_inline'} .= " <lineage>";
+
+	# lineannotation; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <lineannotation>";
+	$self->{options}{'_default_inline'} .= " <lineannotation>";
+
+	# link; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <link>";
+	$self->{options}{'_default_inline'} .= " <link>";
+
+	# listitem; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <listitem>";
+	$self->{options}{'_default_break'} .= " <listitem>";
+
+	# literal; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <literal>";
+	$self->{options}{'_default_inline'} .= " <literal>";
+
+	# literallayout; contains text; verbatim
+	$self->{options}{'_default_translated'} .= " W<literallayout>";
+	$self->{options}{'_default_placeholder'} .= " <literallayout>";
+
+	# locator; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <locator>";
+	$self->{options}{'_default_inline'} .= " <locator>";
+
+	# lot; does not contain text; Formatted as a displayed block.
+	# v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <lot>";
+	$self->{options}{'_default_break'} .= " <lot>";
+
+	# lotentry; contains text; Formatted as a displayed block.
+	# v4, not in v5
+	$self->{options}{'_default_translated'} .= " <lotentry>";
+	$self->{options}{'_default_break'} .= " <lotentry>";
+
+# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+
+	# manvolnum; contains text;
+	$self->{options}{'_default_translated'} .= " <manvolnum>";
+	$self->{options}{'_default_inline'} .= " <manvolnum>";
+
+	# markup; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <markup>";
+	$self->{options}{'_default_inline'} .= " <markup>";
+
+	# mathphrase; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <mathphrase>";
+	$self->{options}{'_default_inline'} .= " <mathphrase>";
+
+	# medialabel; contains text; Formatted inline
+	# v4, not in v5
+	$self->{options}{'_default_translated'} .= " <medialabel>";
+	$self->{options}{'_default_inline'} .= " <medialabel>";
+
+	# mediaobject; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <mediaobject>";
+	$self->{options}{'_default_placeholder'} .= " <mediaobject>";
+
+	# mediaobjectco; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <mediaobjectco>";
+	$self->{options}{'_default_placeholder'} .= " <mediaobjectco>";
+
+	# member; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <member>";
+	$self->{options}{'_default_inline'} .= " <member>";
+
+	# menuchoice; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <menuchoice>";
+	$self->{options}{'_default_inline'} .= " <menuchoice>";
+
+	# methodname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <methodname>";
+	$self->{options}{'_default_inline'} .= " <methodname>";
+
+	# methodparam; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <methodparam>";
+	$self->{options}{'_default_inline'} .= " <methodparam>";
+
+	# methodsynopsis; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <methodsynopsis>";
+	$self->{options}{'_default_inline'} .= " <methodsynopsis>";
+
+	# modifier; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <modifier>";
+	$self->{options}{'_default_inline'} .= " <modifier>";
+
+	# mousebutton; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <mousebutton>";
+	$self->{options}{'_default_inline'} .= " <mousebutton>";
+
+	# msg; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msg>";
+	$self->{options}{'_default_break'} .= " <msg>";
+
+	# msgaud; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <msgaud>";
+	$self->{options}{'_default_break'} .= " <msgaud>";
+
+	# msgentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgentry>";
+	$self->{options}{'_default_break'} .= " <msgentry>";
+
+	# msgexplan; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgexplan>";
+	$self->{options}{'_default_break'} .= " <msgexplan>";
+
+	# msginfo; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msginfo>";
+	$self->{options}{'_default_break'} .= " <msginfo>";
+
+	# msglevel; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <msglevel>";
+	$self->{options}{'_default_break'} .= " <msglevel>";
+
+	# msgmain; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgmain>";
+	$self->{options}{'_default_break'} .= " <msgmain>";
+
+	# msgorig; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <msgorig>";
+	$self->{options}{'_default_break'} .= " <msgorig>";
+
+	# msgrel; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgrel>";
+	$self->{options}{'_default_break'} .= " <msgrel>";
+
+	# msgset; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgset>";
+	$self->{options}{'_default_placeholder'} .= " <msgset>";
+
+	# msgsub; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgsub>";
+	$self->{options}{'_default_break'} .= " <msgsub>";
+
+	# msgtext; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <msgtext>";
+	$self->{options}{'_default_break'} .= " <msgtext>";
+
+# NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+
+	# nonterminal; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <nonterminal>";
+	$self->{options}{'_default_inline'} .= " <nonterminal>";
+
+	# note; does not contain text; Formatted inline
+	# NOTE: can be in a para
+	$self->{options}{'_default_untranslated'} .= " <note>";
+	$self->{options}{'_default_inline'} .= " <note>";
+
+# OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
+
+	# objectinfo; does not contain text; v3.1 -> v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <objectinfo>";
+	$self->{options}{'_default_placeholder'} .= " <objectinfo>";
+
+	# olink; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <olink>";
+	$self->{options}{'_default_inline'} .= " <olink>";
+
+	# ooclass; does not contain text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <ooclass>";
+	$self->{options}{'_default_inline'} .= " <ooclass>";
+
+	# ooexception; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <ooexception>";
+	$self->{options}{'_default_inline'} .= " <ooexception>";
+
+	# oointerface; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <oointerface>";
+	$self->{options}{'_default_inline'} .= " <oointerface>";
+
+	# option; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <option>";
+	$self->{options}{'_default_inline'} .= " <option>";
+
+	# optional; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <optional>";
+	$self->{options}{'_default_inline'} .= " <optional>";
+
+	# orderedlist; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <orderedlist>";
+	$self->{options}{'_default_placeholder'} .= " <orderedlist>";
+
+	# org; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <org>";
+	$self->{options}{'_default_inline'} .= " <org>";
+
+	# orgdiv; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <orgdiv>";
+	$self->{options}{'_default_inline'} .= " <orgdiv>";
+
+	# orgname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <orgname>";
+	$self->{options}{'_default_inline'} .= " <orgname>";
+
+	# otheraddr; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <otheraddr>";
+	$self->{options}{'_default_inline'} .= " <otheraddr>";
+
+	# othercredit; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <othercredit>";
+	$self->{options}{'_default_inline'} .= " <othercredit>";
+
+	# othername; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <othername>";
+	$self->{options}{'_default_inline'} .= " <othername>";
+
+# PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+
+	# package; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <package>";
+	$self->{options}{'_default_inline'} .= " <package>";
+
+	# pagenums; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <pagenums>";
+	$self->{options}{'_default_inline'} .= " <pagenums>";
+
+	# para; contains text; Formatted as a displayed block
+	$self->{options}{'_default_translated'} .= " <para>";
+	$self->{options}{'_default_break'} .= " <para>";
+
+	# paramdef; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <paramdef>";
+	$self->{options}{'_default_inline'} .= " <paramdef>";
+
+	# parameter; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <parameter>";
+	$self->{options}{'_default_inline'} .= " <parameter>";
+
+	# part; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <part>";
+	$self->{options}{'_default_break'} .= " <part>";
+
+	# partinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <partinfo>";
+	$self->{options}{'_default_placeholder'} .= " <partinfo>";
+
+	# partintro; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <partintro>";
+	$self->{options}{'_default_break'} .= " <partintro>";
+
+	# person; does not contain text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_untranslated'} .= " <person>";
+	$self->{options}{'_default_inline'} .= " <person>";
+
+	# personblurb; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <personblurb>";
+	$self->{options}{'_default_placeholder'} .= " <personblurb>";
+
+	# personname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <personname>";
+	$self->{options}{'_default_inline'} .= " <personname>";
+
+	# phone; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <phone>";
+	$self->{options}{'_default_inline'} .= " <phone>";
+
+	# phrase; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <phrase>";
+	$self->{options}{'_default_inline'} .= " <phrase>";
+
+	# pob; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <pob>";
+	$self->{options}{'_default_inline'} .= " <pob>";
+
+	# postcode; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <postcode>";
+	$self->{options}{'_default_inline'} .= " <postcode>";
+
+	# preface; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <preface>";
+	$self->{options}{'_default_break'} .= " <preface>";
+
+	# prefaceinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <prefaceinfo>";
+	$self->{options}{'_default_placeholder'} .= " <prefaceinfo>";
+
+	# primary; contains text;
+	$self->{options}{'_default_translated'} .= " <primary>";
+	$self->{options}{'_default_break'} .= " <primary>";
+
+	# primaryie; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <primaryie>";
+	$self->{options}{'_default_break'} .= " <primaryie>";
+
+	# printhistory; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <printhistory>";
+	$self->{options}{'_default_break'} .= " <printhistory>";
+
+	# procedure; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <procedure>";
+	$self->{options}{'_default_placeholder'} .= " <procedure>";
+
+	# production; doesnot contain text;
+	# NOTE: it might be better to have the production as verbatim
+	#       Keeping the constrainst inline to have it close to the
+	#       lhs or rhs.
+	$self->{options}{'_default_untranslated'} .= " <production>";
+	$self->{options}{'_default_break'} .= " <production>";
+
+	# productionrecap; does not contain text; like production
+	$self->{options}{'_default_untranslated'} .= " <productionrecap>";
+	$self->{options}{'_default_break'} .= " <productionrecap>";
+
+	# productionset; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <productionset>";
+	$self->{options}{'_default_placeholder'} .= " <productionset>";
+
+	# productname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <productname>";
+	$self->{options}{'_default_inline'} .= " <productname>";
+
+	# productnumber; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <productnumber>";
+	$self->{options}{'_default_inline'} .= " <productnumber>";
+
+	# programlisting; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " W<programlisting>";
+	$self->{options}{'_default_placeholder'} .= " <programlisting>";
+
+	# programlistingco; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <programlistingco>";
+	$self->{options}{'_default_placeholder'} .= " <programlistingco>";
+
+	# prompt; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <prompt>";
+	$self->{options}{'_default_inline'} .= " <prompt>";
+
+	# property; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <property>";
+	$self->{options}{'_default_inline'} .= " <property>";
+
+	# pubdate; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <pubdate>";
+	$self->{options}{'_default_inline'} .= " <pubdate>";
+
+	# publisher; does not contain text; Formatted inline or as a displayed block
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <publisher>";
+	$self->{options}{'_default_inline'} .= " <publisher>";
+
+	# publishername; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_translated'} .= " <publishername>";
+	$self->{options}{'_default_inline'} .= " <publishername>";
+
+# QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
+
+	# qandadiv; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <qandadiv>";
+	$self->{options}{'_default_break'} .= " <qandadiv>";
+
+	# qandaentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <qandaentry>";
+	$self->{options}{'_default_break'} .= " <qandaentry>";
+
+	# qandaset; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <qandaset>";
+	$self->{options}{'_default_break'} .= " <qandaset>";
+
+	# question; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <question>";
+	$self->{options}{'_default_break'} .= " <question>";
+
+	# quote; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <quote>";
+	$self->{options}{'_default_inline'} .= " <quote>";
+
+# RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
+
+	# refclass; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <refclass>";
+	$self->{options}{'_default_break'} .= " <refclass>";
+
+	# refdescriptor; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <refdescriptor>";
+	$self->{options}{'_default_break'} .= " <refdescriptor>";
+
+	# refentry; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refentry>";
+	$self->{options}{'_default_break'} .= " <refentry>";
+
+	# refentryinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refentryinfo>";
+	$self->{options}{'_default_placeholder'} .= " <refentryinfo>";
+
+	# refentrytitle; contains text; Formatted as a displayed block
+# FIXME: do not seems to be a block
+	$self->{options}{'_default_translated'} .= " <refentrytitle>";
+	$self->{options}{'_default_inline'} .= " <refentrytitle>";
+
+	# reference; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <reference>";
+	$self->{options}{'_default_break'} .= " <reference>";
+
+	# referenceinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <referenceinfo>";
+	$self->{options}{'_default_placeholder'} .= " <referenceinfo>";
+
+	# refmeta; does not contains text; 
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_untranslated'} .= " <refmeta>";
+	$self->{options}{'_default_break'} .= " <refmeta>";
+
+	# refmiscinfo; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <refmiscinfo>";
+	$self->{options}{'_default_break'} .= " <refmiscinfo>";
+
+	# refname; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <refname>";
+	$self->{options}{'_default_break'} .= " <refname>";
+
+	# refnamediv; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refnamediv>";
+	$self->{options}{'_default_break'} .= " <refnamediv>";
+
+	# refpurpose; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <refpurpose>";
+	$self->{options}{'_default_inline'} .= " <refpurpose>";
+
+	# refsect1; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refsect1>";
+	$self->{options}{'_default_break'} .= " <refsect1>";
+
+	# refsect1info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refsect1info>";
+	$self->{options}{'_default_placeholder'} .= " <refsect1info>";
+
+	# refsect2; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refsect2>";
+	$self->{options}{'_default_break'} .= " <refsect2>";
+
+	# refsect2info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refsect2info>";
+	$self->{options}{'_default_placeholder'} .= " <refsect2info>";
+
+	# refsect3; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refsect3>";
+	$self->{options}{'_default_break'} .= " <refsect3>";
+
+	# refsect3info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refsect3info>";
+	$self->{options}{'_default_placeholder'} .= " <refsect3info>";
+
+	# refsection; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refsection>";
+	$self->{options}{'_default_break'} .= " <refsection>";
+
+	# refsectioninfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refsectioninfo>";
+	$self->{options}{'_default_placeholder'} .= " <refsectioninfo>";
+
+	# refsynopsisdiv; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <refsynopsisdiv>";
+	$self->{options}{'_default_break'} .= " <refsynopsisdiv>";
+
+	# refsynopsisdivinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <refsynopsisdivinfo>";
+	$self->{options}{'_default_placeholder'} .= " <refsynopsisdivinfo>";
+
+	# releaseinfo; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <releaseinfo>";
+	$self->{options}{'_default_break'} .= " <releaseinfo>";
+
+	# remark; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_translated'} .= " <remark>";
+	$self->{options}{'_default_inline'} .= " <remark>";
+
+	# replaceable; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <replaceable>";
+	$self->{options}{'_default_inline'} .= " <replaceable>";
+
+	# returnvalue; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <returnvalue>";
+	$self->{options}{'_default_inline'} .= " <returnvalue>";
+
+	# revdescription; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_translated'} .= " <revdescription>";
+	$self->{options}{'_default_break'} .= " <revdescription>";
+
+	# revhistory; does not contain text; Formatted as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <revhistory>";
+	$self->{options}{'_default_break'} .= " <revhistory>";
+
+	# revision; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <revision>";
+	$self->{options}{'_default_break'} .= " <revision>";
+
+	# revnumber; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <revnumber>";
+	$self->{options}{'_default_inline'} .= " <revnumber>";
+
+	# revremark; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_translated'} .= " <revremark>";
+	$self->{options}{'_default_break'} .= " <revremark>";
+
+	# rhs; contains text; Formatted as a displayed block.
+	# NOTE: it might be better to have the production as verbatim
+	#       Keeping the constrainst inline to have it close to the
+	#       lhs or rhs.
+	$self->{options}{'_default_translated'} .= " <rhs>";
+	$self->{options}{'_default_break'} .= " <rhs>";
+
+	# row; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <row>";
+	$self->{options}{'_default_break'} .= " <row>";
+
+# SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
+
+	# sbr; does not contain text; line break
+	$self->{options}{'_default_untranslated'} .= " <sbr>";
+	$self->{options}{'_default_break'} .= " <sbr>";
+
+	# screen; contains text; verbatim
+	$self->{options}{'_default_translated'} .= " W<screen>";
+	$self->{options}{'_default_placeholder'} .= " <screen>";
+
+	# screenco; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <screenco>";
+	$self->{options}{'_default_placeholder'} .= " <screenco>";
+
+	# screeninfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <screeninfo>";
+	$self->{options}{'_default_placeholder'} .= " <screeninfo>";
+
+	# screenshot; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <screenshot>";
+	$self->{options}{'_default_placeholder'} .= " <screenshot>";
+
+	# secondary; contains text; 
+	$self->{options}{'_default_translated'} .= " <secondary>";
+	$self->{options}{'_default_break'} .= " <secondary>";
+
+	# secondaryie; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <secondaryie>";
+	$self->{options}{'_default_break'} .= " <secondaryie>";
+
+	# sect1; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sect1>";
+	$self->{options}{'_default_break'} .= " <sect1>";
+
+	# sect1info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sect1info>";
+	$self->{options}{'_default_placeholder'} .= " <sect1info>";
+
+	# sect2; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sect2>";
+	$self->{options}{'_default_break'} .= " <sect2>";
+
+	# sect2info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sect2info>";
+	$self->{options}{'_default_placeholder'} .= " <sect2info>";
+
+	# sect3; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sect3>";
+	$self->{options}{'_default_break'} .= " <sect3>";
+
+	# sect3info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sect3info>";
+	$self->{options}{'_default_placeholder'} .= " <sect3info>";
+
+	# sect4; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sect4>";
+	$self->{options}{'_default_break'} .= " <sect4>";
+
+	# sect4info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sect4info>";
+	$self->{options}{'_default_placeholder'} .= " <sect4info>";
+
+	# sect5; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sect5>";
+	$self->{options}{'_default_break'} .= " <sect5>";
+
+	# sect5info; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sect5info>";
+	$self->{options}{'_default_placeholder'} .= " <sect5info>";
+
+	# section; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <section>";
+	$self->{options}{'_default_break'} .= " <section>";
+
+	# sectioninfo; does not contain text; v3.1 -> v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sectioninfo>";
+	$self->{options}{'_default_placeholder'} .= " <sectioninfo>";
+
+	# see; contains text; 
+	$self->{options}{'_default_translated'} .= " <see>";
+	$self->{options}{'_default_break'} .= " <see>";
+
+	# seealso; contains text; 
+	$self->{options}{'_default_translated'} .= " <seealso>";
+	$self->{options}{'_default_break'} .= " <seealso>";
+
+	# seealsoie; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <seealsoie>";
+	$self->{options}{'_default_break'} .= " <seealsoie>";
+
+	# seeie; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <seeie>";
+	$self->{options}{'_default_break'} .= " <seeie>";
+
+	# seg; contains text;
+	$self->{options}{'_default_translated'} .= " <seg>";
+	$self->{options}{'_default_break'} .= " <seg>";
+
+	# seglistitem; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <seglistitem>";
+	$self->{options}{'_default_break'} .= " <seglistitem>";
+
+	# segmentedlist; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <segmentedlist>";
+	$self->{options}{'_default_break'} .= " <segmentedlist>";
+
+	# segtitle; contains text;
+	$self->{options}{'_default_translated'} .= " <segtitle>";
+	$self->{options}{'_default_break'} .= " <segtitle>";
+
+	# seriesinfo; does not contain text;
+	# Removed in v4.0
+	$self->{options}{'_default_untranslated'} .= " <seriesinfo>";
+	$self->{options}{'_default_placeholder'} .= " <seriesinfo>";
+
+	# seriesvolnums; contains text; Formatted inline
+	# NOTE: could be in the break class
+	$self->{options}{'_default_translated'} .= " <seriesvolnums>";
+	$self->{options}{'_default_inline'} .= " <seriesvolnums>";
+
+	# set; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <set>";
+	$self->{options}{'_default_break'} .= " <set>";
+
+	# setindex; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <setindex>";
+	$self->{options}{'_default_break'} .= " <setindex>";
+
+	# setindexinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <setindexinfo>";
+	$self->{options}{'_default_placeholder'} .= " <setindexinfo>";
+
+	# setinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <setinfo>";
+	$self->{options}{'_default_placeholder'} .= " <setinfo>";
+
+	# sgmltag; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <sgmltag>";
+	$self->{options}{'_default_inline'} .= " <sgmltag>";
+
+	# shortaffil; contains text; Formatted inline or as a
+	# displayed block depending on context
+	$self->{options}{'_default_translated'} .= " <shortaffil>";
+	$self->{options}{'_default_inline'} .= " <shortaffil>";
+
+	# shortcut; does not contain text; Formatted inline
+	$self->{options}{'_default_untranslated'} .= " <shortcut>";
+	$self->{options}{'_default_inline'} .= " <shortcut>";
+
+	# sidebar; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <sidebar>";
+	$self->{options}{'_default_break'} .= " <sidebar>";
+
+	# sidebarinfo; does not contain text; v4, not in v5
+	$self->{options}{'_default_untranslated'} .= " <sidebarinfo>";
+	$self->{options}{'_default_placeholder'} .= " <sidebarinfo>";
+
+	# simpara; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <simpara>";
+	$self->{options}{'_default_break'} .= " <simpara>";
+
+	# simplelist; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <simplelist>";
+	$self->{options}{'_default_inline'} .= " <simplelist>";
+
+	# simplemsgentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <simplemsgentry>";
+	$self->{options}{'_default_break'} .= " <simplemsgentry>";
+
+	# simplesect; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <simplesect>";
+	$self->{options}{'_default_break'} .= " <simplesect>";
+
+	# spanspec; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <spanspec>";
+	$self->{options}{'_default_break'} .= " <spanspec>";
+
+	# state; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <state>";
+	$self->{options}{'_default_inline'} .= " <state>";
+
+	# step; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <step>";
+	$self->{options}{'_default_break'} .= " <step>";
+
+	# stepalternatives; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <stepalternatives>";
+	$self->{options}{'_default_break'} .= " <stepalternatives>";
+
+	# street; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <street>";
+	$self->{options}{'_default_inline'} .= " <street>";
+
+	# structfield; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <structfield>";
+	$self->{options}{'_default_inline'} .= " <structfield>";
+
+	# structname; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <structname>";
+	$self->{options}{'_default_inline'} .= " <structname>";
+
+	# subject; does not contain text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_untranslated'} .= " <subject>";
+	$self->{options}{'_default_break'} .= " <subject>";
+
+	# subjectset; does not contain text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_untranslated'} .= " <subjectset>";
+	$self->{options}{'_default_break'} .= " <subjectset>";
+
+	# subjectterm; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <subjectterm>";
+	$self->{options}{'_default_break'} .= " <subjectterm>";
+
+	# subscript; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <subscript>";
+	$self->{options}{'_default_inline'} .= " <subscript>";
+
+	# substeps; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <substeps>";
+	$self->{options}{'_default_break'} .= " <substeps>";
+
+	# subtitle; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <subtitle>";
+	$self->{options}{'_default_break'} .= " <subtitle>";
+
+	# superscript; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <superscript>";
+	$self->{options}{'_default_inline'} .= " <superscript>";
+
+	# surname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <surname>";
+	$self->{options}{'_default_inline'} .= " <surname>";
+
+#svg:svg
+
+	# symbol; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <symbol>";
+	$self->{options}{'_default_inline'} .= " <symbol>";
+
+	# synopfragment; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <synopfragment>";
+	$self->{options}{'_default_placeholder'} .= " <synopfragment>";
+
+	# synopfragmentref; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <synopfragmentref>";
+	$self->{options}{'_default_inline'} .= " <synopfragmentref>";
+
+	# synopsis; contains text; verbatim
+	$self->{options}{'_default_translated'} .= " W<synopsis>";
+	$self->{options}{'_default_placeholder'} .= " <synopsis>";
+
+	# systemitem; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <systemitem>";
+	$self->{options}{'_default_inline'} .= " <systemitem>";
+
+# TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
+
+	# table; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <table>";
+	$self->{options}{'_default_placeholder'} .= " <table>";
+
+	# tag; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <tag>";
+	$self->{options}{'_default_inline'} .= " <tag>";
+
+	# task; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <task>";
+	$self->{options}{'_default_placeholder'} .= " <task>";
+
+	# taskprerequisites; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <taskprerequisites>";
+	$self->{options}{'_default_break'} .= " <taskprerequisites>";
+
+	# taskrelated; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <taskrelated>";
+	$self->{options}{'_default_break'} .= " <taskrelated>";
+
+	# tasksummary; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <tasksummary>";
+	$self->{options}{'_default_break'} .= " <tasksummary>";
+
+	# tbody; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <tbody>";
+	$self->{options}{'_default_break'} .= " <tbody>";
+
+	# td; contains text;
+	$self->{options}{'_default_translated'} .= " <td>";
+	$self->{options}{'_default_break'} .= " <td>";
+
+	# term; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <term>";
+	$self->{options}{'_default_break'} .= " <term>";
+
+	# termdef; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <termdef>";
+	$self->{options}{'_default_inline'} .= " <termdef>";
+
+	# tertiary; contains text; Suppressed
+	$self->{options}{'_default_translated'} .= " <tertiary>";
+	$self->{options}{'_default_placeholder'} .= " <tertiary>";
+
+	# tertiaryie; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <tertiaryie>";
+	$self->{options}{'_default_break'} .= " <tertiaryie>";
+
+	# textdata; does not contain text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_untranslated'} .= " <textdata>";
+	$self->{options}{'_default_break'} .= " <textdata>";
+	$self->{options}{'_default_attributes'}.=' <textdata>fileref';
+
+	# textobject; does not contain text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_untranslated'} .= " <textobject>";
+	$self->{options}{'_default_break'} .= " <textobject>";
+
+	# tfoot; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <tfoot>";
+	$self->{options}{'_default_break'} .= " <tfoot>";
+
+	# tgroup; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <tgroup>";
+	$self->{options}{'_default_break'} .= " <tgroup>";
+
+	# th; contains text;
+	$self->{options}{'_default_translated'} .= " <th>";
+	$self->{options}{'_default_break'} .= " <th>";
+
+	# thead; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <thead>";
+	$self->{options}{'_default_break'} .= " <thead>";
+
+	# tip; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <tip>";
+	$self->{options}{'_default_break'} .= " <tip>";
+
+	# title; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <title>";
+	$self->{options}{'_default_break'} .= " <title>";
+
+	# titleabbrev; contains text; Formatted inline or as a displayed block
+	# NOTE: could be in the inline class
+	$self->{options}{'_default_translated'} .= " <titleabbrev>";
+	$self->{options}{'_default_break'} .= " <titleabbrev>";
+
+	# toc; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toc>";
+	$self->{options}{'_default_break'} .= " <toc>";
+
+	# tocback; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <tocback>";
+	$self->{options}{'_default_break'} .= " <tocback>";
+
+	# tocchap; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <tocchap>";
+	$self->{options}{'_default_break'} .= " <tocchap>";
+
+	# tocdiv; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <tocdiv>";
+	$self->{options}{'_default_break'} .= " <tocdiv>";
+
+	# tocentry; contains text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <tocentry>";
+	$self->{options}{'_default_break'} .= " <tocentry>";
+
+	# tocfront; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_translated'} .= " <tocfront>";
+	$self->{options}{'_default_break'} .= " <tocfront>";
+
+	# toclevel1; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toclevel1>";
+	$self->{options}{'_default_break'} .= " <toclevel1>";
+
+	# toclevel2; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toclevel2>";
+	$self->{options}{'_default_break'} .= " <toclevel2>";
+
+	# toclevel3; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toclevel3>";
+	$self->{options}{'_default_break'} .= " <toclevel3>";
+
+	# toclevel4; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toclevel4>";
+	$self->{options}{'_default_break'} .= " <toclevel4>";
+
+	# toclevel5; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <toclevel5>";
+	$self->{options}{'_default_break'} .= " <toclevel5>";
+
+	# tocpart; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <tocpart>";
+	$self->{options}{'_default_break'} .= " <tocpart>";
+
+	# token; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <token>";
+	$self->{options}{'_default_inline'} .= " <token>";
+
+	# tr; does not contain text;
+	$self->{options}{'_default_untranslated'} .= " <tr>";
+	$self->{options}{'_default_break'} .= " <tr>";
+
+	# trademark; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <trademark>";
+	$self->{options}{'_default_inline'} .= " <trademark>";
+
+	# type; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <type>";
+	$self->{options}{'_default_inline'} .= " <type>";
+
+# UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
+
+	# ulink; contains text; Formatted inline; v4, not in v5
+	$self->{options}{'_default_translated'} .= " <ulink>";
+	$self->{options}{'_default_inline'} .= " <ulink>";
+
+	# uri; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <uri>";
+	$self->{options}{'_default_inline'} .= " <uri>";
+
+	# userinput; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <userinput>";
+	$self->{options}{'_default_inline'} .= " <userinput>";
+
+# VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+
+	# varargs; empty element;
+	$self->{options}{'_default_untranslated'} .= " <varargs>";
+	$self->{options}{'_default_inline'} .= " <varargs>";
+
+	# variablelist; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <variablelist>";
+	$self->{options}{'_default_placeholder'} .= " <variablelist>";
+
+	# varlistentry; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <varlistentry>";
+	$self->{options}{'_default_break'} .= " <varlistentry>";
+
+	# varname; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <varname>";
+	$self->{options}{'_default_inline'} .= " <varname>";
+
+	# videodata; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <videodata>";
+	$self->{options}{'_default_break'} .= " <videodata>";
+	$self->{options}{'_default_attributes'}.=' <videodata>fileref';
+
+	# videoobject; contains text; Formatted inline or as a displayed block
+	$self->{options}{'_default_untranslated'} .= " <videoobject>";
+	$self->{options}{'_default_break'} .= " <videoobject>";
+
+	# void; empty element;
+	$self->{options}{'_default_untranslated'} .= " <void>";
+	$self->{options}{'_default_inline'} .= " <void>";
+
+	# volumenum; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <volumenum>";
+	$self->{options}{'_default_inline'} .= " <volumenum>";
+
+# WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
+
+	# warning; does not contain text; Formatted as a displayed block.
+	$self->{options}{'_default_untranslated'} .= " <warning>";
+	$self->{options}{'_default_break'} .= " <warning>";
+
+	# wordasword; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <wordasword>";
+	$self->{options}{'_default_inline'} .= " <wordasword>";
+
+# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+	# xref; empty element;
+	$self->{options}{'_default_untranslated'} .= " <xref>";
+	$self->{options}{'_default_inline'} .= " <xref>";
+
+# YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
+
+	# year; contains text; Formatted inline
+	$self->{options}{'_default_translated'} .= " <year>";
+	$self->{options}{'_default_inline'} .= " <year>";
+
+# ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
+
+	$self->{options}{'_default_attributes'}.='
+		lang
+		xml:lang';
+
+	$self->treat_options;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/lib/Locale/Po4a/Po.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,1580 @@
+# Locale::Po4a::Po -- manipulation of po files
+# $Id: Po.pm,v 1.95 2009-02-28 22:18:39 nekral-guest Exp $
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the terms of GPL (see COPYING).
+
+############################################################################
+# Modules and declarations
+############################################################################
+
+=head1 NAME
+
+Locale::Po4a::Po - po file manipulation module
+
+=head1 SYNOPSIS
+
+    use Locale::Po4a::Po;
+    my $pofile=Locale::Po4a::Po->new();
+
+    # Read po file
+    $pofile->read('file.po');
+
+    # Add an entry
+    $pofile->push('msgid' => 'Hello', 'msgstr' => 'bonjour',
+                  'flags' => "wrap", 'reference'=>'file.c:46');
+
+    # Extract a translation
+    $pofile->gettext("Hello"); # returns 'bonjour'
+
+    # Write back to a file
+    $pofile->write('otherfile.po');
+
+=head1 DESCRIPTION
+
+Locale::Po4a::Po is a module that allows you to manipulate message
+catalogs. You can load and write from/to a file (which extension is often
+I<po>), you can build new entries on the fly or request for the translation
+of a string.
+
+For a more complete description of message catalogs in the po format and
+their use, please refer to the documentation of the gettext program.
+
+This module is part of the PO4A project, which objective is to use po files
+(designed at origin to ease the translation of program messages) to
+translate everything, including documentation (man page, info manual),
+package description, debconf templates, and everything which may benefit
+from this.
+
+=head1 OPTIONS ACCEPTED BY THIS MODULE
+
+=over 4
+
+=item porefs
+
+This specifies the reference format. It can be one of 'none' to not produce
+any reference, 'noline' to not specify the line number, and 'full' to
+include complete references.
+
+=back
+
+=cut
+
+use IO::File;
+
+
+require Exporter;
+
+package Locale::Po4a::Po;
+use DynaLoader;
+
+use Locale::Po4a::Common qw(wrap_msg wrap_mod wrap_ref_mod dgettext);
+
+use subs qw(makespace);
+use vars qw(@ISA @EXPORT_OK);
+@ISA = qw(Exporter DynaLoader);
+@EXPORT = qw(%debug);
+@EXPORT_OK = qw(&move_po_if_needed);
+
+use Locale::Po4a::TransTractor;
+# Try to use a C extension if present.
+eval("bootstrap Locale::Po4a::Po $Locale::Po4a::TransTractor::VERSION");
+
+use 5.006;
+use strict;
+use warnings;
+
+use Carp qw(croak);
+use File::Path; # mkdir before write
+use File::Copy; # move
+use POSIX qw(strftime floor);
+use Time::Local;
+
+use Encode;
+
+my @known_flags=qw(wrap no-wrap c-format fuzzy);
+
+our %debug=('canonize'  => 0,
+            'quote'     => 0,
+            'escape'    => 0,
+            'encoding'  => 0,
+            'filter'    => 0);
+
+=head1 Functions about whole message catalogs
+
+=over 4
+
+=item new()
+
+Creates a new message catalog. If an argument is provided, it's the name of
+a po file we should load.
+
+=cut
+
+sub new {
+    my ($this, $options) = (shift, shift);
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+    $self->initialize($options);
+
+    my $filename = shift;
+    $self->read($filename) if defined($filename) && length($filename);
+    return $self;
+}
+
+# Return the numerical timezone (e.g. +0200)
+# Neither the %z nor the %s formats of strftime are portable:
+# '%s' is not supported on Solaris and '%z' indicates
+# "2006-10-25 19:36E. Europe Standard Time" on MS Windows.
+sub timezone {
+    my @g = gmtime();
+    my @l = localtime();
+
+    my $diff;
+    $diff  = floor(timelocal(@l)/60 +0.5);
+    $diff -= floor(timelocal(@g)/60 +0.5);
+
+    my $h = floor($diff / 60) + $l[8]; # $l[8] indicates if we are currently
+                                       # in a daylight saving time zone
+    my $m = $diff%60;
+
+    return sprintf "%+03d%02d\n", $h, $m;
+}
+
+sub initialize {
+    my ($self, $options) = (shift, shift);
+    my $date = strftime("%Y-%m-%d %H:%M", localtime).timezone();
+    chomp $date;
+#    $options = ref($options) || $options;
+
+    $self->{options}{'porefs'}= 'full';
+    $self->{options}{'msgid-bugs-address'}= undef;
+    $self->{options}{'copyright-holder'}= "Free Software Foundation, Inc.";
+    $self->{options}{'package-name'}= "PACKAGE";
+    $self->{options}{'package-version'}= "VERSION";
+    foreach my $opt (keys %$options) {
+        if ($options->{$opt}) {
+            die wrap_mod("po4a::po",
+                         dgettext ("po4a", "Unknown option: %s"), $opt)
+                unless exists $self->{options}{$opt};
+            $self->{options}{$opt} = $options->{$opt};
+        }
+    }
+    $self->{options}{'porefs'} =~ /^(full|noline|none)$/ ||
+        die wrap_mod("po4a::po",
+                     dgettext ("po4a",
+                               "Invalid value for option 'porefs' ('%s' is ".
+                               "not one of 'full', 'noline' or 'none')"),
+                     $self->{options}{'porefs'});
+
+    $self->{po}=();
+    $self->{count}=0;  # number of msgids in the PO
+    # count_doc: number of strings in the document
+    # (duplicate strings counted multiple times)
+    $self->{count_doc}=0;
+    $self->{header_comment}=
+                     " SOME DESCRIPTIVE TITLE\n"
+                    ." Copyright (C) YEAR ".
+                     $self->{options}{'copyright-holder'}."\n"
+                    ." This file is distributed under the same license ".
+                     "as the ".$self->{options}{'package-name'}." package.\n"
+                    ." FIRST AUTHOR <EMAIL\@ADDRESS>, YEAR.\n"
+                    ."\n"
+                    .", fuzzy";
+#    $self->header_tag="fuzzy";
+    $self->{header}=escape_text("Project-Id-Version: ".
+                                $self->{options}{'package-name'}." ".
+                                $self->{options}{'package-version'}."\n".
+                        ((defined $self->{options}{'msgid-bugs-address'})?
+        "Report-Msgid-Bugs-To: ".$self->{options}{'msgid-bugs-address'}."\n":
+                                "").
+                                "POT-Creation-Date: $date\n".
+                                "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n".
+                                "Last-Translator: FULL NAME <EMAIL\@ADDRESS>\n".
+                                "Language-Team: LANGUAGE <LL\@li.org>\n".
+                                "MIME-Version: 1.0\n".
+                                "Content-Type: text/plain; charset=CHARSET\n".
+                                "Content-Transfer-Encoding: ENCODING");
+
+    $self->{encoder}=find_encoding("ascii");
+
+    # To make stats about gettext hits
+    $self->stats_clear();
+}
+
+=item read($)
+
+Reads a po file (which name is given as argument).  Previously existing
+entries in self are not removed, the new ones are added to the end of the
+catalog.
+
+=cut
+
+sub read {
+    my $self=shift;
+    my $filename=shift
+        or croak wrap_mod("po4a::po",
+                          dgettext("po4a",
+                                   "Please provide a non-null filename"));
+
+    my $fh;
+    if ($filename eq '-') {
+        $fh=*STDIN;
+    } else {
+        open $fh,"<$filename"
+            or croak wrap_mod("po4a::po",
+                              dgettext("po4a", "Can't read from %s: %s"),
+                              $filename, $!);
+    }
+
+    ## Read paragraphs line-by-line
+    my $pofile="";
+    my $textline;
+    while (defined ($textline = <$fh>)) {
+        $pofile .= $textline;
+    }
+#    close INPUT
+#        or croak (sprintf(dgettext("po4a",
+#                                   "Can't close %s after reading: %s"),
+#                          $filename,$!)."\n");
+
+    my $linenum=0;
+
+    foreach my $msg (split (/\n\n/,$pofile)) {
+        my ($msgid,$msgstr,$comment,$automatic,$reference,$flags,$buffer);
+        my ($msgid_plural, $msgstr_plural);
+        foreach my $line (split (/\n/,$msg)) {
+            $linenum++;
+            if ($line =~ /^#\. ?(.*)$/) {  # Automatic comment
+                $automatic .= (defined($automatic) ? "\n" : "").$1;
+
+            } elsif ($line =~ /^#: ?(.*)$/) { # reference
+                $reference .= (defined($reference) ? "\n" : "").$1;
+
+            } elsif ($line =~ /^#, ?(.*)$/) { # flags
+                $flags .= (defined($flags) ? "\n" : "").$1;
+
+            } elsif ($line =~ /^#(.*)$/) {  # Translator comments
+                $comment .= (defined($comment) ? "\n" : "").($1||"");
+
+            } elsif ($line =~ /^msgid (".*")$/) { # begin of msgid
+                $buffer = $1;
+
+            } elsif ($line =~ /^msgid_plural (".*")$/) {
+                # begin of msgid_plural, end of msgid
+
+                $msgid = $buffer;
+                $buffer = $1;
+
+            } elsif ($line =~ /^msgstr (".*")$/) {
+                # begin of msgstr, end of msgid
+
+                $msgid = $buffer;
+                $buffer = "$1";
+
+            } elsif ($line =~ /^msgstr\[([0-9]+)\] (".*")$/) {
+                # begin of msgstr[x], end of msgid_plural or msgstr[x-1]
+
+                # Note: po4a cannot uses plural forms
+                # (no integer to use the plural form)
+                #   * drop the msgstr[x] where x >= 2
+                #   * use msgstr[0] as the translation of msgid
+                #   * use msgstr[1] as the translation of msgid_plural
+
+                if ($1 eq "0") {
+                    $msgid_plural = $buffer;
+                    $buffer = "$2";
+                } elsif ($1 eq "1") {
+                    $msgstr = $buffer;
+                    $buffer = "$2";
+                } elsif ($1 eq "2") {
+                    $msgstr_plural = $buffer;
+                    warn wrap_ref_mod("$filename:$linenum",
+                                      "po4a::po",
+                                      dgettext("po4a", "Messages with more than 2 plural forms are not supported."));
+                }
+            } elsif ($line =~ /^(".*")$/) {
+                # continuation of a line
+                $buffer .= "\n$1";
+
+            } else {
+                warn wrap_ref_mod("$filename:$linenum",
+                                  "po4a::po",
+                                  dgettext("po4a", "Strange line: -->%s<--"),
+                                  $line);
+            }
+        }
+        $linenum++;
+        if (defined $msgid_plural) {
+            $msgstr_plural=$buffer;
+
+            $msgid = unquote_text($msgid) if (defined($msgid));
+            $msgstr = unquote_text($msgstr) if (defined($msgstr));
+
+            $self->push_raw ('msgid'     => $msgid,
+                             'msgstr'    => $msgstr,
+                             'reference' => $reference,
+                             'flags'     => $flags,
+                             'comment'   => $comment,
+                             'automatic' => $automatic,
+                             'plural'    => 0);
+
+            $msgid_plural = unquote_text($msgid_plural)
+                if (defined($msgid_plural));
+            $msgstr_plural = unquote_text($msgstr_plural)
+                if (defined($msgstr_plural));
+
+            $self->push_raw ('msgid'     => $msgid_plural,
+                             'msgstr'    => $msgstr_plural,
+                             'reference' => $reference,
+                             'flags'     => $flags,
+                             'comment'   => $comment,
+                             'automatic' => $automatic,
+                             'plural'    => 1);
+        } else {
+            $msgstr=$buffer;
+
+            $msgid = unquote_text($msgid) if (defined($msgid));
+            $msgstr = unquote_text($msgstr) if (defined($msgstr));
+
+            $self->push_raw ('msgid'     => $msgid,
+                             'msgstr'    => $msgstr,
+                             'reference' => $reference,
+                             'flags'     => $flags,
+                             'comment'   => $comment,
+                             'automatic' => $automatic);
+        }
+    }
+}
+
+=item write($)
+
+Writes the current catalog to the given file.
+
+=cut
+
+sub write{
+    my $self=shift;
+    my $filename=shift
+        or croak dgettext("po4a","Can't write to a file without filename")."\n";
+
+    my $fh;
+    if ($filename eq '-') {
+        $fh=\*STDOUT;
+    } else {
+        # make sure the directory in which we should write the localized
+        # file exists
+        my $dir = $filename;
+        if ($dir =~ m|/|) {
+            $dir =~ s|/[^/]*$||;
+
+            File::Path::mkpath($dir, 0, 0755) # Croaks on error
+                if (length ($dir) && ! -e $dir);
+        }
+        open $fh,">$filename"
+            or croak wrap_mod("po4a::po",
+                              dgettext("po4a", "Can't write to %s: %s"),
+                              $filename, $!);
+    }
+
+    print $fh "".format_comment($self->{header_comment},"")
+        if defined($self->{header_comment}) && length($self->{header_comment});
+
+    print $fh "msgid \"\"\n";
+    print $fh "msgstr ".quote_text($self->{header})."\n\n";
+
+
+    my $buf_msgstr_plural; # USed to keep the first msgstr of plural forms
+    my $first=1;
+    foreach my $msgid ( sort { ($self->{po}{"$a"}{'pos'}) <=>
+                               ($self->{po}{"$b"}{'pos'})
+                             }  keys %{$self->{po}}) {
+        my $output="";
+
+        if ($first) {
+            $first=0;
+        } else {
+            $output .= "\n";
+        }
+
+        $output .= format_comment($self->{po}{$msgid}{'comment'},"")
+            if    defined($self->{po}{$msgid}{'comment'})
+               && length ($self->{po}{$msgid}{'comment'});
+        if (   defined($self->{po}{$msgid}{'automatic'})
+            && length ($self->{po}{$msgid}{'automatic'})) {
+            foreach my $comment (split(/\\n/,$self->{po}{$msgid}{'automatic'}))
+            {
+                $output .= format_comment($comment, ". ")
+            }
+        }
+        $output .= format_comment($self->{po}{$msgid}{'type'},". type: ")
+            if    defined($self->{po}{$msgid}{'type'})
+               && length ($self->{po}{$msgid}{'type'});
+        $output .= format_comment($self->{po}{$msgid}{'reference'},": ")
+            if    defined($self->{po}{$msgid}{'reference'})
+               && length ($self->{po}{$msgid}{'reference'});
+        $output .= "#, ". join(", ", sort split(/\s+/,$self->{po}{$msgid}{'flags'}))."\n"
+            if    defined($self->{po}{$msgid}{'flags'})
+               && length ($self->{po}{$msgid}{'flags'});
+
+        if (exists $self->{po}{$msgid}{'plural'}) {
+            if ($self->{po}{$msgid}{'plural'} == 0) {
+                if ($self->get_charset =~ /^utf-8$/i) {
+                    my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'});
+                    $msgid = Encode::decode_utf8($msgid);
+                    $output .= Encode::encode_utf8("msgid ".quote_text($msgid)."\n");
+                    $buf_msgstr_plural = Encode::encode_utf8("msgstr[0] ".quote_text($msgstr)."\n");
+                } else {
+                    $output = "msgid ".quote_text($msgid)."\n";
+                    $buf_msgstr_plural = "msgstr[0] ".quote_text($self->{po}{$msgid}{'msgstr'})."\n";
+                }
+            } elsif ($self->{po}{$msgid}{'plural'} == 1) {
+# TODO: there may be only one plural form
+                if ($self->get_charset =~ /^utf-8$/i) {
+                    my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'});
+                    $msgid = Encode::decode_utf8($msgid);
+                    $output = Encode::encode_utf8("msgid_plural ".quote_text($msgid)."\n");
+                    $output .= $buf_msgstr_plural;
+                    $output .= Encode::encode_utf8("msgstr[1] ".quote_text($msgstr)."\n");
+                    $buf_msgstr_plural = "";
+                } else {
+                    $output = "msgid_plural ".quote_text($msgid)."\n";
+                    $output .= $buf_msgstr_plural;
+                    $output .= "msgstr[1] ".quote_text($self->{po}{$msgid}{'msgstr'})."\n";
+                }
+            } else {
+                die wrap_msg(dgettext("po4a","Can't write PO files with more than two plural forms."));
+            }
+        } else {
+            if ($self->get_charset =~ /^utf-8$/i) {
+                my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'});
+                $msgid = Encode::decode_utf8($msgid);
+                $output .= Encode::encode_utf8("msgid ".quote_text($msgid)."\n");
+                $output .= Encode::encode_utf8("msgstr ".quote_text($msgstr)."\n");
+            } else {
+                $output .= "msgid ".quote_text($msgid)."\n";
+                $output .= "msgstr ".quote_text($self->{po}{$msgid}{'msgstr'})."\n";
+            }
+        }
+
+        print $fh $output;
+    }
+#    print STDERR "$fh";
+#    if ($filename ne '-') {
+#        close $fh
+#            or croak (sprintf(dgettext("po4a",
+#                                       "Can't close %s after writing: %s\n"),
+#                              $filename,$!));
+#    }
+}
+
+=item write_if_needed($$)
+
+Like write, but if the PO or POT file already exists, the object will be
+written in a temporary file which will be compared with the existing file
+to check that the update is needed (this avoids to change a POT just to
+update a line reference or the POT-Creation-Date field).
+
+=cut
+
+sub move_po_if_needed {
+    my ($new_po, $old_po, $backup) = (shift, shift, shift);
+    my $diff;
+
+    if (-e $old_po) {
+        my $diff_ignore = "-I'^#:' "
+                         ."-I'^\"POT-Creation-Date:' "
+                         ."-I'^\"PO-Revision-Date:'";
+        $diff = qx(diff -q $diff_ignore $old_po $new_po);
+        if ( $diff eq "" ) {
+            unlink $new_po
+                or die wrap_msg(dgettext("po4a","Can't unlink %s: %s."),
+                                $new_po, $!);
+            # touch the old PO
+            my ($atime, $mtime) = (time,time);
+            utime $atime, $mtime, $old_po;
+        } else {
+            if ($backup) {
+                copy $old_po, $old_po."~"
+                    or die wrap_msg(dgettext("po4a","Can't copy %s to %s: %s."),
+                                    $old_po, $old_po."~", $!);
+            } else {
+            }
+            move $new_po, $old_po
+                or die wrap_msg(dgettext("po4a","Can't move %s to %s: %s."),
+                                $new_po, $old_po, $!);
+        }
+    } else {
+        move $new_po, $old_po
+            or die wrap_msg(dgettext("po4a","Can't move %s to %s: %s."),
+                            $new_po, $old_po, $!);
+    }
+}
+
+sub write_if_needed {
+    my $self=shift;
+    my $filename=shift
+        or croak dgettext("po4a","Can't write to a file without filename")."\n";
+
+    if (-e $filename) {
+        my ($tmp_filename);
+        (undef,$tmp_filename)=File::Temp->tempfile($filename."XXXX",
+                                                   DIR    => "/tmp",
+                                                   OPEN   => 0,
+                                                   UNLINK => 0);
+        $self->write($tmp_filename);
+        move_po_if_needed($tmp_filename, $filename);
+    } else {
+        $self->write($filename);
+    }
+}
+
+=item gettextize($$)
+
+This function produces one translated message catalog from two catalogs, an
+original and a translation. This process is described in L<po4a(7)|po4a.7>,
+section I<Gettextization: how does it work?>.
+
+=cut
+
+sub gettextize {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my ($poorig,$potrans)=(shift,shift);
+
+    my $pores=Locale::Po4a::Po->new();
+
+    my $please_fail = 0;
+    my $toobad = dgettext("po4a",
+        "\nThe gettextization failed (once again). Don't give up, ".
+        "gettextizing is a subtle art, but this is only needed once ".
+        "to convert a project to the gorgeous luxus offered by po4a ".
+        "to translators.".
+        "\nPlease refer to the po4a(7) documentation, the section ".
+        "\"HOWTO convert a pre-existing translation to po4a?\" ".
+        "contains several hints to help you in your task");
+
+    # Don't fail right now when the entry count does not match. Instead, give
+    # it a try so that the user can see where we fail (which is probably where
+    # the problem is).
+    if ($poorig->count_entries_doc() > $potrans->count_entries_doc()) {
+        warn wrap_mod("po4a gettextize", dgettext("po4a",
+            "Original has more strings than the translation (%d>%d). ".
+            "Please fix it by editing the translated version to add ".
+            "some dummy entry."),
+                      $poorig->count_entries_doc(),
+                      $potrans->count_entries_doc());
+        $please_fail = 1;
+    } elsif ($poorig->count_entries_doc() < $potrans->count_entries_doc()) {
+        warn wrap_mod("po4a gettextize", dgettext("po4a",
+            "Original has less strings than the translation (%d<%d). ".
+            "Please fix it by removing the extra entry from the ".
+            "translated file. You may need an addendum (cf po4a(7)) ".
+            "to reput the chunk in place after gettextization. A ".
+            "possible cause is that a text duplicated in the original ".
+            "is not translated the same way each time. Remove one of ".
+            "the translations, and you're fine."),
+                      $poorig->count_entries_doc(),
+                      $potrans->count_entries_doc());
+        $please_fail = 1;
+    }
+
+    if ( $poorig->get_charset =~ /^utf-8$/i ) {
+        $potrans->to_utf8;
+        $pores->set_charset("utf-8");
+    } else {
+        if ($potrans->get_charset eq "CHARSET") {
+            $pores->set_charset("ascii");
+        } else {
+            $pores->set_charset($potrans->get_charset);
+        }
+    }
+    print "Po character sets:\n".
+        "  original=".$poorig->get_charset."\n".
+        "  translated=".$potrans->get_charset."\n".
+        "  result=".$pores->get_charset."\n"
+            if $debug{'encoding'};
+
+    for (my ($o,$t)=(0,0) ;
+         $o<$poorig->count_entries_doc() && $t<$potrans->count_entries_doc();
+         $o++,$t++) {
+        #
+        # Extract some informations
+
+        my ($orig,$trans)=($poorig->msgid_doc($o),$potrans->msgid_doc($t));
+#       print STDERR "Matches [[$orig]]<<$trans>>\n";
+
+        my ($reforig,$reftrans)=($poorig->{po}{$orig}{'reference'},
+                                 $potrans->{po}{$trans}{'reference'});
+        my ($typeorig,$typetrans)=($poorig->{po}{$orig}{'type'},
+                                   $potrans->{po}{$trans}{'type'});
+
+        #
+        # Make sure the type of both string exist
+        #
+        die wrap_mod("po4a gettextize",
+                     "Internal error: type of original string number %s ".
+                     "isn't provided", $o)
+            if ($typeorig eq '');
+
+        die wrap_mod("po4a gettextize",
+                     "Internal error: type of translated string number %s ".
+                     "isn't provided", $o)
+            if ($typetrans eq '');
+
+        #
+        # Make sure both type are the same
+        #
+        if ($typeorig ne $typetrans){
+            $pores->write("gettextization.failed.po");
+            die wrap_msg(dgettext("po4a",
+                         "po4a gettextization: Structure disparity between ".
+                         "original and translated files:\n".
+                         "msgid (at %s) is of type '%s' while\n".
+                         "msgstr (at %s) is of type '%s'.\n".
+                         "Original text: %s\n".
+                         "Translated text: %s\n".
+                         "(result so far dumped to gettextization.failed.po)").
+                         "%s",
+                         $reforig, $typeorig,
+                         $reftrans, $typetrans,
+                         $orig,
+                         $trans,
+                         $toobad);
+        }
+
+        #
+        # Push the entry
+        #
+        my $flags;
+        if (defined $poorig->{po}{$orig}{'flags'}) {
+            $flags = $poorig->{po}{$orig}{'flags'}." fuzzy";
+        } else {
+            $flags = "fuzzy";
+        }
+        $pores->push_raw('msgid'     => $orig,
+                         'msgstr'    => $trans,
+                         'flags'     => $flags,
+                         'type'      => $typeorig,
+                         'reference' => $reforig,
+                         'conflict'  => 1,
+                         'transref'  => $potrans->{po}{$trans}{'reference'})
+            unless (defined($pores->{po}{$orig})
+                    and ($pores->{po}{$orig}{'msgstr'} eq $trans))
+        # FIXME: maybe we should be smarter about what reference should be
+        #        sent to push_raw.
+    }
+
+    # make sure we return a useful error message when entry count differ
+    die "$toobad\n" if $please_fail;
+
+    return $pores;
+}
+
+=item filter($)
+
+This function extracts a catalog from an existing one. Only the entries having
+a reference in the given file will be placed in the resulting catalog.
+
+This function parses its argument, converts it to a perl function definition,
+eval this definition and filter the fields for which this function returns
+true.
+
+I love perl sometimes ;)
+
+=cut
+
+sub filter {
+    my $self=shift;
+    our $filter=shift;
+
+    my $res;
+    $res = Locale::Po4a::Po->new();
+
+    # Parse the filter
+    our $code="sub apply { return ";
+    our $pos=0;
+    our $length = length $filter;
+
+    # explode chars to parts. How to subscript a string in Perl?
+    our @filter = split(//,$filter);
+
+    sub gloups {
+        my $fmt=shift;
+        my $space = "";
+        for (1..$pos){
+            $space .= ' ';
+        }
+        die wrap_msg("$fmt\n$filter\n$space^ HERE");
+    }
+    sub showmethecode {
+        return unless $debug{'filter'};
+        my $fmt=shift;
+        my $space="";
+        for (1..$pos){
+            $space .= ' ';
+        }
+        print STDERR "$filter\n$space^ $fmt\n";#"$code\n";
+    }
+
+    # I dream of a lex in perl :-/
+    sub parse_expression {
+        showmethecode("Begin expression")
+            if $debug{'filter'};
+
+        gloups("Begin of expression expected, got '%s'",$filter[$pos])
+            unless ($filter[$pos] eq '(');
+        $pos ++; # pass the '('
+        if ($filter[$pos] eq '&') {
+            # AND
+            $pos++;
+            showmethecode("Begin of AND")
+                if $debug{'filter'};
+            $code .= "(";
+            while (1) {
+                gloups ("Unfinished AND statement.")
+                    if ($pos == $length);
+                parse_expression();
+                if ($filter[$pos] eq '(') {
+                    $code .= " && ";
+                } elsif ($filter[$pos] eq ')') {
+                    last; # do not eat that char
+                } else {
+                    gloups("End of AND or begin of sub-expression expected, got '%s'", $filter[$pos]);
+                }
+            }
+            $code .= ")";
+        } elsif ($filter[$pos] eq '|') {
+            # OR
+            $pos++;
+            $code .= "(";
+            while (1) {
+                gloups("Unfinished OR statement.")
+                    if ($pos == $length);
+                parse_expression();
+                if ($filter[$pos] eq '(') {
+                    $code .= " || ";
+                } elsif ($filter[$pos] eq ')') {
+                    last; # do not eat that char
+                } else {
+                    gloups("End of OR or begin of sub-expression expected, got '%s'",$filter[$pos]);
+                }
+            }
+            $code .= ")";
+        } elsif ($filter[$pos] eq '!') {
+            # NOT
+            $pos++;
+            $code .= "(!";
+            gloups("Missing sub-expression in NOT statement.")
+                if ($pos == $length);
+            parse_expression();
+            $code .= ")";
+        } else {
+            # must be an equal. Let's get field and argument
+            my ($field,$arg,$done);
+            $field = substr($filter,$pos);
+            gloups("EQ statement contains no '=' or invalid field name")
+                unless ($field =~ /([a-z]*)=/i);
+            $field = lc($1);
+            $pos += (length $field) + 1;
+
+            # check that we've got a valid field name,
+            # and the number it referes to
+            # DO NOT CHANGE THE ORDER
+            my @names=qw(msgid msgstr reference flags comment automatic);
+            my $fieldpos;
+            for ($fieldpos = 0;
+                 $fieldpos < scalar @names && $field ne $names[$fieldpos];
+                 $fieldpos++) {}
+            gloups("Invalid field name: %s",$field)
+                if $fieldpos == scalar @names; # not found
+
+            # Now, get the argument value. It has to be between quotes,
+            # which can be escaped
+            # We point right on the first char of the argument
+            # (first quote already eaten)
+            my $escaped = 0;
+            my $quoted = 0;
+            if ($filter[$pos] eq '"') {
+                $pos++;
+                $quoted = 1;
+            }
+            showmethecode(($quoted?"Quoted":"Unquoted")." argument of field '$field'")
+                if $debug{'filter'};
+
+            while (!$done) {
+                gloups("Unfinished EQ argument.")
+                    if ($pos == $length);
+
+                if ($quoted) {
+                    if ($filter[$pos] eq '\\') {
+                        if ($escaped) {
+                            $arg .= '\\';
+                            $escaped = 0;
+                        } else {
+                            $escaped = 1;
+                        }
+                    } elsif ($escaped) {
+                        if ($filter[$pos] eq '"') {
+                            $arg .= '"';
+                            $escaped = 0;
+                        } else {
+                            gloups("Invalid escape sequence in argument: '\\%s'",$filter[$pos]);
+                        }
+                    } else {
+                        if ($filter[$pos] eq '"') {
+                            $done = 1;
+                        } else {
+                            $arg .= $filter[$pos];
+                        }
+                    }
+                } else {
+                    if ($filter[$pos] eq ')') {
+                        # counter the next ++ since we don't want to eat
+                        # this char
+                        $pos--;
+                        $done = 1;
+                    } else {
+                        $arg .= $filter[$pos];
+                    }
+                }
+                $pos++;
+            }
+            # and now, add the code to check this equality
+            $code .= "(\$_[$fieldpos] =~ m/$arg/)";
+
+        }
+        showmethecode("End of expression")
+            if $debug{'filter'};
+        gloups("Unfinished statement.")
+            if ($pos == $length);
+        gloups("End of expression expected, got '%s'",$filter[$pos])
+            unless ($filter[$pos] eq ')');
+        $pos++;
+    }
+    # And now, launch the beast, finish the function and use eval
+    # to construct this function.
+    # Ok, the lack of lexer is a fair price for the eval ;)
+    parse_expression();
+    gloups("Garbage at the end of the expression")
+        if ($pos != $length);
+    $code .= "; }";
+    print STDERR "CODE = $code\n"
+        if $debug{'filter'};
+    eval $code;
+    die wrap_mod("po4a::po", dgettext("po4a", "Eval failure: %s"), $@)
+        if $@;
+
+    for (my $cpt=(0) ;
+         $cpt<$self->count_entries();
+         $cpt++) {
+
+        my ($msgid,$ref,$msgstr,$flags,$type,$comment,$automatic);
+
+        $msgid = $self->msgid($cpt);
+        $ref=$self->{po}{$msgid}{'reference'};
+
+        $msgstr= $self->{po}{$msgid}{'msgstr'};
+        $flags =  $self->{po}{$msgid}{'flags'};
+        $type = $self->{po}{$msgid}{'type'};
+        $comment = $self->{po}{$msgid}{'comment'};
+        $automatic = $self->{po}{$msgid}{'automatic'};
+
+        # DO NOT CHANGE THE ORDER
+        $res->push_raw('msgid' => $msgid,
+                       'msgstr' => $msgstr,
+                       'flags' => $flags,
+                       'type'  => $type,
+                       'reference' => $ref,
+                       'comment' => $comment,
+                       'automatic' => $automatic)
+               if (apply($msgid,$msgstr,$ref,$flags,$comment,$automatic));
+    }
+    # delete the apply subroutine
+    # otherwise it will be redefined.
+    undef &apply;
+    return $res;
+}
+
+=item to_utf8()
+
+Recodes to utf-8 the po's msgstrs. Does nothing if the charset is not
+specified in the po file ("CHARSET" value), or if it's already utf-8 or
+ascii.
+
+=cut
+
+sub to_utf8 {
+    my $this = shift;
+    my $charset = $this->get_charset();
+
+    unless ($charset eq "CHARSET" or
+            $charset =~ /^ascii$/i or
+            $charset =~ /^utf-8$/i) {
+        foreach my $msgid ( keys %{$this->{po}} ) {
+            Encode::from_to($this->{po}{$msgid}{'msgstr'}, $charset, "utf-8");
+        }
+        $this->set_charset("utf-8");
+    }
+}
+
+=back
+
+=head1 Functions to use a message catalog for translations
+
+=over 4
+
+=item gettext($%)
+
+Request the translation of the string given as argument in the current catalog.
+The function returns the original (untranslated) string if the string was not
+found.
+
+After the string to translate, you can pass a hash of extra
+arguments. Here are the valid entries:
+
+=over
+
+=item wrap
+
+boolean indicating whether we can consider that whitespaces in string are
+not important. If yes, the function canonizes the string before looking for
+a translation, and wraps the result.
+
+=item wrapcol
+
+The column at which we should wrap (default: 76).
+
+=back
+
+=cut
+
+sub gettext {
+    my $self=shift;
+    my $text=shift;
+    my (%opt)=@_;
+    my $res;
+
+    return "" unless defined($text) && length($text); # Avoid returning the header.
+    my $validoption="reference wrap wrapcol";
+    my %validoption;
+
+    map { $validoption{$_}=1 } (split(/ /,$validoption));
+    foreach (keys %opt) {
+        Carp::confess "internal error:  unknown arg $_.\n".
+                      "Here are the valid options: $validoption.\n"
+            unless $validoption{$_};
+    }
+
+    $text=canonize($text)
+        if ($opt{'wrap'});
+
+    my $esc_text=escape_text($text);
+
+    $self->{gettextqueries}++;
+
+    if (    defined $self->{po}{$esc_text}
+        and defined $self->{po}{$esc_text}{'msgstr'}
+        and length $self->{po}{$esc_text}{'msgstr'}
+        and (   not defined $self->{po}{$esc_text}{'flags'}
+             or $self->{po}{$esc_text}{'flags'} !~ /fuzzy/)) {
+
+        $self->{gettexthits}++;
+        $res = unescape_text($self->{po}{$esc_text}{'msgstr'});
+        if (defined $self->{po}{$esc_text}{'plural'}) {
+            if ($self->{po}{$esc_text}{'plural'} eq "0") {
+                warn wrap_mod("po4a gettextize", dgettext("po4a",
+                              "'%s' is the singular form of a message, ".
+                              "po4a will use the msgstr[0] translation (%s)."),
+                              $esc_text, $res);
+            } else {
+                warn wrap_mod("po4a gettextize", dgettext("po4a",
+                              "'%s' is the plural form of a message, ".
+                              "po4a will use the msgstr[1] translation (%s)."),
+                              $esc_text, $res);
+            }
+        }
+    } else {
+        $res = $text;
+    }
+
+    if ($opt{'wrap'}) {
+        if ($self->get_charset =~ /^utf-8$/i) {
+            $res=Encode::decode_utf8($res);
+            $res=wrap ($res, $opt{'wrapcol'} || 76);
+            $res=Encode::encode_utf8($res);
+        } else {
+            $res=wrap ($res, $opt{'wrapcol'} || 76);
+        }
+    }
+#    print STDERR "Gettext >>>$text<<<(escaped=$esc_text)=[[[$res]]]\n\n";
+    return $res;
+}
+
+=item stats_get()
+
+Returns statistics about the hit ratio of gettext since the last time that
+stats_clear() was called. Please note that it's not the same
+statistics than the one printed by msgfmt --statistic. Here, it's statistics
+about recent usage of the po file, while msgfmt reports the status of the
+file.  Example of use:
+
+    [some use of the po file to translate stuff]
+
+    ($percent,$hit,$queries) = $pofile->stats_get();
+    print "So far, we found translations for $percent\%  ($hit of $queries) of strings.\n";
+
+=cut
+
+sub stats_get() {
+    my $self=shift;
+    my ($h,$q)=($self->{gettexthits},$self->{gettextqueries});
+    my $p = ($q == 0 ? 100 : int($h/$q*10000)/100);
+
+#    $p =~ s/\.00//;
+#    $p =~ s/(\..)0/$1/;
+
+    return ( $p,$h,$q );
+}
+
+=item stats_clear()
+
+Clears the statistics about gettext hits.
+
+=cut
+
+sub stats_clear {
+    my $self = shift;
+    $self->{gettextqueries} = 0;
+    $self->{gettexthits} = 0;
+}
+
+=back
+
+=head1 Functions to build a message catalog
+
+=over 4
+
+=item push(%)
+
+Push a new entry at the end of the current catalog. The arguments should
+form a hash table. The valid keys are:
+
+=over 4
+
+=item msgid
+
+the string in original language.
+
+=item msgstr
+
+the translation.
+
+=item reference
+
+an indication of where this string was found. Example: file.c:46 (meaning
+in 'file.c' at line 46). It can be a space-separated list in case of
+multiple occurrences.
+
+=item comment
+
+a comment added here manually (by the translators). The format here is free.
+
+=item automatic
+
+a comment which was automatically added by the string extraction
+program. See the I<--add-comments> option of the B<xgettext> program for
+more information.
+
+=item flags
+
+space-separated list of all defined flags for this entry.
+
+Valid flags are: c-text, python-text, lisp-text, elisp-text, librep-text,
+smalltalk-text, java-text, awk-text, object-pascal-text, ycp-text,
+tcl-text, wrap, no-wrap and fuzzy.
+
+See the gettext documentation for their meaning.
+
+=item type
+
+This is mostly an internal argument: it is used while gettextizing
+documents. The idea here is to parse both the original and the translation
+into a po object, and merge them, using one's msgid as msgid and the
+other's msgid as msgstr. To make sure that things get ok, each msgid in po
+objects are given a type, based on their structure (like "chapt", "sect1",
+"p" and so on in docbook). If the types of strings are not the same, that
+means that both files do not share the same structure, and the process
+reports an error.
+
+This information is written as automatic comment in the po file since this
+gives to translators some context about the strings to translate.
+
+=item wrap
+
+boolean indicating whether whitespaces can be mangled in cosmetic
+reformattings. If true, the string is canonized before use.
+
+This information is written to the po file using the 'wrap' or 'no-wrap' flag.
+
+=item wrapcol
+
+The column at which we should wrap (default: 76).
+
+This information is not written to the po file.
+
+=back
+
+=cut
+
+sub push {
+    my $self=shift;
+    my %entry=@_;
+
+    my $validoption="wrap wrapcol type msgid msgstr automatic flags reference";
+    my %validoption;
+
+    map { $validoption{$_}=1 } (split(/ /,$validoption));
+    foreach (keys %entry) {
+        Carp::confess "internal error:  unknown arg $_.\n".
+                      "Here are the valid options: $validoption.\n"
+            unless $validoption{$_};
+    }
+
+    unless ($entry{'wrap'}) {
+        $entry{'flags'} .= " no-wrap";
+    }
+    if (defined ($entry{'msgid'})) {
+        $entry{'msgid'} = canonize($entry{'msgid'})
+            if ($entry{'wrap'});
+
+        $entry{'msgid'} = escape_text($entry{'msgid'});
+    }
+    if (defined ($entry{'msgstr'})) {
+        $entry{'msgstr'} = canonize($entry{'msgstr'})
+            if ($entry{'wrap'});
+
+        $entry{'msgstr'} = escape_text($entry{'msgstr'});
+    }
+
+    $self->push_raw(%entry);
+}
+
+# The same as push(), but assuming that msgid and msgstr are already escaped
+sub push_raw {
+    my $self=shift;
+    my %entry=@_;
+    my ($msgid,$msgstr,$reference,$comment,$automatic,$flags,$type,$transref)=
+        ($entry{'msgid'},$entry{'msgstr'},
+         $entry{'reference'},$entry{'comment'},$entry{'automatic'},
+         $entry{'flags'},$entry{'type'},$entry{'transref'});
+    my $keep_conflict = $entry{'conflict'};
+
+#    print STDERR "Push_raw\n";
+#    print STDERR " msgid=>>>$msgid<<<\n" if $msgid;
+#    print STDERR " msgstr=[[[$msgstr]]]\n" if $msgstr;
+#    Carp::cluck " flags=$flags\n" if $flags;
+
+    return unless defined($entry{'msgid'});
+
+    #no msgid => header definition
+    unless (length($entry{'msgid'})) {
+#       if (defined($self->{header}) && $self->{header} =~ /\S/) {
+#           warn dgettext("po4a","Redefinition of the header. ".
+#                                "The old one will be discarded\n");
+#       } FIXME: do that iff the header isn't the default one.
+        $self->{header}=$msgstr;
+        $self->{header_comment}=$comment;
+        my $charset = $self->get_charset;
+        if ($charset ne "CHARSET") {
+            $self->{encoder}=find_encoding($charset);
+        } else {
+            $self->{encoder}=find_encoding("ascii");
+        }
+        return;
+    }
+
+    if ($self->{options}{'porefs'} eq "none") {
+        $reference = "";
+    } elsif ($self->{options}{'porefs'} eq "noline") {
+        $reference =~ s/:[0-9]*/:1/g;
+    }
+
+    if (defined($self->{po}{$msgid})) {
+        warn wrap_mod("po4a::po",
+                      dgettext("po4a","msgid defined twice: %s"),
+                      $msgid)
+            if (0); # FIXME: put a verbose stuff
+        if (    defined $msgstr
+            and defined $self->{po}{$msgid}{'msgstr'}
+            and $self->{po}{$msgid}{'msgstr'} ne $msgstr) {
+            my $txt=quote_text($msgid);
+            my ($first,$second)=
+                (format_comment(". ",$self->{po}{$msgid}{'reference'}).
+                 quote_text($self->{po}{$msgid}{'msgstr'}),
+
+                 format_comment(". ",$reference).
+                 quote_text($msgstr));
+
+            if ($keep_conflict) {
+                if ($self->{po}{$msgid}{'msgstr'} =~ m/^#-#-#-#-#  .*  #-#-#-#-#\\n/s) {
+                    $msgstr = $self->{po}{$msgid}{'msgstr'}.
+                              "\\n#-#-#-#-#  $transref  #-#-#-#-#\\n".
+                              $msgstr;
+                } else {
+                    $msgstr = "#-#-#-#-#  ".
+                              $self->{po}{$msgid}{'transref'}.
+                              "  #-#-#-#-#\\n".
+                              $self->{po}{$msgid}{'msgstr'}."\\n".
+                              "#-#-#-#-#  $transref  #-#-#-#-#\\n".
+                              $msgstr;
+                }
+                # Every msgid will have the same list of references.
+                # Only keep the last list.
+                $self->{po}{$msgid}{'reference'} = "";
+            } else {
+            warn wrap_msg(dgettext("po4a",
+                                   "Translations don't match for:\n".
+                                   "%s\n".
+                                   "-->First translation:\n".
+                                   "%s\n".
+                                   " Second translation:\n".
+                                   "%s\n".
+                                   " Old translation discarded."),
+                          $txt,$first,$second);
+            }
+        }
+    }
+    if (defined $transref) {
+        $self->{po}{$msgid}{'transref'} = $transref;
+    }
+    if (defined $reference) {
+        if (defined $self->{po}{$msgid}{'reference'}) {
+            $self->{po}{$msgid}{'reference'} .= " ".$reference;
+        } else {
+            $self->{po}{$msgid}{'reference'} = $reference;
+        }
+    }
+    $self->{po}{$msgid}{'msgstr'} = $msgstr;
+    $self->{po}{$msgid}{'comment'} = $comment;
+    $self->{po}{$msgid}{'automatic'} = $automatic;
+    if (defined($self->{po}{$msgid}{'pos_doc'})) {
+        $self->{po}{$msgid}{'pos_doc'} .= " ".$self->{count_doc}++;
+    } else {
+        $self->{po}{$msgid}{'pos_doc'}  = $self->{count_doc}++;
+    }
+    unless (defined($self->{po}{$msgid}{'pos'})) {
+        $self->{po}{$msgid}{'pos'} = $self->{count}++;
+    }
+    $self->{po}{$msgid}{'type'} = $type;
+    $self->{po}{$msgid}{'plural'} = $entry{'plural'}
+        if defined $entry{'plural'};
+
+    if (defined($flags)) {
+        $flags = " $flags ";
+        $flags =~ s/,/ /g;
+        foreach my $flag (@known_flags) {
+            if ($flags =~ /\s$flag\s/) { # if flag to be set
+                unless (   defined($self->{po}{$msgid}{'flags'})
+                        && $self->{po}{$msgid}{'flags'} =~ /\b$flag\b/) {
+                    # flag not already set
+                    if (defined $self->{po}{$msgid}{'flags'}) {
+                        $self->{po}{$msgid}{'flags'} .= " ".$flag;
+                    } else {
+                        $self->{po}{$msgid}{'flags'} = $flag;
+                    }
+                }
+            }
+        }
+    }
+#    print STDERR "stored ((($msgid)))=>(((".$self->{po}{$msgid}{'msgstr'}.")))\n\n";
+
+}
+
+=back
+
+=head1 Miscellaneous functions
+
+=over 4
+
+=item count_entries()
+
+Returns the number of entries in the catalog (without the header).
+
+=cut
+
+sub count_entries($) {
+    my $self=shift;
+    return $self->{count};
+}
+
+=item count_entries_doc()
+
+Returns the number of entries in document. If a string appears multiple times
+in the document, it will be counted multiple times
+
+=cut
+
+sub count_entries_doc($) {
+    my $self=shift;
+    return $self->{count_doc};
+}
+
+=item msgid($)
+
+Returns the msgid of the given number.
+
+=cut
+
+sub msgid($$) {
+    my $self=shift;
+    my $num=shift;
+
+    foreach my $msgid ( keys %{$self->{po}} ) {
+        return $msgid if ($self->{po}{$msgid}{'pos'} eq $num);
+    }
+    return undef;
+}
+
+=item msgid_doc($)
+
+Returns the msgid with the given position in the document.
+
+=cut
+
+sub msgid_doc($$) {
+    my $self=shift;
+    my $num=shift;
+
+    foreach my $msgid ( keys %{$self->{po}} ) {
+        foreach my $pos (split / /, $self->{po}{$msgid}{'pos_doc'}) {
+            return $msgid if ($pos eq $num);
+        }
+    }
+    return undef;
+}
+
+=item get_charset()
+
+Returns the character set specified in the po header. If it hasn't been
+set, it will return "CHARSET".
+
+=cut
+
+sub get_charset() {
+    my $self=shift;
+
+    $self->{header} =~ /charset=(.*?)[\s\\]/;
+
+    if (defined $1) {
+        return $1;
+    } else {
+        return "CHARSET";
+    }
+}
+
+=item set_charset($)
+
+This sets the character set of the po header to the value specified in its
+first argument. If you never call this function (and no file with a specified
+character set is read), the default value is left to "CHARSET". This value
+doesn't change the behavior of this module, it's just used to fill that field
+in the header, and to return it in get_charset().
+
+=cut
+
+sub set_charset() {
+    my $self=shift;
+
+    my ($newchar,$oldchar);
+    $newchar = shift;
+    $oldchar = $self->get_charset();
+
+    $self->{header} =~ s/$oldchar/$newchar/;
+    $self->{encoder}=find_encoding($newchar);
+}
+
+#----[ helper functions ]---------------------------------------------------
+
+# transforme the string from its po file representation to the form which
+#   should be used to print it
+sub unescape_text {
+    my $text = shift;
+
+    print STDERR "\nunescape [$text]====" if $debug{'escape'};
+    $text = join("",split(/\n/,$text));
+    $text =~ s/\\"/"/g;
+    # unescape newlines
+    #   NOTE on \G:
+    #   The following regular expression introduce newlines.
+    #   Thus, ^ doesn't match all beginnings of lines.
+    #   \G is a zero-width assertion that matches the position
+    #   of the previous substitution with s///g. As every
+    #   substitution ends by a newline, it always matches a
+    #   position just after a newline.
+    $text =~ s/(           # $1:
+                (\G|[^\\]) #    beginning of the line or any char
+                           #    different from '\'
+                (\\\\)*    #    followed by any even number of '\'
+               )\\n        # and followed by an escaped newline
+              /$1\n/sgx;   # single string, match globally, allow comments
+    # unescape tabulations
+    $text =~ s/(          # $1:
+                (\G|[^\\])#    beginning of the line or any char
+                          #    different from '\'
+                (\\\\)*   #    followed by any even number of '\'
+               )\\t       # and followed by an escaped tabulation
+              /$1\t/mgx;  # multilines string, match globally, allow comments
+    # and unescape the escape character
+    $text =~ s/\\\\/\\/g;
+    print STDERR ">$text<\n" if $debug{'escape'};
+
+    return $text;
+}
+
+# transform the string to its representation as it should be written in po
+# files
+sub escape_text {
+    my $text = shift;
+
+    print STDERR "\nescape [$text]====" if $debug{'escape'};
+    $text =~ s/\\/\\\\/g;
+    $text =~ s/"/\\"/g;
+    $text =~ s/\n/\\n/g;
+    $text =~ s/\t/\\t/g;
+    print STDERR ">$text<\n" if $debug{'escape'};
+
+    return $text;
+}
+
+# put quotes around the string on each lines (without escaping it)
+# It does also normalize the text (ie, make sure its representation is wraped
+#   on the 80th char, but without changing the meaning of the string)
+sub quote_text {
+    my $string = shift;
+
+    return '""' unless defined($string) && length($string);
+
+    print STDERR "\nquote [$string]====" if $debug{'quote'};
+    # break lines on newlines, if any
+    # see unescape_text for an explanation on \G
+    $string =~ s/(           # $1:
+                  (\G|[^\\]) #    beginning of the line or any char
+                             #    different from '\'
+                  (\\\\)*    #    followed by any even number of '\'
+                 \\n)        # and followed by an escaped newline
+                /$1\n/sgx;   # single string, match globally, allow comments
+    $string = wrap($string);
+    my @string = split(/\n/,$string);
+    $string = join ("\"\n\"",@string);
+    $string = "\"$string\"";
+    if (scalar @string > 1 && $string[0] ne '') {
+        $string = "\"\"\n".$string;
+    }
+
+    print STDERR ">$string<\n" if $debug{'quote'};
+    return $string;
+}
+
+# undo the work of the quote_text function
+sub unquote_text {
+    my $string = shift;
+    print STDERR "\nunquote [$string]====" if $debug{'quote'};
+    $string =~ s/^""\\n//s;
+    $string =~ s/^"(.*)"$/$1/s;
+    $string =~ s/"\n"//gm;
+    # Note: an even number of '\' could precede \\n, but I could not build a
+    # document to test this
+    $string =~ s/([^\\])\\n\n/$1!!DUMMYPOPM!!/gm;
+    $string =~ s|!!DUMMYPOPM!!|\\n|gm;
+    print STDERR ">$string<\n" if $debug{'quote'};
+    return $string;
+}
+
+# canonize the string: write it on only one line, changing consecutive
+# whitespace to only one space.
+# Warning, it changes the string and should only be called if the string is
+# plain text
+sub canonize {
+    my $text=shift;
+    print STDERR "\ncanonize [$text]====" if $debug{'canonize'};
+    $text =~ s/^ *//s;
+    $text =~ s/^[ \t]+/  /gm;
+    # if ($text eq "\n"), it messed up the first string (header)
+    $text =~ s/\n/  /gm if ($text ne "\n");
+    $text =~ s/([.)])  +/$1  /gm;
+    $text =~ s/([^.)])  */$1 /gm;
+    $text =~ s/ *$//s;
+    print STDERR ">$text<\n" if $debug{'canonize'};
+    return $text;
+}
+
+# wraps the string. We don't use Text::Wrap since it mangles whitespace at
+# the end of splited line
+sub wrap {
+    my $text=shift;
+    return "0" if ($text eq '0');
+    my $col=shift || 76;
+    my @lines=split(/\n/,"$text");
+    my $res="";
+    my $first=1;
+    while (defined(my $line=shift @lines)) {
+        if ($first && length($line) > $col - 10) {
+            unshift @lines,$line;
+            $first=0;
+            next;
+        }
+        if (length($line) > $col) {
+            my $pos=rindex($line," ",$col);
+            while (substr($line,$pos-1,1) eq '.' && $pos != -1) {
+                $pos=rindex($line," ",$pos-1);
+            }
+            if ($pos == -1) {
+                # There are no spaces in the first $col chars, pick-up the
+                # first space
+                $pos = index($line," ");
+            }
+            if ($pos != -1) {
+                my $end=substr($line,$pos+1);
+                $line=substr($line,0,$pos+1);
+                if ($end =~ s/^( +)//) {
+                    $line .= $1;
+                }
+                unshift @lines,$end;
+            }
+        }
+        $first=0;
+        $res.="$line\n";
+    }
+    # Restore the original trailing spaces
+    $res =~ s/\s+$//s;
+    if ($text =~ m/(\s+)$/s) {
+        $res .= $1;
+    }
+    return $res;
+}
+
+# outputs properly a '# ... ' line to be put in the po file
+sub format_comment {
+    my $comment=shift;
+    my $char=shift;
+    my $result = "#". $char . $comment;
+    $result =~ s/\n/\n#$char/gs;
+    $result =~ s/^#$char$/#/gm;
+    $result .= "\n";
+    return $result;
+}
+
+
+1;
+__END__
+
+=back
+
+=head1 AUTHORS
+
+ Denis Barbier <barbier@linuxfr.org>
+ Martin Quinson (mquinson#debian.org)
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/lib/Locale/Po4a/TransTractor.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,1100 @@
+#!/usr/bin/perl -w
+
+require Exporter;
+
+package Locale::Po4a::TransTractor;
+use DynaLoader;
+
+use 5.006;
+use strict;
+use warnings;
+
+use subs qw(makespace);
+use vars qw($VERSION @ISA @EXPORT);
+$VERSION="0.36";
+@ISA = qw(DynaLoader);
+@EXPORT = qw(new process translate 
+             read write readpo writepo
+             getpoout setpoout);
+
+# Try to use a C extension if present.
+eval("bootstrap Locale::Po4a::TransTractor $VERSION");
+
+use Carp qw(croak);
+use Locale::Po4a::Po;
+use Locale::Po4a::Common;
+
+use File::Path; # mkdir before write
+
+use Encode;
+use Encode::Guess;
+
+=head1 NAME
+
+Locale::Po4a::TransTractor - Generic trans(lator ex)tractor.
+
+=head1 DESCRIPTION
+
+The po4a (po for anything) project goal is to ease translations (and more
+interestingly, the maintenance of translations) using gettext tools on
+areas where they were not expected like documentation.
+
+This class is the ancestor of every po4a parsers used to parse a document to
+search translatable strings, extract them to a po file and replace them by
+their translation in the output document. 
+
+More formally, it takes the following arguments as input:
+
+=over 2
+
+=item -
+
+a document to translate ;
+
+=item -
+
+a po file containing the translations to use.
+
+=back
+
+As output, it produces:
+
+=over 2
+
+=item -
+
+another po file, resulting of the extraction of translatable strings from
+the input document ;
+
+=item -
+
+a translated document, with the same structure than the one in input, but
+with all translatable strings replaced with the translations found in the
+po file provided in input.
+
+=back
+
+Here is a graphical representation of this:
+
+   Input document --\                             /---> Output document
+                     \                           /       (translated)
+                      +-> parse() function -----+
+                     /                           \
+   Input po --------/                             \---> Output po
+                                                         (extracted)
+
+=head1 FUNCTIONS YOUR PARSER SHOULD OVERRIDE
+
+=over 4
+
+=item parse()
+
+This is where all the work takes place: the parsing of input documents, the
+generation of output, and the extraction of the translatable strings. This
+is pretty simple using the provided functions presented in the section
+"INTERNAL FUNCTIONS" below. See also the synopsis, which present an
+example.
+
+This function is called by the process() function bellow, but if you choose
+to use the new() function, and to add content manually to your document,
+you will have to call this function yourself.
+
+=item docheader()
+
+This function returns the header we should add to the produced document,
+quoted properly to be a comment in the target language.  See the section
+"Educating developers about translations", from L<po4a(7)|po4a.7>, for what
+it is good for.
+
+=back
+
+=cut
+
+sub docheader {}
+
+sub parse {}
+
+=head1 SYNOPSIS
+
+The following example parses a list of paragraphs beginning with "<p>". For the sake
+of simplicity, we assume that the document is well formatted, i.e. that '<p>'
+tags are the only tags present, and that this tag is at the very beginning
+of each paragraph.
+
+ sub parse {
+   my $self = shift;
+
+   PARAGRAPH: while (1) {
+       my ($paragraph,$pararef)=("","");
+       my $first=1;
+       my ($line,$lref)=$self->shiftline();
+       while (defined($line)) {
+	   if ($line =~ m/<p>/ && !$first--; ) {
+	       # Not the first time we see <p>. 
+	       # Reput the current line in input,
+	       #  and put the built paragraph to output
+	       $self->unshiftline($line,$lref);
+	      
+	       # Now that the document is formed, translate it:
+	       #   - Remove the leading tag
+	       $paragraph =~ s/^<p>//s;
+
+	       #   - push to output the leading tag (untranslated) and the
+	       #     rest of the paragraph (translated)
+	       $self->pushline(  "<p>"
+                               . $document->translate($paragraph,$pararef)
+                               );
+
+ 	       next PARAGRAPH;
+	   } else {
+	       # Append to the paragraph
+	       $paragraph .= $line;
+	       $pararef = $lref unless(length($pararef));
+	   }
+
+           # Reinit the loop
+           ($line,$lref)=$self->shiftline();
+       }
+       # Did not get a defined line? End of input file.
+       return;
+   }
+ } 
+
+Once you've implemented the parse function, you can use your document
+class, using the public interface presented in the next section.
+
+=head1 PUBLIC INTERFACE for scripts using your parser
+
+=head2 Constructor
+
+=over 4
+
+=item process(%)
+
+This function can do all you need to do with a po4a document in one
+invocation. Its arguments must be packed as a hash. ACTIONS:
+
+=over 3
+
+=item a.
+
+Reads all the po files specified in po_in_name
+
+=item b.
+
+Reads all original documents specified in file_in_name
+
+=item c.
+
+Parses the document
+
+=item d.
+
+Reads and applies all the addenda specified
+
+=item e.
+
+Writes the translated document to file_out_name (if given)
+
+=item f.
+
+Writes the extracted po file to po_out_name (if given)
+
+=back
+
+ARGUMENTS, beside the ones accepted by new() (with expected type):
+
+=over 4
+
+=item file_in_name (@)
+
+List of filenames where we should read the input document.
+
+=item file_in_charset ($)
+
+Charset used in the input document (if it isn't specified, it will try
+to detect it from the input document).
+
+=item file_out_name ($)
+
+Filename where we should write the output document.
+
+=item file_out_charset ($)
+
+Charset used in the output document (if it isn't specified, it will use
+the po file charset).
+
+=item po_in_name (@)
+
+List of filenames where we should read the input po files from, containing
+the translation which will be used to translate the document.
+
+=item po_out_name ($)
+
+Filename where we should write the output po file, containing the strings
+extracted from the input document.
+
+=item addendum (@)
+
+List of filenames where we should read the addenda from.
+
+=item addendum_charset ($)
+
+Charset for the addenda.
+
+=back
+
+=item new(%)
+
+Create a new Po4a document. Accepted options (but be in a hash):
+
+=over 4
+
+=item verbose ($)
+
+Sets the verbosity.
+
+=item debug ($)
+
+Sets the debugging.
+
+=back
+
+=cut
+
+sub process {
+    ## Determine if we were called via an object-ref or a classname
+    my $self = shift;
+
+    ## Any remaining arguments are treated as initial values for the
+    ## hash that is used to represent this object.
+    my %params = @_;
+    
+    # Build the args for new()
+    my %newparams = ();
+    foreach (keys %params) {
+	next if ($_ eq 'po_in_name' ||
+		 $_ eq 'po_out_name' ||
+		 $_ eq 'file_in_name' ||
+		 $_ eq 'file_in_charset' ||
+		 $_ eq 'file_out_name' ||
+		 $_ eq 'file_out_charset' ||
+		 $_ eq 'addendum' ||
+		 $_ eq 'addendum_charset');
+	$newparams{$_}=$params{$_};
+    }
+
+    $self->detected_charset($params{'file_in_charset'});
+    $self->{TT}{'file_out_charset'}=$params{'file_out_charset'};
+    if (defined($self->{TT}{'file_out_charset'}) and
+	length($self->{TT}{'file_out_charset'})) {
+	$self->{TT}{'file_out_encoder'} = find_encoding($self->{TT}{'file_out_charset'});
+    }
+    $self->{TT}{'addendum_charset'}=$params{'addendum_charset'};
+
+    foreach my $file (@{$params{'po_in_name'}}) {
+	print STDERR "readpo($file)... " if $self->debug();
+	$self->readpo($file);
+	print STDERR "done.\n" if $self->debug()
+    }
+    foreach my $file (@{$params{'file_in_name'}}) {
+	print STDERR "read($file)..." if $self->debug();
+	$self->read($file);
+	print STDERR "done.\n"  if $self->debug();
+    }
+    print STDERR "parse..." if $self->debug();
+    $self->parse();
+    print STDERR "done.\n" if $self->debug();
+    foreach my $file (@{$params{'addendum'}}) {
+	print STDERR "addendum($file)..." if $self->debug();
+	$self->addendum($file) || die "An addendum failed\n";
+	print STDERR "done.\n" if $self->debug();
+    }
+    if (defined $params{'file_out_name'}) {
+	print STDERR "write(".$params{'file_out_name'}.")... " 
+	    if $self->debug();
+	$self->write($params{'file_out_name'});
+	print STDERR "done.\n" if $self->debug();
+    }
+    if (defined $params{'po_out_name'}) {
+	print STDERR "writepo(".$params{'po_out_name'}.")... "
+	     if $self->debug();
+	$self->writepo($params{'po_out_name'});
+	print STDERR "done.\n" if $self->debug();
+    }
+    return $self;
+}
+
+sub new {
+    ## Determine if we were called via an object-ref or a classname
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = { };
+    my %options=@_;
+    ## Bless ourselves into the desired class and perform any initialization
+    bless $self, $class;
+    
+    ## initialize the plugin
+    # prevent the plugin from croaking on the options intended for Po.pm
+    $self->{options}{'porefs'} = '';
+    # let the plugin parse the options and such
+    $self->initialize(%options);
+
+    ## Create our private data
+    my %po_options;
+    $po_options{'porefs'} = $self->{options}{'porefs'};
+    
+    # private data
+    $self->{TT}=(); 
+    $self->{TT}{po_in}=Locale::Po4a::Po->new();
+    $self->{TT}{po_out}=Locale::Po4a::Po->new(\%po_options);
+    # Warning, this is an array of array:
+    #  The document is splited on lines, and for each
+    #  [0] is the line content, [1] is the reference [2] the type
+    $self->{TT}{doc_in}=();
+    $self->{TT}{doc_out}=();
+    if (defined $options{'verbose'}) {
+	$self->{TT}{verbose}  =  $options{'verbose'};
+    }
+    if (defined $options{'debug'}) {
+	$self->{TT}{debug}  =  $options{'debug'};
+    }
+    # Input document is in ascii until we prove the opposite (in read())
+    $self->{TT}{ascii_input}=1;
+    # We try not to use utf unless it's forced from the outside (in case the
+    # document isn't in ascii)
+    $self->{TT}{utf_mode}=0;
+
+    
+    return $self;
+}
+
+=back
+
+=head2 Manipulating document files
+
+=over 4
+
+=item read($)
+
+Add another input document at the end of the existing one. The argument is
+the filename to read. 
+
+Please note that it does not parse anything. You should use the parse()
+function when you're done with packing input files into the document. 
+
+=cut
+
+#'
+sub read() {
+    my $self=shift;
+    my $filename=shift
+	or croak wrap_msg(dgettext("po4a", "Can't read from file without having a filename"));
+    my $linenum=0;
+
+    open INPUT,"<$filename" 
+	or croak wrap_msg(dgettext("po4a", "Can't read from %s: %s"), $filename, $!);
+    while (defined (my $textline = <INPUT>)) {
+	$linenum++;
+	my $ref="$filename:$linenum";
+	my @entry=($textline,$ref);
+	push @{$self->{TT}{doc_in}}, @entry;
+
+	if (!defined($self->{TT}{'file_in_charset'})) {
+	    # Detect if this file has non-ascii characters
+	    if($self->{TT}{ascii_input}) {
+		my $decoder = guess_encoding($textline);
+		if (!ref($decoder) or $decoder !~ /Encode::XS=/) {
+		    # We have detected a non-ascii line
+		    $self->{TT}{ascii_input} = 0;
+		    # Save the reference for future error message
+		    $self->{TT}{non_ascii_ref} ||= $ref;
+		}
+	    }
+	}
+    }
+    close INPUT 
+	or croak wrap_msg(dgettext("po4a", "Can't close %s after reading: %s"), $filename, $!);
+
+}
+
+=item write($)
+
+Write the translated document to the given filename.
+
+=cut
+
+sub write {
+    my $self=shift;
+    my $filename=shift
+	or croak wrap_msg(dgettext("po4a", "Can't write to a file without filename"));
+
+    my $fh;
+    if ($filename eq '-') {
+	$fh=\*STDOUT;
+    } else {
+	# make sure the directory in which we should write the localized file exists
+	my $dir = $filename;
+	if ($dir =~ m|/|) {
+	    $dir =~ s|/[^/]*$||;
+	
+	    File::Path::mkpath($dir, 0, 0755) # Croaks on error
+	      if (length ($dir) && ! -e $dir);
+	}
+	open $fh,">$filename"
+	    or croak wrap_msg(dgettext("po4a", "Can't write to %s: %s"), $filename, $!);
+    }
+    
+    map { print $fh $_ } $self->docheader();
+    map { print $fh $_ } @{$self->{TT}{doc_out}};
+
+    if ($filename ne '-') {
+	close $fh or croak wrap_msg(dgettext("po4a", "Can't close %s after writing: %s"), $filename, $!);
+    }
+
+}
+
+=back
+
+=head2 Manipulating po files
+
+=over 4 
+
+=item readpo($)
+
+Add the content of a file (which name is passed in argument) to the
+existing input po. The old content is not discarded.
+
+=item writepo($)
+
+Write the extracted po file to the given filename.
+
+=item stats()
+
+Returns some statistics about the translation done so far. Please note that
+it's not the same statistics than the one printed by msgfmt
+--statistic. Here, it's stats about recent usage of the po file, while
+msgfmt reports the status of the file. It is a wrapper to the
+Locale::Po4a::Po::stats_get function applied to the input po file. Example
+of use:
+
+    [normal use of the po4a document...]
+
+    ($percent,$hit,$queries) = $document->stats();
+    print "We found translations for $percent\%  ($hit from $queries) of strings.\n";
+
+=back
+
+=cut
+
+sub getpoout {
+    return $_[0]->{TT}{po_out};
+}
+sub setpoout {
+    $_[0]->{TT}{po_out} = $_[1];
+}
+sub readpo  { 
+    $_[0]->{TT}{po_in}->read($_[1]);        
+}
+sub writepo { 
+    $_[0]->{TT}{po_out}->write( $_[1] );    
+}
+sub stats   { 
+    return $_[0]->{TT}{po_in}->stats_get(); 
+}
+
+=head2 Manipulating addenda
+
+=over 4
+
+=item addendum($)
+
+Please refer to L<po4a(7)|po4a.7> for more information on what addenda are,
+and how translators should write them. To apply an addendum to the translated
+document, simply pass its filename to this function and you are done ;)
+
+This function returns a non-null integer on error.
+
+=cut
+
+# Internal function to read the header.
+sub addendum_parse {
+    my ($filename,$header)=shift;
+
+    my ($errcode,$mode,$position,$boundary,$bmode,$content)=
+	(1,"","","","","");
+
+    unless (open (INS, "<$filename")) {
+	warn wrap_msg(dgettext("po4a", "Can't read from %s: %s"), $filename, $!);
+	goto END_PARSE_ADDFILE;
+    } 
+
+    unless (defined ($header=<INS>) && $header)  {
+	warn wrap_msg(dgettext("po4a", "Can't read Po4a header from %s."), $filename);
+	goto END_PARSE_ADDFILE;
+    }
+
+    unless ($header =~ s/PO4A-HEADER://i) {
+	warn wrap_msg(dgettext("po4a", "First line of %s does not look like a Po4a header."), $filename);
+	goto END_PARSE_ADDFILE;
+    }
+    foreach my $part (split(/;/,$header)) {
+	unless ($part =~ m/^\s*([^=]*)=(.*)$/) {
+	    warn wrap_msg(dgettext("po4a", "Syntax error in Po4a header of %s, near \"%s\""), $filename, $part);
+	    goto END_PARSE_ADDFILE;
+	}
+	my ($key,$value)=($1,$2);
+	$key=lc($key);
+  	     if ($key eq 'mode')     {  $mode=lc($value);
+	} elsif ($key eq 'position') {  $position=$value;
+	} elsif ($key eq 'endboundary') {  
+	    $boundary=$value;
+	    $bmode='after';
+	} elsif ($key eq 'beginboundary') {  
+	    $boundary=$value;
+	    $bmode='before';
+	} else { 
+	    warn wrap_msg(dgettext("po4a", "Invalid argument in the Po4a header of %s: %s"), $filename, $key);
+	    goto END_PARSE_ADDFILE;
+	}
+    }
+
+    unless (length($mode)) {
+	warn wrap_msg(dgettext("po4a", "The Po4a header of %s does not define the mode."), $filename);
+	goto END_PARSE_ADDFILE;
+    }
+    unless ($mode eq "before" || $mode eq "after") {
+	warn wrap_msg(dgettext("po4a", "Mode invalid in the Po4a header of %s: should be 'before' or 'after' not %s."), $filename, $mode);
+	goto END_PARSE_ADDFILE;
+    }
+
+    unless (length($position)) {
+	warn wrap_msg(dgettext("po4a", "The Po4a header of %s does not define the position."), $filename);
+	goto END_PARSE_ADDFILE;
+    }
+    unless ($mode eq "before" || length($boundary)) {
+    	warn wrap_msg(dgettext("po4a", "No ending boundary given in the Po4a header, but mode=after."));
+	goto END_PARSE_ADDFILE;
+    }
+
+    while (defined(my $line = <INS>)) {
+	$content .= $line;
+    }
+    close INS;
+
+    $errcode=0;
+  END_PARSE_ADDFILE: 
+      return ($errcode,$mode,$position,$boundary,$bmode,$content);
+}
+
+sub mychomp {
+    my ($str) = shift;
+    chomp($str);
+    return $str;
+}
+
+sub addendum {
+    my ($self,$filename) = @_;
+
+    print STDERR "Apply addendum $filename..." if $self->debug();
+    unless ($filename) {
+	warn wrap_msg(dgettext("po4a",
+	    "Can't apply addendum when not given the filename"));
+	return 0;
+    }
+    die wrap_msg(dgettext("po4a", "Addendum %s does not exist."), $filename)
+      unless -e $filename;
+  
+    my ($errcode,$mode,$position,$boundary,$bmode,$content)=
+	addendum_parse($filename);
+    return 0 if ($errcode);
+
+    print STDERR "mode=$mode;pos=$position;bound=$boundary;bmode=$bmode;ctn=$content\n"
+      if $self->debug();
+    
+    # We only recode the addendum if an origin charset is specified, else we
+    # suppose it's already in the output document's charset
+    if (defined($self->{TT}{'addendum_charset'}) &&
+        length($self->{TT}{'addendum_charset'})) {
+	Encode::from_to($content,$self->{TT}{'addendum_charset'},
+	    $self->get_out_charset);
+    }
+
+    my $found = scalar grep { /$position/ } @{$self->{TT}{doc_out}};
+    if ($found == 0) {
+	warn wrap_msg(dgettext("po4a",
+	    "No candidate position for the addendum %s."), $filename);
+	return 0;
+    }
+    if ($found > 1) {
+	warn wrap_msg(dgettext("po4a",
+	    "More than one candidate position found for the addendum %s."), $filename);
+	return 0;
+    }
+
+    if ($mode eq "before") {
+	if ($self->verbose() > 1 || $self->debug() ) {
+	    map { print STDERR wrap_msg(dgettext("po4a", "Addendum '%s' applied before this line: %s"), $filename, $_) if (/$position/);
+ 	        } @{$self->{TT}{doc_out}};
+	}
+	@{$self->{TT}{doc_out}} = map { /$position/ ? ($content,$_) : $_ 
+                                        }  @{$self->{TT}{doc_out}};
+    } else {
+	my @newres=();
+
+	do {
+	    # make sure it doesnt whine on empty document
+	    my $line = scalar @{$self->{TT}{doc_out}} ? shift @{$self->{TT}{doc_out}} : "";
+	    push @newres,$line;
+	    my $outline=mychomp($line);
+	    $outline =~ s/^[ \t]*//;
+	      
+	    if ($line =~ m/$position/) {
+		while ($line=shift @{$self->{TT}{doc_out}}) {
+		    last if ($line=~/$boundary/);
+		    push @newres,$line;
+		}
+		if (defined $line) {
+		    if ($bmode eq 'before') {
+			print wrap_msg(dgettext("po4a",
+			    "Addendum '%s' applied before this line: %s"),
+			    $filename, $outline)
+			  if ($self->verbose() > 1 || $self->debug());
+			push @newres,$content;
+			push @newres,$line;
+		    } else {
+			print wrap_msg(dgettext("po4a",
+			    "Addendum '%s' applied after the line: %s."),
+			    $filename, $outline)
+			  if ($self->verbose() > 1 || $self->debug());
+			push @newres,$line;
+			push @newres,$content;
+		    }
+		} else {
+		    print wrap_msg(dgettext("po4a", "Addendum '%s' applied at the end of the file."), $filename)
+		      if ($self->verbose() > 1 || $self->debug());
+		    push @newres,$content;
+		}
+	    }
+	} while (scalar @{$self->{TT}{doc_out}});
+	@{$self->{TT}{doc_out}} = @newres;
+    }
+    print STDERR "done.\n" if $self->debug();
+    return 1;
+}
+
+=back
+
+=head1 INTERNAL FUNCTIONS used to write derivated parsers
+
+=head2 Getting input, providing output
+
+Four functions are provided to get input and return output. They are very
+similar to shift/unshift and push/pop. The first pair is about input, while
+the second is about output. Mnemonic: in input, you are interested in the
+first line, what shift gives, and in output you want to add your result at
+the end, like push does.
+
+=over 4
+
+=item shiftline()
+
+This function returns the next line of the doc_in to be parsed and its
+reference (packed as an array).
+
+=item unshiftline($$)
+
+Unshifts a line of the input document and its reference. 
+
+=item pushline($)
+
+Push a new line to the doc_out.
+
+=item popline()
+
+Pop the last pushed line from the doc_out.
+
+=back
+
+=cut
+
+sub shiftline   {  
+    my ($line,$ref)=(shift @{$_[0]->{TT}{doc_in}},
+		     shift @{$_[0]->{TT}{doc_in}}); 
+    return ($line,$ref);
+}
+sub unshiftline {
+	my $self = shift;
+	unshift @{$self->{TT}{doc_in}},@_;
+}
+
+sub pushline    {  push @{$_[0]->{TT}{doc_out}}, $_[1] if defined $_[1]; }
+sub popline     {  return pop @{$_[0]->{TT}{doc_out}};            }
+
+=head2 Marking strings as translatable
+
+One function is provided to handle the text which should be translated. 
+
+=over 4
+
+=item translate($$$)
+
+Mandatory arguments:
+
+=over 2
+
+=item -
+
+A string to translate
+
+=item -
+
+The reference of this string (ie, position in inputfile)
+
+=item -
+
+The type of this string (ie, the textual description of its structural role
+; used in Locale::Po4a::Po::gettextization() ; see also L<po4a(7)|po4a.7>,
+section I<Gettextization: how does it work?>)
+
+=back
+
+This function can also take some extra arguments. They must be organized as
+a hash. For example:
+
+  $self->translate("string","ref","type",
+		   'wrap' => 1);
+
+=over
+
+=item wrap
+
+boolean indicating whether we can consider that whitespaces in string are
+not important. If yes, the function canonizes the string before looking for
+a translation or extracting it, and wraps the translation.
+
+=item wrapcol
+
+The column at which we should wrap (default: 76).
+
+=item comment
+
+An extra comment to add to the entry.
+
+=back
+
+Actions:
+
+=over 2
+
+=item -
+
+Pushes the string, reference and type to po_out.
+
+=item -
+
+Returns the translation of the string (as found in po_in) so that the
+parser can build the doc_out.
+
+=item -
+
+Handles the charsets to recode the strings before sending them to
+po_out and before returning the translations.
+
+=back
+
+=back
+
+=cut
+
+sub translate {
+    my $self=shift;
+    my ($string,$ref,$type)=(shift,shift,shift);
+    my (%options)=@_;
+
+    # my $validoption="wrap wrapcol";
+    # my %validoption;
+
+    return "" unless defined($string) && length($string);
+
+    # map { $validoption{$_}=1 } (split(/ /,$validoption));
+    # foreach (keys %options) {
+    #	Carp::confess "internal error: translate() called with unknown arg $_. Valid options: $validoption"
+    #	    unless $validoption{$_};
+    # }
+
+    my $in_charset;
+    if ($self->{TT}{ascii_input}) {
+	$in_charset = "ascii";
+    } else {
+	if (defined($self->{TT}{'file_in_charset'}) and
+	    length($self->{TT}{'file_in_charset'}) and
+	    $self->{TT}{'file_in_charset'} !~ m/ascii/i) {
+	    $in_charset=$self->{TT}{'file_in_charset'};
+	} else {
+	    # FYI, the document charset have to be determined *before* we see the first
+	    # string to recode.
+	    die wrap_mod("po4a", dgettext("po4a", "Couldn't determine the input document's charset. Please specify it on the command line. (non-ascii char at %s)"), $self->{TT}{non_ascii_ref})
+	}
+    }
+
+    if ($self->{TT}{po_in}->get_charset ne "CHARSET") {
+	$string = encode_from_to($string,
+	                         $self->{TT}{'file_in_encoder'},
+	                         $self->{TT}{po_in}{encoder});
+    }
+
+    if (defined $options{'wrapcol'} && $options{'wrapcol'} < 0) {
+# FIXME: should be the parameter given with --width
+        $options{'wrapcol'} = 76 + $options{'wrapcol'};
+    }
+    my $transstring = $self->{TT}{po_in}->gettext($string,
+					'wrap'      => $options{'wrap'}||0,
+					'wrapcol'   => $options{'wrapcol'});
+
+    if ($self->{TT}{po_in}->get_charset ne "CHARSET") {
+	my $out_encoder = $self->{TT}{'file_out_encoder'};
+	unless (defined $out_encoder) {
+	    $out_encoder = find_encoding($self->get_out_charset)
+	}
+	$transstring = encode_from_to($transstring,
+	                              $self->{TT}{po_in}{encoder},
+	                              $out_encoder);
+    }
+
+    # If the input document isn't completely in ascii, we should see what to
+    # do with the current string
+    unless ($self->{TT}{ascii_input}) {
+        my $out_charset = $self->{TT}{po_out}->get_charset;
+	# We set the output po charset 
+        if ($out_charset eq "CHARSET") {
+	    if ($self->{TT}{utf_mode}) {
+		$out_charset="utf-8";
+	    } else {
+		$out_charset=$in_charset;
+	    }
+	    $self->{TT}{po_out}->set_charset($out_charset);
+	}
+	if ( $in_charset !~ /^$out_charset$/i ) {
+	    Encode::from_to($string,$in_charset,$out_charset);
+	    if (defined($options{'comment'}) and length($options{'comment'})) {
+		Encode::from_to($options{'comment'},$in_charset,$out_charset);
+	    }
+	}
+    }
+
+    # the comments provided by the modules are automatic comments from the PO point of view
+    $self->{TT}{po_out}->push('msgid'     => $string,
+			      'reference' => $ref,
+			      'type'      => $type,
+	                      'automatic' => $options{'comment'},
+			      'wrap'      => $options{'wrap'}||0,
+			      'wrapcol'   => $options{'wrapcol'});
+
+#    if ($self->{TT}{po_in}->get_charset ne "CHARSET") {
+#	Encode::from_to($transstring,$self->{TT}{po_in}->get_charset,
+#	    $self->get_out_charset);
+#    }
+
+    if ($options{'wrap'}||0) {
+        $transstring =~ s/( *)$//s;
+        my $trailing_spaces = $1||"";
+        $transstring =~ s/ *$//gm;
+        $transstring .= $trailing_spaces;
+    }
+
+    return $transstring;
+}
+
+=head2 Misc functions
+
+=over 4
+
+=item verbose()
+
+Returns if the verbose option was passed during the creation of the
+TransTractor.
+
+=cut
+
+sub verbose {
+    if (defined $_[1]) {
+	$_[0]->{TT}{verbose} = $_[1];
+    } else {
+	return $_[0]->{TT}{verbose} || 0; # undef and 0 have the same meaning, but one generates warnings
+    }
+}
+
+=item debug()
+
+Returns if the debug option was passed during the creation of the
+TransTractor.
+
+=cut
+
+sub debug {
+    return $_[0]->{TT}{debug};
+}
+
+=item detected_charset($)
+
+This tells TransTractor that a new charset (the first argument) has been
+detected from the input document. It can usually be read from the document
+header. Only the first charset will remain, coming either from the
+process() arguments or detected from the document.
+
+=cut
+
+sub detected_charset {
+    my ($self,$charset)=(shift,shift);
+    unless (defined($self->{TT}{'file_in_charset'}) and
+            length($self->{TT}{'file_in_charset'}) ) {
+        $self->{TT}{'file_in_charset'}=$charset;
+        if (defined $charset) {
+            $self->{TT}{'file_in_encoder'}=find_encoding($charset);
+        }
+    }
+
+    if (defined $self->{TT}{'file_in_charset'} and
+        length $self->{TT}{'file_in_charset'} and
+        $self->{TT}{'file_in_charset'} !~ m/ascii/i) {
+	$self->{TT}{ascii_input}=0;
+    }
+}
+
+=item get_out_charset()
+
+This function will return the charset that should be used in the output
+document (usually useful to substitute the input document's detected charset
+where it has been found).
+
+It will use the output charset specified in the command line. If it wasn't
+specified, it will use the input po's charset, and if the input po has the
+default "CHARSET", it will return the input document's charset, so that no
+encoding is performed.
+
+=cut
+
+sub get_out_charset {
+    my $self=shift;
+    my $charset;
+
+    # Use the value specified at the command line
+    if (defined($self->{TT}{'file_out_charset'}) and
+	length($self->{TT}{'file_out_charset'})) {
+	$charset=$self->{TT}{'file_out_charset'};
+    } else {
+	if ($self->{TT}{utf_mode} && $self->{TT}{ascii_input}) {
+	    $charset="utf-8";
+	} else {
+	    $charset=$self->{TT}{po_in}->get_charset;
+	    $charset=$self->{TT}{'file_in_charset'}
+		if $charset eq "CHARSET" and
+		    defined($self->{TT}{'file_in_charset'}) and
+		    length($self->{TT}{'file_in_charset'});
+	    $charset="ascii"
+		if $charset eq "CHARSET";
+	}
+    }
+    return $charset;
+}
+
+=item recode_skipped_text($)
+
+This function returns the recoded text passed as argument, from the input
+document's charset to the output document's one. This isn't needed when
+translating a string (translate() recodes everything itself), but it is when
+you skip a string from the input document and you want the output document to
+be consistent with the global encoding.
+
+=cut
+
+sub recode_skipped_text {
+    my ($self,$text)=(shift,shift);
+    unless ($self->{TT}{'ascii_input'}) {
+	if(defined($self->{TT}{'file_in_charset'}) and
+	    length($self->{TT}{'file_in_charset'}) ) {
+	    $text = encode_from_to($text,
+	                           $self->{TT}{'file_in_encoder'},
+	                           find_encoding($self->get_out_charset));
+	} else {
+	    die wrap_mod("po4a", dgettext("po4a", "Couldn't determine the input document's charset. Please specify it on the command line. (non-ascii char at %s)"), $self->{TT}{non_ascii_ref})
+	}
+    }
+    return $text;
+}
+
+
+# encode_from_to($,$,$)
+#
+# Encode the given text from one encoding to another one.
+# It differs from Encode::from_to because it does not take the name of the
+# encoding in argument, but the encoders (as returned by the
+# Encode::find_encoding(<name>) method). Thus it permits to save a bunch
+# of call to find_encoding.
+#
+# If the "from" encoding is undefined, it is considered as UTF-8 (or
+# ascii).
+# If the "to" encoding is undefined, it is considered as UTF-8.
+#
+sub encode_from_to {
+    my ($text,$from,$to) = (shift,shift,shift);
+
+    if (not defined $from) {
+        # for ascii and UTF-8, no conversion needed to get an utf-8
+        # string.
+    } else {
+        $text = $from->decode($text, 0);
+    }
+
+    if (not defined $to) {
+        # Already in UTF-8, no conversion needed
+    } else {
+        $text = $to->encode($text, 0);
+    }
+
+    return $text;
+}
+
+=back
+
+=head1 FUTURE DIRECTIONS
+
+One shortcoming of the current TransTractor is that it can't handle
+translated document containing all languages, like debconf templates, or
+.desktop files.
+
+To address this problem, the only interface changes needed are:
+
+=over 2
+
+=item -
+
+take a hash as po_in_name (a list per language)
+
+=item -
+
+add an argument to translate to indicate the target language
+
+=item -
+
+make a pushline_all function, which would make pushline of its content for
+all language, using a map-like syntax:
+
+    $self->pushline_all({ "Description[".$langcode."]=".
+			  $self->translate($line,$ref,$langcode) 
+		        });
+
+=back
+
+Will see if it's enough ;)
+
+=head1 AUTHORS
+
+ Denis Barbier <barbier@linuxfr.org>
+ Martin Quinson (mquinson#debian.org)
+ Jordi Vilalta <jvprat@gmail.com>
+
+=cut
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/lib/Locale/Po4a/Xml.pm	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,1973 @@
+#!/usr/bin/perl
+
+# Po4a::Xml.pm 
+# 
+# extract and translate translatable strings from XML documents.
+# 
+# This code extracts plain text from tags and attributes from generic
+# XML documents, and it can be used as a base to build modules for
+# XML-based documents.
+#
+# Copyright (c) 2004 by Jordi Vilalta  <jvprat@gmail.com>
+# Copyright (c) 2008-2009 by Nicolas François  <nicolas.francois@centraliens.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+########################################################################
+
+=head1 NAME
+
+Locale::Po4a::Xml - Convert XML documents and derivates from/to PO files
+
+=head1 DESCRIPTION
+
+The po4a (po for anything) project goal is to ease translations (and more
+interestingly, the maintenance of translations) using gettext tools on
+areas where they were not expected like documentation.
+
+Locale::Po4a::Xml is a module to help the translation of XML documents into
+other [human] languages. It can also be used as a base to build modules for
+XML-based documents.
+
+=cut
+
+package Locale::Po4a::Xml;
+
+use 5.006;
+use strict;
+use warnings;
+
+require Exporter;
+use vars qw(@ISA @EXPORT);
+@ISA = qw(Locale::Po4a::TransTractor);
+@EXPORT = qw(new initialize @tag_types);
+
+use Locale::Po4a::TransTractor;
+use Locale::Po4a::Common;
+use Carp qw(croak);
+use File::Basename;
+use File::Spec;
+
+#It will mantain the path from the root tag to the current one
+my @path;
+
+#It will contain a list of external entities and their attached paths
+my %entities;
+
+my @comments;
+
+sub shiftline {
+    my $self = shift;
+    # call Transtractor's shiftline
+    my ($line,$ref) = $self->SUPER::shiftline();
+    return ($line,$ref) if (not defined $line);
+
+    for my $k (keys %entities) {
+        if ($line =~ m/^(.*?)&$k;(.*)$/s) {
+            my ($before, $after) = ($1, $2);
+            my $linenum=0;
+            my @textentries;
+
+            open (my $in, $entities{$k})
+                or croak wrap_mod("po4a::xml",
+                                  dgettext("po4a", "Can't read from %s: %s"),
+                                  $entities{$k}, $!);
+            while (defined (my $textline = <$in>)) {
+                $linenum++;
+                my $textref=$entities{$k}.":$linenum";
+                push @textentries, ($textline,$textref);
+            }
+            close $in
+                or croak wrap_mod("po4a::xml",
+                          dgettext("po4a", "Can't close %s after reading: %s"),
+                                  $entities{$k}, $!);
+
+            push @textentries, ($after, $ref);
+            $line = $before.(shift @textentries);
+            $ref .= " ".(shift @textentries);
+            $self->unshiftline(@textentries);
+        }
+    }
+
+    return ($line,$ref);
+}
+
+sub read {
+	my ($self,$filename)=@_;
+	push @{$self->{DOCPOD}{infile}}, $filename;
+	$self->Locale::Po4a::TransTractor::read($filename);
+}
+
+sub parse {
+	my $self=shift;
+	map {$self->parse_file($_)} @{$self->{DOCPOD}{infile}};
+}
+
+# @save_holders is a stack of references to ('paragraph', 'translation',
+# 'sub_translations', 'open', 'close', 'folded_attributes') hashes, where:
+# paragraph         is a reference to an array (see paragraph in the
+#                   treat_content() subroutine) of strings followed by
+#                   references.  It contains the @paragraph array as it was
+#                   before the processing was interrupted by a tag instroducing
+#                   a placeholder.
+# translation       is the translation of this level up to now
+# sub_translations  is a reference to an array of strings containing the
+#                   translations which must replace the placeholders.
+# open              is the tag which opened the placeholder.
+# close             is the tag which closed the placeholder.
+# folded_attributes is an hash of tags with their attributes (<tag attrs=...>
+#                   strings), referenced by the folded tag id, which should
+#                   replace the <tag po4a-id=id> strings in the current
+#                   translation.
+#
+# If @save_holders only has 1 holder, then we are not processing the
+# content of an holder, we are translating the document.
+my @save_holders;
+
+
+# If we are at the bottom of the stack and there is no <placeholder ...> in
+# the current translation, we can push the translation in the translated
+# document.
+# Otherwise, we keep the translation in the current holder.
+sub pushline {
+	my ($self, $line) = (shift, shift);
+
+	my $holder = $save_holders[$#save_holders];
+	my $translation = $holder->{'translation'};
+	$translation .= $line;
+
+	while (    %{$holder->{folded_attributes}}
+	       and $translation =~ m/^(.*)<([^>]+?)\s+po4a-id=([0-9]+)>(.*)$/s) {
+		my $begin = $1;
+		my $tag = $2;
+		my $id = $3;
+		my $end = $4;
+		if (defined $holder->{folded_attributes}->{$id}) {
+			# TODO: check if the tag is the same
+			$translation = $begin.$holder->{folded_attributes}->{$id}.$end;
+			delete $holder->{folded_attributes}->{$id};
+		} else {
+			# TODO: It will be hard to identify the location.
+			#       => find a way to retrieve the reference.
+			die wrap_mod("po4a::xml", dgettext("po4a", "'po4a-id=%d' in the translation does not exist in the original string (or 'po4a-id=%d' used twice in the translation)."), $id, $id);
+		}
+	}
+# TODO: check that %folded_attributes is empty at some time
+# => in translate_paragraph?
+
+	if (   ($#save_holders > 0)
+	    or ($translation =~ m/<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>/s)) {
+		$holder->{'translation'} = $translation;
+	} else {
+		$self->SUPER::pushline($translation);
+		$holder->{'translation'} = '';
+	}
+}
+
+=head1 TRANSLATING WITH PO4A::XML
+
+This module can be used directly to handle generic XML documents.  This will
+extract all tag's content, and no attributes, since it's where the text is
+written in most XML based documents.
+
+There are some options (described in the next section) that can customize
+this behavior.  If this doesn't fit to your document format you're encouraged
+to write your own module derived from this, to describe your format's details.
+See the section "Writing derivate modules" below, for the process description.
+
+=cut
+
+#
+# Parse file and translate it
+#
+sub parse_file {
+	my ($self,$filename) = @_;
+	my $eof = 0;
+
+	while (!$eof) {
+		# We get all the text until the next breaking tag (not
+		# inline) and translate it
+		$eof = $self->treat_content;
+		if (!$eof) {
+			# And then we treat the following breaking tag
+			$eof = $self->treat_tag;
+		}
+	}
+}
+
+=head1 OPTIONS ACCEPTED BY THIS MODULE
+
+The global debug option causes this module to show the excluded strings, in
+order to see if it skips something important.
+
+These are this module's particular options:
+
+=over 4
+
+=item B<nostrip>
+
+Prevents it to strip the spaces around the extracted strings.
+
+=item B<wrap>
+
+Canonizes the string to translate, considering that whitespaces are not
+important, and wraps the translated document. This option can be overridden
+by custom tag options. See the "tags" option below.
+
+=item B<caseinsensitive>
+
+It makes the tags and attributes searching to work in a case insensitive
+way.  If it's defined, it will treat E<lt>BooKE<gt>laNG and E<lt>BOOKE<gt>Lang as E<lt>bookE<gt>lang.
+
+=item B<includeexternal>
+
+When defined, external entities are included in the generated (translated)
+document, and for the extraction of strings.  If it's not defined, you
+will have to translate external entities separately as independent
+documents.
+
+=item B<ontagerror>
+
+This option defines the behavior of the module when it encounter a invalid
+Xml syntax (a closing tag which does not match the last opening tag, or a
+tag's attribute without value).
+It can take the following values:
+
+=over
+
+=item I<fail>
+
+This is the default value.
+The module will exit with an error.
+
+=item I<warn>
+
+The module will continue, and will issue a warning.
+
+=item I<silent>
+
+The module will continue without any warnings.
+
+=back
+
+Be careful when using this option.
+It is generally recommended to fix the input file.
+
+=item B<tagsonly>
+
+Extracts only the specified tags in the "tags" option.  Otherwise, it
+will extract all the tags except the ones specified.
+
+Note: This option is deprecated.
+
+=item B<doctype>
+
+String that will try to match with the first line of the document's doctype
+(if defined). If it doesn't, a warning will indicate that the document
+might be of a bad type.
+
+=item B<tags>
+
+Space-separated list of tags you want to translate or skip.  By default,
+the specified tags will be excluded, but if you use the "tagsonly" option,
+the specified tags will be the only ones included.  The tags must be in the
+form E<lt>aaaE<gt>, but you can join some (E<lt>bbbE<gt>E<lt>aaaE<gt>) to say that the content of
+the tag E<lt>aaaE<gt> will only be translated when it's into a E<lt>bbbE<gt> tag.
+
+You can also specify some tag options putting some characters in front of
+the tag hierarchy. For example, you can put 'w' (wrap) or 'W' (don't wrap)
+to override the default behavior specified by the global "wrap" option.
+
+Example: WE<lt>chapterE<gt>E<lt>titleE<gt>
+
+Note: This option is deprecated.
+You should use the B<translated> and B<untranslated> options instead.
+
+=item B<attributes>
+
+Space-separated list of tag's attributes you want to translate.  You can
+specify the attributes by their name (for example, "lang"), but you can
+prefix it with a tag hierarchy, to specify that this attribute will only be
+translated when it's into the specified tag. For example: E<lt>bbbE<gt>E<lt>aaaE<gt>lang
+specifies that the lang attribute will only be translated if it's into an
+E<lt>aaaE<gt> tag, and it's into a E<lt>bbbE<gt> tag.
+
+=item B<foldattributes>
+
+Do not translate attributes in inline tags.
+Instead, replace all attributes of a tag by po4a-id=<id>.
+
+This is useful when attributes shall not be translated, as this simplifies the
+strings for translators, and avoids typos.
+
+=item B<break>
+
+Space-separated list of tags which should break the sequence.
+By default, all tags break the sequence.
+
+The tags must be in the form <aaa>, but you can join some
+(<bbb><aaa>), if a tag (<aaa>) should only be considered 
+when it's into another tag (<bbb>).
+
+=item B<inline>
+
+Space-separated list of tags which should be treated as inline.
+By default, all tags break the sequence.
+
+The tags must be in the form <aaa>, but you can join some
+(<bbb><aaa>), if a tag (<aaa>) should only be considered 
+when it's into another tag (<bbb>).
+
+=item B<placeholder>
+
+Space-separated list of tags which should be treated as placeholders.
+Placeholders do not break the sequence, but the content of placeholders is
+translated separately.
+
+The location of the placeholder in its blocks will be marked with a string
+similar to:
+
+  <placeholder type=\"footnote\" id=\"0\"/>
+
+The tags must be in the form <aaa>, but you can join some
+(<bbb><aaa>), if a tag (<aaa>) should only be considered 
+when it's into another tag (<bbb>).
+
+=item B<nodefault>
+
+Space separated list of tags that the module should not try to set by
+default in any category.
+
+=item B<cpp>
+
+Support C preprocessor directives.
+When this option is set, po4a will consider preprocessor directives as
+paragraph separators.
+This is important if the XML file must be preprocessed because otherwise
+the directives may be inserted in the middle of lines if po4a consider it
+belong to the current paragraph, and they won't be recognized by the
+preprocessor.
+Note: the preprocessor directives must only appear between tags
+(they must not break a tag).
+
+=item B<translated>
+
+Space-separated list of tags you want to translate.
+
+The tags must be in the form <aaa>, but you can join some
+(<bbb><aaa>), if a tag (<aaa>) should only be considered 
+when it's into another tag (<bbb>).
+
+You can also specify some tag options putting some characters in front of
+the tag hierarchy. For example, you can put 'w' (wrap) or 'W' (don't wrap)
+to overide the default behavior specified by the global "wrap" option.
+
+Example: WE<lt>chapterE<gt>E<lt>titleE<gt>
+
+=item B<untranslated>
+
+Space-separated list of tags you do not want to translate.
+
+The tags must be in the form <aaa>, but you can join some
+(<bbb><aaa>), if a tag (<aaa>) should only be considered 
+when it's into another tag (<bbb>).
+
+=item B<defaulttranslateoption>
+
+The default categories for tags that are not in any of the translated,
+untranslated, break, inline, or placeholder.
+
+This is a set of letters:
+
+=over
+
+=item I<w>
+
+Tags should be translated and content can be re-wrapped.
+
+=item I<W>
+
+Tags should be translated and content should not be re-wrapped.
+
+=item I<i>
+
+Tags should be translated inline.
+
+=item I<p>
+
+Tags should be translated as placeholders.
+
+=back
+
+=back
+
+=cut
+# TODO: defaulttranslateoption
+# w => indicate that it is only valid for translatable tags and do not
+#      care about inline/break/placeholder?
+# ...
+
+sub initialize {
+	my $self = shift;
+	my %options = @_;
+
+	# Reset the path
+	@path = ();
+
+	# Initialize the stack of holders
+	my @paragraph = ();
+	my @sub_translations = ();
+	my %folded_attributes;
+	my %holder = ('paragraph' => \@paragraph,
+	              'translation' => "",
+	              'sub_translations' => \@sub_translations,
+	              'folded_attributes' => \%folded_attributes);
+	@save_holders = (\%holder);
+
+	$self->{options}{'nostrip'}=0;
+	$self->{options}{'wrap'}=0;
+	$self->{options}{'caseinsensitive'}=0;
+	$self->{options}{'tagsonly'}=0;
+	$self->{options}{'tags'}='';
+	$self->{options}{'break'}='';
+	$self->{options}{'translated'}='';
+	$self->{options}{'untranslated'}='';
+	$self->{options}{'defaulttranslateoption'}='';
+	$self->{options}{'attributes'}='';
+	$self->{options}{'foldattributes'}=0;
+	$self->{options}{'inline'}='';
+	$self->{options}{'placeholder'}='';
+	$self->{options}{'doctype'}='';
+	$self->{options}{'nodefault'}='';
+	$self->{options}{'includeexternal'}=0;
+	$self->{options}{'ontagerror'}="fail";
+	$self->{options}{'cpp'}=0;
+
+	$self->{options}{'verbose'}='';
+	$self->{options}{'debug'}='';
+
+	foreach my $opt (keys %options) {
+		if ($options{$opt}) {
+			die wrap_mod("po4a::xml",
+				dgettext("po4a", "Unknown option: %s"), $opt)
+				unless exists $self->{options}{$opt};
+			$self->{options}{$opt} = $options{$opt};
+		}
+	}
+	# Default options set by modules. Forbidden for users.
+	$self->{options}{'_default_translated'}='';
+	$self->{options}{'_default_untranslated'}='';
+	$self->{options}{'_default_break'}='';
+	$self->{options}{'_default_inline'}='';
+	$self->{options}{'_default_placeholder'}='';
+	$self->{options}{'_default_attributes'}='';
+
+	#It will maintain the list of the translatable tags
+	$self->{tags}=();
+	$self->{translated}=();
+	$self->{untranslated}=();
+	#It will maintain the list of the translatable attributes
+	$self->{attributes}=();
+	#It will maintain the list of the breaking tags
+	$self->{break}=();
+	#It will maintain the list of the inline tags
+	$self->{inline}=();
+	#It will maintain the list of the placeholder tags
+	$self->{placeholder}=();
+	#list of the tags that must not be set in the tags or inline category
+	#by this module or sub-module (unless specified in an option)
+	$self->{nodefault}=();
+
+	$self->treat_options;
+}
+
+=head1 WRITING DERIVATE MODULES
+
+=head2 DEFINE WHAT TAGS AND ATTRIBUTES TO TRANSLATE
+
+The simplest customization is to define which tags and attributes you want
+the parser to translate.  This should be done in the initialize function.
+First you should call the main initialize, to get the command-line options,
+and then, append your custom definitions to the options hash.  If you want
+to treat some new options from command line, you should define them before
+calling the main initialize:
+
+  $self->{options}{'new_option'}='';
+  $self->SUPER::initialize(%options);
+  $self->{options}{'_default_translated'}.=' <p> <head><title>';
+  $self->{options}{'attributes'}.=' <p>lang id';
+  $self->{options}{'_default_inline'}.=' <br>';
+  $self->treat_options;
+
+You should use the B<_default_inline>, B<_default_break>,
+B<_default_placeholder>, B<_default_translated>, B<_default_untranslated>,
+and B<_default_attributes> options in derivated modules. This allow users
+to override the default behavior defined in your module with command line
+options.
+
+=head2 OVERRIDING THE found_string FUNCTION
+
+Another simple step is to override the function "found_string", which
+receives the extracted strings from the parser, in order to translate them.
+There you can control which strings you want to translate, and perform
+transformations to them before or after the translation itself.
+
+It receives the extracted text, the reference on where it was, and a hash
+that contains extra information to control what strings to translate, how
+to translate them and to generate the comment.
+
+The content of these options depends on the kind of string it is (specified in an 
+entry of this hash):
+
+=over
+
+=item type="tag"
+
+The found string is the content of a translatable tag. The entry "tag_options"
+contains the option characters in front of the tag hierarchy in the module
+"tags" option.
+
+=item type="attribute"
+
+Means that the found string is the value of a translatable attribute. The
+entry "attribute" has the name of the attribute.
+
+=back
+
+It must return the text that will replace the original in the translated
+document. Here's a basic example of this function:
+
+  sub found_string {
+    my ($self,$text,$ref,$options)=@_;
+    $text = $self->translate($text,$ref,"type ".$options->{'type'},
+      'wrap'=>$self->{options}{'wrap'});
+    return $text;
+  }
+
+There's another simple example in the new Dia module, which only filters
+some strings.
+
+=cut
+
+sub found_string {
+	my ($self,$text,$ref,$options)=@_;
+
+	if ($text =~ m/^\s*$/s) {
+		return $text;
+	}
+
+	my $comment;
+	my $wrap = $self->{options}{'wrap'};
+
+	if ($options->{'type'} eq "tag") {
+		$comment = "Content of: ".$self->get_path;
+
+		if($options->{'tag_options'} =~ /w/) {
+			$wrap = 1;
+		}
+		if($options->{'tag_options'} =~ /W/) {
+			$wrap = 0;
+		}
+	} elsif ($options->{'type'} eq "attribute") {
+		$comment = "Attribute '".$options->{'attribute'}."' of: ".$self->get_path;
+	} elsif ($options->{'type'} eq "CDATA") {
+		$comment = "CDATA";
+		$wrap = 0;
+	} else {
+		die wrap_ref_mod($ref, "po4a::xml", dgettext("po4a", "Internal error: unknown type identifier '%s'."), $options->{'type'});
+	}
+	$text = $self->translate($text,$ref,$comment,'wrap'=>$wrap, comment => $options->{'comments'});
+	return $text;
+}
+
+=head2 MODIFYING TAG TYPES (TODO)
+
+This is a more complex one, but it enables a (almost) total customization.
+It's based in a list of hashes, each one defining a tag type's behavior. The
+list should be sorted so that the most general tags are after the most
+concrete ones (sorted first by the beginning and then by the end keys). To
+define a tag type you'll have to make a hash with the following keys:
+
+=over 4
+
+=item beginning
+
+Specifies the beginning of the tag, after the "E<lt>".
+
+=item end
+
+Specifies the end of the tag, before the "E<gt>".
+
+=item breaking
+
+It says if this is a breaking tag class.  A non-breaking (inline) tag is one
+that can be taken as part of the content of another tag.  It can take the
+values false (0), true (1) or undefined.  If you leave this undefined, you'll
+have to define the f_breaking function that will say whether a concrete tag of
+this class is a breaking tag or not.
+
+=item f_breaking
+
+It's a function that will tell if the next tag is a breaking one or not.  It
+should be defined if the "breaking" option is not.
+
+=item f_extract
+
+If you leave this key undefined, the generic extraction function will have to
+extract the tag itself.  It's useful for tags that can have other tags or
+special structures in them, so that the main parser doesn't get mad.  This
+function receives a boolean that says if the tag should be removed from the
+input stream or not.
+
+=item f_translate
+
+This function receives the tag (in the get_string_until() format) and returns
+the translated tag (translated attributes or all needed transformations) as a
+single string.
+
+=back
+
+=cut
+
+##### Generic XML tag types #####' 
+
+our @tag_types = ( 
+	{	beginning	=> "!--#",
+		end		=> "--",
+		breaking	=> 0,
+		f_extract	=> \&tag_extract_comment,
+		f_translate	=> \&tag_trans_comment},
+	{	beginning	=> "!--",
+		end		=> "--",
+		breaking	=> 0,
+		f_extract	=> \&tag_extract_comment,
+		f_translate	=> \&tag_trans_comment},
+	{	beginning	=> "?xml",
+		end		=> "?",
+		breaking	=> 1,
+		f_translate	=> \&tag_trans_xmlhead},
+	{	beginning	=> "?",
+		end		=> "?",
+		breaking	=> 1,
+		f_translate	=> \&tag_trans_procins},
+	{	beginning	=> "!DOCTYPE",
+		end		=> "",
+		breaking	=> 1,
+		f_extract	=> \&tag_extract_doctype,
+		f_translate	=> \&tag_trans_doctype},
+	{	beginning	=> "![CDATA[",
+		end		=> "",
+		breaking	=> 1,
+		f_extract	=> \&CDATA_extract,
+		f_translate	=> \&CDATA_trans},
+	{	beginning	=> "/",
+		end		=> "",
+		f_breaking	=> \&tag_break_close,
+		f_translate	=> \&tag_trans_close},
+	{	beginning	=> "",
+		end		=> "/",
+		f_breaking	=> \&tag_break_alone,
+		f_translate	=> \&tag_trans_alone},
+	{	beginning	=> "",
+		end		=> "",
+		f_breaking	=> \&tag_break_open,
+		f_translate	=> \&tag_trans_open}
+);
+
+sub tag_extract_comment {
+	my ($self,$remove)=(shift,shift);
+	my ($eof,@tag)=$self->get_string_until('-->',{include=>1,remove=>$remove});
+	return ($eof,@tag);
+}
+
+sub tag_trans_comment {
+	my ($self,@tag)=@_;
+	return $self->join_lines(@tag);
+}
+
+sub tag_trans_xmlhead {
+	my ($self,@tag)=@_;
+
+	# We don't have to translate anything from here: throw away references
+	my $tag = $self->join_lines(@tag);
+	$tag =~ /encoding=(("|')|)(.*?)(\s|\2)/s;
+	my $in_charset=$3;
+	$self->detected_charset($in_charset);
+	my $out_charset=$self->get_out_charset;
+
+	if (defined $in_charset) {
+		$tag =~ s/$in_charset/$out_charset/;
+	} else {
+		if ($tag =~ m/standalone/) {
+			$tag =~ s/(standalone)/encoding="$out_charset" $1/;
+		} else {
+			$tag.= " encoding=\"$out_charset\"";
+		}
+	}
+
+	return $tag;
+}
+
+sub tag_trans_procins {
+	my ($self,@tag)=@_;
+	return $self->join_lines(@tag);
+}
+
+sub tag_extract_doctype {
+	my ($self,$remove)=(shift,shift);
+
+	# Check if there is an internal subset (between []).
+	my ($eof,@tag)=$self->get_string_until('>',{include=>1,unquoted=>1});
+	my $parity = 0;
+	my $paragraph = "";
+	map { $parity = 1 - $parity; $paragraph.= $parity?$_:""; } @tag;
+	my $found = 0;
+	if ($paragraph =~ m/<.*\[.*</s) {
+		$found = 1
+	}
+
+	if (not $found) {
+		($eof,@tag)=$self->get_string_until('>',{include=>1,remove=>$remove,unquoted=>1});
+	} else {
+		($eof,@tag)=$self->get_string_until(']\s*>',{include=>1,remove=>$remove,unquoted=>1,regex=>1});
+	}
+	return ($eof,@tag);
+}
+
+sub tag_trans_doctype {
+# This check is not really reliable.  There are system and public
+# identifiers.  Only the public one could be checked reliably.
+	my ($self,@tag)=@_;
+	if (defined $self->{options}{'doctype'} ) {
+		my $doctype = $self->{options}{'doctype'};
+		if ( $tag[0] !~ /\Q$doctype\E/i ) {
+			warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Bad document type. '%s' expected. You can fix this warning with a -o doctype option, or ignore this check with -o doctype=\"\"."), $doctype);
+		}
+	}
+	my $i = 0;
+	my $basedir = $tag[1];
+	$basedir =~ s/:[0-9]+$//;
+	$basedir = dirname($basedir);
+
+	while ( $i < $#tag ) {
+		my $t = $tag[$i];
+		my $ref = $tag[$i+1];
+		if ( $t =~ /^(\s*<!ENTITY\s+)(.*)$/is ) {
+			my $part1 = $1;
+			my $part2 = $2;
+			my $includenow = 0;
+			my $file = 0;
+			my $name = "";
+			if ($part2 =~ /^(%\s+)(.*)$/s ) {
+				$part1.= $1;
+				$part2 = $2;
+				$includenow = 1;
+			}
+			$part2 =~ /^(\S+)(\s+)(.*)$/s;
+			$name = $1;
+			$part1.= $1.$2;
+			$part2 = $3;
+			if ( $part2 =~ /^(SYSTEM\s+)(.*)$/is ) {
+				$part1.= $1;
+				$part2 = $2;
+				$file = 1;
+				if ($self->{options}{'includeexternal'}) {
+					$entities{$name} = $part2;
+					$entities{$name} =~ s/^"?(.*?)".*$/$1/s;
+					$entities{$name} = File::Spec->catfile($basedir, $entities{$name});
+				}
+			}
+			if ((not $file) and (not $includenow)) {
+			    if ($part2 =~ m/^\s*(["'])(.*)\1(\s*>.*)$/s) {
+				my $comment = "Content of the $name entity";
+				my $quote = $1;
+				my $text = $2;
+				$part2 = $3;
+				$text = $self->translate($text,
+				                         $ref,
+				                         $comment,
+				                         'wrap'=>1);
+				$t = $part1."$quote$text$quote$part2";
+			    }
+			}
+#			print $part1."\n";
+#			print $name."\n";
+#			print $part2."\n";
+		}
+		$tag[$i] = $t;
+		$i += 2;
+	}
+	return $self->join_lines(@tag);
+}
+
+sub tag_break_close {
+	my ($self,@tag)=@_;
+	my $struct = $self->get_path;
+	my $options = $self->get_translate_options($struct);
+	if ($options =~ m/[ip]/) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+sub tag_trans_close {
+	my ($self,@tag)=@_;
+	my $name = $self->get_tag_name(@tag);
+
+	my $test = pop @path;
+	if (!defined($test) || $test ne $name ) {
+		my $ontagerror = $self->{options}{'ontagerror'};
+		if ($ontagerror eq "warn") {
+			warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong.  Continuing..."), $name);
+		} elsif ($ontagerror ne "silent") {
+			die wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong."), $name);
+		}
+	}
+	return $self->join_lines(@tag);
+}
+
+sub CDATA_extract {
+	my ($self,$remove)=(shift,shift);
+        my ($eof, @tag) = $self->get_string_until(']]>',{include=>1,unquoted=>0,remove=>$remove});
+
+	return ($eof, @tag);
+}
+
+sub CDATA_trans {
+	my ($self,@tag)=@_;
+	return $self->found_string($self->join_lines(@tag),
+	                           $tag[1],
+	                           {'type' => "CDATA"});
+}
+
+sub tag_break_alone {
+	my ($self,@tag)=@_;
+	my $struct = $self->get_path($self->get_tag_name(@tag));
+	if ($self->get_translate_options($struct) =~ m/i/) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+sub tag_trans_alone {
+	my ($self,@tag)=@_;
+	my $name = $self->get_tag_name(@tag);
+	push @path, $name;
+
+	$name = $self->treat_attributes(@tag);
+
+	pop @path;
+	return $name;
+}
+
+sub tag_break_open {
+	my ($self,@tag)=@_;
+	my $struct = $self->get_path($self->get_tag_name(@tag));
+	my $options = $self->get_translate_options($struct);
+	if ($options =~ m/[ip]/) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+sub tag_trans_open {
+	my ($self,@tag)=@_;
+	my $name = $self->get_tag_name(@tag);
+	push @path, $name;
+
+	$name = $self->treat_attributes(@tag);
+
+	return $name;
+}
+
+##### END of Generic XML tag types #####
+
+=head1 INTERNAL FUNCTIONS used to write derivated parsers
+
+=head2 WORKING WITH TAGS
+
+=over 4
+
+=item get_path()
+
+This function returns the path to the current tag from the document's root,
+in the form E<lt>htmlE<gt>E<lt>bodyE<gt>E<lt>pE<gt>.
+
+An additional array of tags (without brackets) can be passed in argument.
+These path elements are added to the end of the current path.
+
+=cut
+
+sub get_path {
+	my $self = shift;
+	my @add = @_;
+	if ( @path > 0 or @add > 0 ) {
+		return "<".join("><",@path,@add).">";
+	} else {
+		return "outside any tag (error?)";
+	}
+}
+
+=item tag_type()
+
+This function returns the index from the tag_types list that fits to the next
+tag in the input stream, or -1 if it's at the end of the input file.
+
+=cut
+
+sub tag_type {
+	my $self = shift;
+	my ($line,$ref) = $self->shiftline();
+	my ($match1,$match2);
+	my $found = 0;
+	my $i = 0;
+
+	if (!defined($line)) { return -1; }
+
+	$self->unshiftline($line,$ref);
+	my ($eof,@lines) = $self->get_string_until(">",{include=>1,unquoted=>1});
+	my $line2 = $self->join_lines(@lines);
+	while (!$found && $i < @tag_types) {
+		($match1,$match2) = ($tag_types[$i]->{beginning},$tag_types[$i]->{end});
+		if ($line =~ /^<\Q$match1\E/) {
+			if (!defined($tag_types[$i]->{f_extract})) {
+#print substr($line2,length($line2)-1-length($match2),1+length($match2))."\n";
+				if (defined($line2) and $line2 =~ /\Q$match2\E>$/) {
+					$found = 1;
+#print "YES: <".$match1." ".$match2.">\n";
+				} else {
+#print "NO: <".$match1." ".$match2.">\n";
+					$i++;
+				}
+			} else {
+				$found = 1;
+			}
+		} else {
+			$i++;
+		}
+	}
+	if (!$found) {
+		#It should never enter here, unless you undefine the most
+		#general tags (as <...>)
+		die "po4a::xml: Unknown tag type: ".$line."\n";
+	} else {
+		return $i;
+	}
+}
+
+=item extract_tag($$)
+
+This function returns the next tag from the input stream without the beginning
+and end, in an array form, to maintain the references from the input file.  It
+has two parameters: the type of the tag (as returned by tag_type) and a
+boolean, that indicates if it should be removed from the input stream.
+
+=cut
+
+sub extract_tag {
+	my ($self,$type,$remove) = (shift,shift,shift);
+	my ($match1,$match2) = ($tag_types[$type]->{beginning},$tag_types[$type]->{end});
+	my ($eof,@tag);
+	if (defined($tag_types[$type]->{f_extract})) {
+		($eof,@tag) = &{$tag_types[$type]->{f_extract}}($self,$remove);
+	} else {
+		($eof,@tag) = $self->get_string_until($match2.">",{include=>1,remove=>$remove,unquoted=>1});
+	}
+	$tag[0] =~ /^<\Q$match1\E(.*)$/s;
+	$tag[0] = $1;
+	$tag[$#tag-1] =~ /^(.*)\Q$match2\E>$/s;
+	$tag[$#tag-1] = $1;
+	return ($eof,@tag);
+}
+
+=item get_tag_name(@)
+
+This function returns the name of the tag passed as an argument, in the array
+form returned by extract_tag.
+
+=cut
+
+sub get_tag_name {
+	my ($self,@tag)=@_;
+	$tag[0] =~ /^(\S*)/;
+	return $1;
+}
+
+=item breaking_tag()
+
+This function returns a boolean that says if the next tag in the input stream
+is a breaking tag or not (inline tag).  It leaves the input stream intact.
+
+=cut
+
+sub breaking_tag {
+	my $self = shift;
+	my $break;
+
+	my $type = $self->tag_type;
+	if ($type == -1) { return 0; }
+
+#print "TAG TYPE = ".$type."\n";
+	$break = $tag_types[$type]->{breaking};
+	if (!defined($break)) {
+		# This tag's breaking depends on its content
+		my ($eof,@lines) = $self->extract_tag($type,0);
+		$break = &{$tag_types[$type]->{f_breaking}}($self,@lines);
+	}
+#print "break = ".$break."\n";
+	return $break;
+}
+
+=item treat_tag()
+
+This function translates the next tag from the input stream.  Using each
+tag type's custom translation functions.
+
+=cut
+
+sub treat_tag {
+	my $self = shift;
+	my $type = $self->tag_type;
+
+	my ($match1,$match2) = ($tag_types[$type]->{beginning},$tag_types[$type]->{end});
+	my ($eof,@lines) = $self->extract_tag($type,1);
+
+	$lines[0] =~ /^(\s*)(.*)$/s;
+	my $space1 = $1;
+	$lines[0] = $2;
+	$lines[$#lines-1] =~ /^(.*?)(\s*)$/s;
+	my $space2 = $2;
+	$lines[$#lines-1] = $1;
+
+	# Calling this tag type's specific handling (translation of
+	# attributes...)
+	my $line = &{$tag_types[$type]->{f_translate}}($self,@lines);
+	$self->pushline("<".$match1.$space1.$line.$space2.$match2.">");
+	return $eof;
+}
+
+=item tag_in_list($@)
+
+This function returns a string value that says if the first argument (a tag
+hierarchy) matches any of the tags from the second argument (a list of tags
+or tag hierarchies). If it doesn't match, it returns 0. Else, it returns the
+matched tag's options (the characters in front of the tag) or 1 (if that tag
+doesn't have options).
+
+=back
+
+=cut
+sub tag_in_list ($$$) {
+	my ($self,$path,$list) = @_;
+	if ($self->{options}{'caseinsensitive'}) {
+		$path = lc $path;
+	}
+
+	while (1) {
+		if (defined $list->{$path}) {
+			if (length $list->{$path}) {
+				return $list->{$path};
+			} else {
+				return 1;
+			}
+		}
+		last unless ($path =~ m/</);
+		$path =~ s/^<.*?>//;
+	} 
+
+	return 0;
+}
+
+=head2 WORKING WITH ATTRIBUTES
+
+=over 4
+
+=item treat_attributes(@)
+
+This function handles the translation of the tags' attributes. It receives the tag
+without the beginning / end marks, and then it finds the attributes, and it
+translates the translatable ones (specified by the module option "attributes").
+This returns a plain string with the translated tag.
+
+=back
+
+=cut
+
+sub treat_attributes {
+	my ($self,@tag)=@_;
+
+	$tag[0] =~ /^(\S*)(.*)/s;
+	my $text = $1;
+	$tag[0] = $2;
+
+	while (@tag) {
+		my $complete = 1;
+
+		$text .= $self->skip_spaces(\@tag);
+		if (@tag) {
+			# Get the attribute's name
+			$complete = 0;
+
+			$tag[0] =~ /^([^\s=]+)(.*)/s;
+			my $name = $1;
+			my $ref = $tag[1];
+			$tag[0] = $2;
+			$text .= $name;
+			$text .= $self->skip_spaces(\@tag);
+			if (@tag) {
+				# Get the '='
+				if ($tag[0] =~ /^=(.*)/s) {
+					$tag[0] = $1;
+					$text .= "=";
+					$text .= $self->skip_spaces(\@tag);
+					if (@tag) {
+						# Get the value
+						my $value="";
+						$ref=$tag[1];
+						my $quot=substr($tag[0],0,1);
+						if ($quot ne "\"" and $quot ne "'") {
+							# Unquoted value
+							$quot="";
+							$tag[0] =~ /^(\S+)(.*)/s;
+							$value = $1;
+							$tag[0] = $2;
+						} else {
+							# Quoted value
+							$text .= $quot;
+							$tag[0] =~ /^\Q$quot\E(.*)/s;
+							$tag[0] = $1;
+							while ($tag[0] !~ /\Q$quot\E/) {
+								$value .= $tag[0];
+								shift @tag;
+								shift @tag;
+							}
+							$tag[0] =~ /^(.*?)\Q$quot\E(.*)/s;
+							$value .= $1;
+							$tag[0] = $2;
+						}
+						$complete = 1;
+						if ($self->tag_in_list($self->get_path.$name,$self->{attributes})) {
+							$text .= $self->found_string($value, $ref, { type=>"attribute", attribute=>$name });
+						} else {
+							print wrap_ref_mod($ref, "po4a::xml", dgettext("po4a", "Content of attribute %s excluded: %s"), $self->get_path.$name, $value)
+							       if $self->debug();
+							$text .= $self->recode_skipped_text($value);
+						}
+						$text .= $quot;
+					}
+				}
+			}
+          
+			unless ($complete) {
+				my $ontagerror = $self->{options}{'ontagerror'};
+				if ($ontagerror eq "warn") {
+					warn wrap_ref_mod($ref, "po4a::xml", dgettext ("po4a", "Bad attribute syntax.  Continuing..."));
+				} elsif ($ontagerror ne "silent") {
+					die wrap_ref_mod($ref, "po4a::xml", dgettext ("po4a", "Bad attribute syntax"));
+				}
+			}
+		}
+	}
+	return $text;
+}
+
+# Returns an empty string if the content in the $path should not be
+# translated.
+#
+# Otherwise, returns the set of options for translation:
+#   w: the content shall be re-wrapped
+#   W: the content shall not be re-wrapped
+#   i: the tag shall be inlined
+#   p: a placeholder shall replace the tag (and its content)
+#
+# A translatable inline tag in an untranslated tag is treated as a translatable breaking tag.
+my %translate_options_cache;
+sub get_translate_options {
+	my $self = shift;
+	my $path = shift;
+
+	if (defined $translate_options_cache{$path}) {
+		return $translate_options_cache{$path};
+	}
+
+	my $options = "";
+	my $translate = 0;
+	my $usedefault = 1;
+
+	my $inlist = 0;
+	my $tag = $self->get_tag_from_list($path, $self->{tags});
+	if (defined $tag) {
+		$inlist = 1;
+	}
+	if ($self->{options}{'tagsonly'} eq $inlist) {
+		$usedefault = 0;
+		if (defined $tag) {
+			$options = $tag;
+			$options =~ s/<.*$//;
+		} else {
+			if ($self->{options}{'wrap'}) {
+				$options = "w";
+			} else {
+				$options = "W";
+			}
+		}
+		$translate = 1;
+	}
+
+# TODO: a less precise set of tags should not override a more precise one
+	# The tags and tagsonly options are deprecated.
+	# The translated and untranslated options have an higher priority.
+	$tag = $self->get_tag_from_list($path, $self->{translated});
+	if (defined $tag) {
+		$usedefault = 0;
+		$options = $tag;
+		$options =~ s/<.*$//;
+		$translate = 1;
+	}
+
+	if ($translate and $options !~ m/w/i) {
+		$options .= ($self->{options}{'wrap'})?"w":"W";
+	}
+
+	if (not defined $tag) {
+		$tag = $self->get_tag_from_list($path, $self->{untranslated});
+		if (defined $tag) {
+			$usedefault = 0;
+			$options = "";
+			$translate = 0;
+		}
+	}
+
+	$tag = $self->get_tag_from_list($path, $self->{inline});
+	if (defined $tag) {
+		$usedefault = 0;
+		$options .= "i";
+	} else {
+		$tag = $self->get_tag_from_list($path, $self->{placeholder});
+		if (defined $tag) {
+			$usedefault = 0;
+			$options .= "p";
+		}
+	}
+
+	if ($usedefault) {
+		$options = $self->{options}{'defaulttranslateoption'};
+	}
+
+	# A translatable inline tag in an untranslated tag is treated as a
+	# translatable breaking tag.
+	if ($options =~ m/i/) {
+		my $ppath = $path;
+		$ppath =~ s/<[^>]*>$//;
+		my $poptions = $self->get_translate_options ($ppath);
+		if ($poptions eq "") {
+			$options =~ s/i//;
+		}
+	}
+
+	if ($options =~ m/i/ and $self->{options}{'foldattributes'}) {
+		$options .= "f";
+	}
+
+	$translate_options_cache{$path} = $options;
+	return $options;
+}
+
+
+# Return the tag (or biggest set of tags) of a list which matches with the
+# given path.
+#
+# The tag (or set of tags) is returned with its options.
+#
+# If no tags could match the path, undef is returned.
+sub get_tag_from_list ($$$) {
+	my ($self,$path,$list) = @_;
+	if ($self->{options}{'caseinsensitive'}) {
+		$path = lc $path;
+	}
+
+	while (1) {
+		if (defined $list->{$path}) {
+			return $list->{$path}.$path;
+		}
+		last unless ($path =~ m/</);
+		$path =~ s/^<.*?>//;
+	}
+
+	return undef;
+}
+
+
+
+sub treat_content {
+	my $self = shift;
+	my $blank="";
+	# Indicates if the paragraph will have to be translated
+	my $translate = "";
+
+	my ($eof,@paragraph)=$self->get_string_until('<',{remove=>1});
+
+	while (!$eof and !$self->breaking_tag) {
+	NEXT_TAG:
+		my @text;
+		my $type = $self->tag_type;
+		my $f_extract = $tag_types[$type]->{'f_extract'};
+		if (    defined($f_extract)
+		    and $f_extract eq \&tag_extract_comment) {
+			# Remove the content of the comments
+			($eof, @text) = $self->extract_tag($type,1);
+			$text[$#text-1] .= "\0";
+			if ($tag_types[$type]->{'beginning'} eq "!--#") {
+				$text[0] = "#".$text[0];
+			}
+			push @comments, @text;
+		} else {
+			my ($tmpeof, @tag) = $self->extract_tag($type,0);
+			# Append the found inline tag
+			($eof,@text)=$self->get_string_until('>',
+			                                     {include=>1,
+			                                      remove=>1,
+			                                      unquoted=>1});
+			# Append or remove the opening/closing tag from
+			# the tag path
+			if ($tag_types[$type]->{'end'} eq "") {
+				if ($tag_types[$type]->{'beginning'} eq "") {
+					# Opening inline tag
+					my $cur_tag_name = $self->get_tag_name(@tag);
+					my $t_opts = $self->get_translate_options($self->get_path($cur_tag_name));
+					if ($t_opts =~ m/p/) {
+						# We enter a new holder.
+						# Append a <placeholder ...> tag to the current
+						# paragraph, and save the @paragraph in the
+						# current holder.
+						my $last_holder = $save_holders[$#save_holders];
+						my $placeholder_str = "<placeholder type=\"".$cur_tag_name."\" id=\"".($#{$last_holder->{'sub_translations'}}+1)."\"/>";
+						push @paragraph, ($placeholder_str, $text[1]);
+						my @saved_paragraph = @paragraph;
+
+						$last_holder->{'paragraph'} = \@saved_paragraph;
+
+						# Then we must push a new holder
+						my @new_paragraph = ();
+						my @sub_translations = ();
+						my %folded_attributes;
+						my %new_holder = ('paragraph' => \@new_paragraph,
+						                  'open' => $text[0],
+						                  'translation' => "",
+						                  'close' => undef,
+						                  'sub_translations' => \@sub_translations,
+						                  'folded_attributes' => \%folded_attributes);
+						push @save_holders, \%new_holder;
+						@text = ();
+
+						# The current @paragraph
+						# (for the current holder)
+						# is empty.
+						@paragraph = ();
+					} elsif ($t_opts =~ m/f/) {
+						my $tag_full = $self->join_lines(@text);
+						my $tag_ref = $text[1];
+						if ($tag_full =~ m/^<\s*\S+\s+\S.*>$/s) {
+							my $holder = $save_holders[$#save_holders];
+							my $id = 0;
+							foreach (keys %{$holder->{folded_attributes}}) {
+								$id = $_ + 1 if ($_ >= $id);
+							}
+							$holder->{folded_attributes}->{$id} = $tag_full;
+
+							@text = ("<$cur_tag_name po4a-id=$id>", $tag_ref);
+						}
+					}
+					push @path, $cur_tag_name;
+				} elsif ($tag_types[$type]->{'beginning'} eq "/") {
+					# Closing inline tag
+
+					# Check if this is closing the
+					# last opening tag we detected.
+					my $test = pop @path;
+					my $name = $self->get_tag_name(@tag);
+					if (!defined($test) ||
+					    $test ne $name ) {
+						my $ontagerror = $self->{options}{'ontagerror'};
+						if ($ontagerror eq "warn") {
+							warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong.  Continuing..."), $name);
+						} elsif ($ontagerror ne "silent") {
+							die wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong."), $name);
+						}
+					}
+
+					if ($self->get_translate_options($self->get_path($self->get_tag_name(@tag))) =~ m/p/) {
+						# This closes the current holder.
+
+						push @path, $self->get_tag_name(@tag);
+						# Now translate this paragraph if needed.
+						# This will call pushline and append the
+						# translation to the current holder's translation.
+						$self->translate_paragraph(@paragraph);
+						pop @path;
+
+						# Now that this holder is closed, we can remove
+						# the holder from the stack.
+						my $holder = pop @save_holders;
+						# We need to keep the translation of this holder
+						my $translation = $holder->{'open'}.$holder->{'translation'}.$text[0];
+						# FIXME: @text could be multilines.
+
+						@text = ();
+
+						# Then we store the translation in the previous
+						# holder's sub_translations array
+						my $previous_holder = $save_holders[$#save_holders];
+						push @{$previous_holder->{'sub_translations'}}, $translation;
+						# We also need to restore the @paragraph array, as
+						# it was before we encountered the holder.
+						@paragraph = @{$previous_holder->{'paragraph'}};
+					}
+				}
+			}
+			push @paragraph, @text;
+		}
+
+		# Next tag
+		($eof,@text)=$self->get_string_until('<',{remove=>1});
+		if ($#text > 0) {
+			# Check if text (extracted after the inline tag)
+			# has to be translated
+			push @paragraph, @text;
+		}
+	}
+
+	# This strips the extracted strings
+	# (only if you don't specify the 'nostrip' option, and if the
+	# paragraph can be re-wrapped)
+	$translate = $self->get_translate_options($self->get_path);
+	if (!$self->{options}{'nostrip'} and $translate !~ m/W/) {
+		my $clean = 0;
+		# Clean the beginning
+		while (!$clean and $#paragraph > 0) {
+			$paragraph[0] =~ /^(\s*)(.*)/s;
+			my $match = $1;
+			if ($paragraph[0] eq $match) {
+				if ($match ne "") {
+					$self->pushline($match);
+				}
+				shift @paragraph;
+				shift @paragraph;
+			} else {
+				$paragraph[0] = $2;
+				if ($match ne "") {
+					$self->pushline($match);
+				}
+				$clean = 1;
+			}
+		}
+		$clean = 0;
+		# Clean the end
+		while (!$clean and $#paragraph > 0) {
+			$paragraph[$#paragraph-1] =~ /^(.*?)(\s*)$/s;
+			my $match = $2;
+			if ($paragraph[$#paragraph-1] eq $match) {
+				if ($match ne "") {
+					$blank = $match.$blank;
+				}
+				pop @paragraph;
+				pop @paragraph;
+			} else {
+				$paragraph[$#paragraph-1] = $1;
+				if ($match ne "") {
+					$blank = $match.$blank;
+				}
+				$clean = 1;
+			}
+		}
+	}
+
+	# Translate the string when needed
+	# This will either push the translation in the translated document or
+	# in the current holder translation.
+	$self->translate_paragraph(@paragraph);
+
+	# Push the trailing blanks
+	if ($blank ne "") {
+		$self->pushline($blank);
+	}
+	return $eof;
+}
+
+# Translate a @paragraph array of (string, reference).
+# The $translate argument indicates if the strings must be translated or
+# just pushed
+sub translate_paragraph {
+	my $self = shift;
+	my @paragraph = @_;
+	my $translate = $self->get_translate_options($self->get_path);
+
+	while (    (scalar @paragraph)
+	       and ($paragraph[0] =~ m/^\s*\n/s)) {
+		$self->pushline($paragraph[0]);
+		shift @paragraph;
+		shift @paragraph;
+	}
+
+	my $comments;
+	while (@comments) {
+		my ($comment,$eoc);
+		do {
+			my ($t,$l) = (shift @comments, shift @comments);
+			$t =~ s/\n?(\0)?$//;
+			$eoc = $1;
+			$comment .= "\n" if defined $comment;
+			$comment .= $t;
+		} until ($eoc);
+		$comments .= "\n" if defined $comments;
+		$comments .= $comment;
+		$self->pushline("<!--".$comment."-->\n") if defined $comment;
+	}
+	@comments = ();
+
+	if ($self->{options}{'cpp'}) {
+		my @tmp = @paragraph;
+		@paragraph = ();
+		while (@tmp) {
+			my ($t,$l) = (shift @tmp, shift @tmp);
+			# #include can be followed by a filename between
+			# <> brackets. In that case, the argument won't be
+			# handled in the same call to translate_paragraph.
+			# Thus do not try to match "include ".
+			if ($t =~ m/^#[ \t]*(if |endif|undef |include|else|ifdef |ifndef |define )/si) {
+				if (@paragraph) {
+					$self->translate_paragraph(@paragraph);
+					@paragraph = ();
+					$self->pushline("\n");
+				}
+				$self->pushline($t);
+			} else {
+				push @paragraph, ($t,$l);
+			}
+		}
+	}
+
+	my $para = $self->join_lines(@paragraph);
+	if ( length($para) > 0 ) {
+		if ($translate ne "") {
+			# This tag should be translated
+			$self->pushline($self->found_string(
+				$para,
+				$paragraph[1], {
+					type=>"tag",
+					tag_options=>$translate,
+					comments=>$comments
+				}));
+		} else {
+			# Inform that this tag isn't translated in debug mode
+			print wrap_ref_mod($paragraph[1], "po4a::xml", dgettext ("po4a", "Content of tag %s excluded: %s"), $self->get_path, $para)
+			       if $self->debug();
+			$self->pushline($self->recode_skipped_text($para));
+		}
+	}
+	# Now the paragraph is fully translated.
+	# If we have all the holders' translation, we can replace the
+	# placeholders by their translations.
+	# We must wait to have all the translations because the holders are
+	# numbered.
+	{
+		my $holder = $save_holders[$#save_holders];
+		my $translation = $holder->{'translation'};
+
+		# Count the number of <placeholder ...> in $translation
+		my $count = 0;
+		my $str = $translation;
+		while (    (defined $str)
+		       and ($str =~ m/^.*?<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>(.*)$/s)) {
+			$count += 1;
+			$str = $2;
+			if ($holder->{'sub_translations'}->[$1] =~ m/<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>/s) {
+				$count = -1;
+				last;
+			}
+		}
+
+		if (    (defined $translation)
+		    and (scalar(@{$holder->{'sub_translations'}}) == $count)) {
+			# OK, all the holders of the current paragraph are
+			# closed (and translated).
+			# Replace them by their translation.
+			while ($translation =~ m/^(.*?)<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>(.*)$/s) {
+				# FIXME: we could also check that
+				#          * the holder exists
+				#          * all the holders are used
+				$translation = $1.$holder->{'sub_translations'}->[$2].$3;
+			}
+			# We have our translation
+			$holder->{'translation'} = $translation;
+			# And there is no need for any holder in it.
+			my @sub_translations = ();
+			$holder->{'sub_translations'} = \@sub_translations;
+		}
+	}
+
+}
+
+
+
+=head2 WORKING WITH THE MODULE OPTIONS
+
+=over 4
+
+=item treat_options()
+
+This function fills the internal structures that contain the tags, attributes
+and inline data with the options of the module (specified in the command-line
+or in the initialize function).
+
+=back
+
+=cut
+
+sub treat_options {
+	my $self = shift;
+
+	if ($self->{options}{'caseinsensitive'}) {
+		$self->{options}{'nodefault'}             = lc $self->{options}{'nodefault'};
+		$self->{options}{'tags'}                  = lc $self->{options}{'tags'};
+		$self->{options}{'break'}                 = lc $self->{options}{'break'};
+		$self->{options}{'_default_break'}        = lc $self->{options}{'_default_break'};
+		$self->{options}{'translated'}            = lc $self->{options}{'translated'};
+		$self->{options}{'_default_translated'}   = lc $self->{options}{'_default_translated'};
+		$self->{options}{'untranslated'}          = lc $self->{options}{'untranslated'};
+		$self->{options}{'_default_untranslated'} = lc $self->{options}{'_default_untranslated'};
+		$self->{options}{'attributes'}            = lc $self->{options}{'attributes'};
+		$self->{options}{'_default_attributes'}   = lc $self->{options}{'_default_attributes'};
+		$self->{options}{'inline'}                = lc $self->{options}{'inline'};
+		$self->{options}{'_default_inline'}       = lc $self->{options}{'_default_inline'};
+		$self->{options}{'placeholder'}           = lc $self->{options}{'placeholder'};
+		$self->{options}{'_default_placeholder'}  = lc $self->{options}{'_default_placeholder'};
+	}
+
+	$self->{options}{'nodefault'} =~ /^\s*(.*)\s*$/s;
+	my %list_nodefault;
+	foreach (split(/\s+/s,$1)) {
+		$list_nodefault{$_} = 1;
+	}
+	$self->{nodefault} = \%list_nodefault;
+
+	$self->{options}{'tags'} =~ /^\s*(.*)\s*$/s;
+	if (length $self->{options}{'tags'}) {
+		warn wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "The '%s' option is deprecated. Please use the translated/untranslated and/or break/inline/placeholder categories."), "tags");
+	}
+	foreach (split(/\s+/s,$1)) {
+		$_ =~ m/^(.*?)(<.*)$/;
+		$self->{tags}->{$2} = $1 || "";
+	}
+
+	if ($self->{options}{'tagsonly'}) {
+		warn wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "The '%s' option is deprecated. Please use the translated/untranslated and/or break/inline/placeholder categories."), "tagsonly");
+	}
+
+	$self->{options}{'break'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{break}->{$2} = $1 || "";
+	}
+	$self->{options}{'_default_break'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{break}->{$2} = $1 || ""
+			unless    $list_nodefault{$2}
+			       or defined $self->{break}->{$2};
+	}
+
+	$self->{options}{'translated'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{translated}->{$2} = $1 || "";
+	}
+	$self->{options}{'_default_translated'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{translated}->{$2} = $1 || ""
+			unless    $list_nodefault{$2}
+			       or defined $self->{translated}->{$2};
+	}
+
+	$self->{options}{'untranslated'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{untranslated}->{$2} = $1 || "";
+	}
+	$self->{options}{'_default_untranslated'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{untranslated}->{$2} = $1 || ""
+			unless    $list_nodefault{$2}
+			       or defined $self->{untranslated}->{$2};
+	}
+
+	$self->{options}{'attributes'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		if ($tag =~ m/^(.*?)(<.*)$/) {
+			$self->{attributes}->{$2} = $1 || "";
+		} else {
+			$self->{attributes}->{$tag} = "";
+		}
+	}
+	$self->{options}{'_default_attributes'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		if ($tag =~ m/^(.*?)(<.*)$/) {
+			$self->{attributes}->{$2} = $1 || ""
+				unless    $list_nodefault{$2}
+				       or defined $self->{attributes}->{$2};
+		} else {
+			$self->{attributes}->{$tag} = ""
+				unless    $list_nodefault{$tag}
+				       or defined $self->{attributes}->{$tag};
+		}
+	}
+
+	my @list_inline;
+	$self->{options}{'inline'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{inline}->{$2} = $1 || "";
+	}
+	$self->{options}{'_default_inline'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{inline}->{$2} = $1 || ""
+			unless    $list_nodefault{$2}
+			       or defined $self->{inline}->{$2};
+	}
+
+	$self->{options}{'placeholder'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{placeholder}->{$2} = $1 || "";
+	}
+	$self->{options}{'_default_placeholder'} =~ /^\s*(.*)\s*$/s;
+	foreach my $tag (split(/\s+/s,$1)) {
+		$tag =~ m/^(.*?)(<.*)$/;
+		$self->{placeholder}->{$2} = $1 || ""
+			unless    $list_nodefault{$2}
+			       or defined $self->{placeholder}->{$2};
+	}
+
+	# There should be no translated and untranslated tags
+	foreach my $tag (keys %{$self->{translated}}) {
+		die wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "Tag '%s' both in the %s and %s categories."), $tag, "translated", "untranslated")
+			if defined $self->{untranslated}->{$tag};
+	}
+	# There should be no inline, break, and placeholder tags
+	foreach my $tag (keys %{$self->{inline}}) {
+		die wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "Tag '%s' both in the %s and %s categories."), $tag, "inline", "break")
+			if defined $self->{break}->{$tag};
+		die wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "Tag '%s' both in the %s and %s categories."), $tag, "inline", "placeholder")
+			if defined $self->{placeholder}->{$tag};
+	}
+	foreach my $tag (keys %{$self->{break}}) {
+		die wrap_mod("po4a::xml",
+		             dgettext("po4a",
+		                      "Tag '%s' both in the %s and %s categories."), $tag, "break", "placeholder")
+			if defined $self->{placeholder}->{$tag};
+	}
+}
+
+=head2 GETTING TEXT FROM THE INPUT DOCUMENT
+
+=over
+
+=item get_string_until($%)
+
+This function returns an array with the lines (and references) from the input
+document until it finds the first argument.  The second argument is an options
+hash. Value 0 means disabled (the default) and 1, enabled.
+
+The valid options are:
+
+=over 4
+
+=item include
+
+This makes the returned array to contain the searched text
+
+=item remove
+
+This removes the returned stream from the input
+
+=item unquoted
+
+This ensures that the searched text is outside any quotes
+
+=back
+
+=cut
+
+sub get_string_until {
+	my ($self,$search) = (shift,shift);
+	my $options = shift;
+	my ($include,$remove,$unquoted, $regex) = (0,0,0,0);
+
+	if (defined($options->{include})) { $include = $options->{include}; }
+	if (defined($options->{remove})) { $remove = $options->{remove}; }
+	if (defined($options->{unquoted})) { $unquoted = $options->{unquoted}; }
+	if (defined($options->{regex})) { $regex = $options->{regex}; }
+
+	my ($line,$ref) = $self->shiftline();
+	my (@text,$paragraph);
+	my ($eof,$found) = (0,0);
+
+	$search = "\Q$search\E" unless $regex;
+	while (defined($line) and !$found) {
+		push @text, ($line,$ref);
+		$paragraph .= $line;
+		if ($unquoted) {
+			if ( $paragraph =~ /^((\".*?\")|(\'.*?\')|[^\"\'])*$search/s ) {
+				$found = 1;
+			}
+		} else {
+			if ( $paragraph =~ /$search/s ) {
+				$found = 1;
+			}
+		}
+		if (!$found) {
+			($line,$ref)=$self->shiftline();
+		}
+	}
+
+	if (!defined($line)) { $eof = 1; }
+
+	if ( $found ) {
+		$line = "";
+		if($unquoted) {
+			$paragraph =~ /^(?:(?:\".*?\")|(?:\'.*?\')|[^\"\'])*?$search(.*)$/s;
+			$line = $1;
+			$text[$#text-1] =~ s/\Q$line\E$//s;
+		} else {
+			$paragraph =~ /$search(.*)$/s;
+			$line = $1;
+			$text[$#text-1] =~ s/\Q$line\E$//s;
+		}
+		if(!$include) {
+			$text[$#text-1] =~ /^(.*)($search.*)$/s;
+			$text[$#text-1] = $1;
+			$line = $2.$line;
+		}
+		if (defined($line) and ($line ne "")) {
+			$self->unshiftline ($line,$text[$#text]);
+		}
+	}
+	if (!$remove) {
+		$self->unshiftline (@text);
+	}
+
+	#If we get to the end of the file, we return the whole paragraph
+	return ($eof,@text);
+}
+
+=item skip_spaces(\@)
+
+This function receives as argument the reference to a paragraph (in the format
+returned by get_string_until), skips his heading spaces and returns them as
+a simple string.
+
+=cut
+
+sub skip_spaces {
+	my ($self,$pstring)=@_;
+	my $space="";
+
+	while (@$pstring and (@$pstring[0] =~ /^(\s+)(.*)$/s or @$pstring[0] eq "")) {
+		if (@$pstring[0] ne "") {
+			$space .= $1;
+			@$pstring[0] = $2;
+		}
+
+		if (@$pstring[0] eq "") {
+			shift @$pstring;
+			shift @$pstring;
+		}
+	}
+	return $space;
+}
+
+=item join_lines(@)
+
+This function returns a simple string with the text from the argument array
+(discarding the references).
+
+=cut
+
+sub join_lines {
+	my ($self,@lines)=@_;
+	my ($line,$ref);
+	my $text = "";
+	while ($#lines > 0) {
+		($line,$ref) = (shift @lines,shift @lines);
+		$text .= $line;
+	}
+	return $text;
+}
+
+=back
+
+=head1 STATUS OF THIS MODULE
+
+This module can translate tags and attributes.
+
+=head1 TODO LIST
+
+DOCTYPE (ENTITIES)
+
+There is a minimal support for the translation of entities. They are
+translated as a whole, and tags are not taken into account. Multilines
+entities are not supported and entities are always rewrapped during the
+translation.
+
+MODIFY TAG TYPES FROM INHERITED MODULES
+(move the tag_types structure inside the $self hash?)
+
+=head1 SEE ALSO
+
+L<po4a(7)|po4a.7>, L<Locale::Po4a::TransTractor(3pm)|Locale::Po4a::TransTractor>.
+
+=head1 AUTHORS
+
+ Jordi Vilalta <jvprat@gmail.com>
+ Nicolas François <nicolas.francois@centraliens.net>
+
+=head1 COPYRIGHT AND LICENSE
+
+ Copyright (c) 2004 by Jordi Vilalta  <jvprat@gmail.com>
+ Copyright (c) 2008-2009 by Nicolas François <nicolas.francois@centraliens.net>
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/po4a-translate	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,257 @@
+#! /usr/bin/env perl
+eval 'exec perl -S $0 ${1+"$@"}'
+    if $running_under_some_shell;
+
+# po4a-translate -- translate doc files using a message catalog(ie, po file)
+# $Id: po4a-translate,v 1.41 2009-03-07 12:33:10 nekral-guest Exp $
+#
+# Copyright 2002, 2003, 2004 by Martin Quinson (mquinson#debian.org)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of GPL (see COPYING).
+
+=head1 NAME
+
+po4a-translate - convert a po file back to documentation format
+
+=head1 SYNOPSIS
+
+po4a-translate -f E<lt>fmtE<gt> -m E<lt>master.docE<gt> -p E<lt>XX.poE<gt> -l E<lt>XX.docE<gt>
+
+(XX.doc is the output, all others are inputs)
+
+=head1 DESCRIPTION
+
+The po4a (po for anything) project goal is to ease translations (and more
+interestingly, the maintenance of translations) using gettext tools on
+areas where they were not expected like documentation.
+
+The C<po4a-translate> script is in charge of converting the translation
+(which was done in a po file) under the documentation format back. The
+provided C<po> file should be the translation of the C<pot> file which were
+produced by po4a-gettextize(1).
+
+=head1 OPTIONS
+
+=over 4
+
+=item -f, --format
+
+Format of the documentation you want to handle. Use the --help-format
+option to see the list of available formats.
+
+=item -a, --addendum
+
+Add a file to the resulting file (to put translator's name or a section
+"About this translation", for example). The first line of the file to insert
+should be a PO4A header indicating where it should be added (see section
+I<HOWTO add extra text to translations> in po4a(7)).
+
+=item -A, --addendum-charset
+
+Charset of the addenda. Note that all the addenda should be in the same
+charset.
+
+=item -m, --master
+
+File containing the master document to translate.
+
+=item -M, --master-charset
+
+Charset of the file containing the document to translate.
+
+=item -l, --localized
+
+File where the localized (translated) document should be written.
+
+=item -L, --localized-charset
+
+Charset of the file containing the localized document.
+
+=item -p, --po
+
+File from which the message catalog should be read.
+
+=item -o, --option
+
+Extra option(s) to pass to the format plugin. Specify each option in the
+'name=value' format. See the documentation of each plugin for more
+information about the valid options and their meanings.
+
+=item -k, --keep
+
+Minimal threshold for translation percentage to keep (ie, write) the
+resulting file (default: 80). Ie, by default, files have to be translated
+at at least 80% to get written.
+
+=item -w, --width
+
+Column at which we should wrap the resulting file.
+
+=item -h, --help
+
+Show a short help message.
+
+=item --help-format
+
+List the documentation format understood by po4a.
+
+=item -V, --version
+
+Display the version of the script and exit.
+
+=item -v, --verbose
+
+Increase the verbosity of the program.
+
+=item -d, --debug
+
+Output some debugging information.
+
+=back
+
+=head1 Adding content (beside translations) to generated files
+
+To add some extra content to the generated document beside what you
+translated (like the name of the translator, or a "about this translation"
+section), you should use the C<--addendum> option. 
+
+The first line of the addendum must be a header indicating where to put
+it in the document (it can be before or after a given part of the
+document).  The rest of the file will be added verbatim to the resulting
+file without further processing.
+
+Note that if po4a-translate fails to add one of the given files, it discards
+the whole translation (because the missing file could be the one indicating
+the author, what would prevent the users to contact him to report bugs in
+the translation).
+
+The header has a pretty rigid syntax. For more information on how to use
+this feature and how it works, please refer to the po4a(7) man page.
+
+=head1 SEE ALSO
+
+L<po4a(7)>, L<po4a-gettextize(1)>, L<po4a-updatepo(1)>, L<po4a-normalize(1)>.
+
+
+=head1 AUTHORS
+
+ Denis Barbier <barbier@linuxfr.org>
+ Martin Quinson (mquinson#debian.org)
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2002, 2003, 2004 by SPI, inc.
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
+
+use 5.006;
+use strict;
+use warnings;
+
+use Locale::Po4a::Chooser;
+use Locale::Po4a::TransTractor;
+use Locale::Po4a::Common;
+
+use Pod::Usage qw(pod2usage);
+use Getopt::Long qw(GetOptions);
+
+Locale::Po4a::Common::textdomain("po4a");
+
+sub show_version {
+    Locale::Po4a::Common::show_version("po4a-translate");
+    exit 0;
+}
+
+
+Getopt::Long::Configure('no_auto_abbrev','no_ignore_case');
+my ($outfile,$width,$threshold)=('-',80,80);
+my ($help,$help_fmt,@verbose,$debug,@addfiles,$format,@options);
+my ($master_filename,$po_filename);
+my ($mastchar,$locchar,$addchar);
+GetOptions(
+	'help|h'        => \$help,
+	'help-format'   => \$help_fmt,
+
+	'master|m=s'    => \$master_filename,
+	'localized|l=s' => \$outfile,
+	'po|p=s'        => \$po_filename,
+	'addendum|a=s'  => \@addfiles,
+	'format|f=s'    => \$format,
+
+	'master-charset|M=s'    => \$mastchar,
+	'localized-charset|L=s' => \$locchar,
+	'addendum-charset|A=s' => \$addchar,
+
+	'option|o=s'    => \@options,
+
+	'width|w=s'     => \$width,
+	'verbose|v'     => \@verbose,
+	'debug|d'       => \$debug,
+	'keep|k=s'      => \$threshold,
+
+	'version|V'     => \&show_version
+) or pod2usage();
+
+$help && pod2usage(-verbose => 1, -exitval => 0);
+$help_fmt && Locale::Po4a::Chooser::list(0);
+
+(defined($master_filename) && length($master_filename))||pod2usage();
+(defined($po_filename)     && length($po_filename))    ||pod2usage();
+-e $master_filename || die wrap_msg(gettext("File %s does not exist."), $master_filename);
+-e $po_filename || die wrap_msg(gettext("File %s does not exist."), $po_filename);
+
+my (@pos,@masters);
+push @pos,$po_filename;
+push @masters,$master_filename;
+
+my %options = (
+    "verbose" => scalar @verbose,
+    "debug" => $debug);
+
+foreach (@options) {
+    if (m/^([^=]*)=(.*)$/) {
+	$options{$1}="$2";
+    } else {
+	$options{$_}=1;
+    }
+}
+# parser
+my $doc=Locale::Po4a::Chooser::new($format,%options);
+
+
+# Prepare the document to be used as translator, but not parser
+$doc->process('po_in_name'       => \@pos,
+	      'file_in_name'     => \@masters,
+	      'file_in_charset'  => $mastchar,
+	      'file_out_charset' => $locchar,
+	      'addendum_charset' => $addchar);
+
+my ($percent,$hit,$queries) = $doc->stats();
+my $error=0;
+
+print STDERR wrap_msg(gettext("%s is %s%% translated (%s of %s strings)."),
+    $master_filename, $percent, $hit, $queries)
+  if (scalar @verbose) && ($percent>=$threshold);
+
+
+if ($percent<$threshold)  {
+    print STDERR wrap_msg(gettext("Discard the translation of %s (only %s%% translated; need %s%%)."),
+	$master_filename, $percent, $threshold);
+    unlink($outfile) if (-e $outfile);
+} else {
+    foreach my $add (@addfiles) {
+	unless ($doc->addendum($add)) {
+	    unlink($outfile) if (-e $outfile);
+	    die wrap_msg(gettext("Discard the translation of %s (addendum %s does not apply)."),
+		$master_filename, $add);
+	}
+    }
+    $doc->write($outfile);
+}
+
+1;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/po4a/po4a-updatepo	Mon Mar 30 16:23:33 2009 +0800
@@ -0,0 +1,235 @@
+#! /usr/bin/env perl
+eval 'exec perl -S $0 ${1+"$@"}'
+    if $running_under_some_shell;
+
+# pod-updatepo -- Update the po translation of POD data.
+# $Id: po4a-updatepo,v 1.44 2009-03-07 12:33:10 nekral-guest Exp $
+#
+# Copyright 2002, 2003, 2004 by Martin Quinson (mquinson#debian.org)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of GPL (see COPYING).
+
+=head1 NAME
+
+po4a-updatepo - update the translation (in po format) of documentation
+
+=head1 SYNOPSIS
+
+po4a-updatepo -f E<lt>fmtE<gt> (-m E<lt>master.docE<gt>)+ (-p E<lt>XX.poE<gt>)+
+
+(XX.po are the outputs, all others are inputs)
+
+=head1 DESCRIPTION
+
+The po4a (po for anything) project goal is to ease translations (and more
+interestingly, the maintenance of translations) using gettext tools on
+areas where they were not expected like documentation.
+
+The C<po4a-updatepo> script is in charge of updating po files to make
+them reflect the changes made to the original documentation file. For that,
+it converts the documentation file to a pot file, and call L<msgmerge(1)>
+on this new pot and on the provided po files.
+
+It is possible to give more than one po file (if you want to update several
+languages at once), and several documentation files (if you want to store
+the translations of several documents in the same po file).
+
+If the master document has non-ascii characters, it will convert the po files
+to utf-8 (if they weren't already), in order to allow non-standard characters
+in a culture independent way.
+
+=head1 COMMAND-LINE OPTIONS
+
+=over 4
+
+=item -f, --format
+
+Format of the documentation you want to handle. Use the --help-format
+option to see the list of available formats.
+
+=item -m, --master
+
+File(s) containing the master document to translate.
+
+=item -M, --master-charset
+
+Charset of the files containing the document to translate. Note that all
+files must have the same charset.
+
+=item -p, --po
+
+Po file(s) to update. If these files do not exist, they are created by
+C<po4a-updatepo>.
+
+=item -o, --option
+
+Extra option(s) to pass to the format plugin and other po4a internal module.
+Specify each option in the 'name=value' format. See the documentation of
+each plugin for more information about the valid options and their meanings.
+
+=item --previous
+
+This option adds '--previous' to the options passed to msgmerge.
+It requires gettext 0.16 or later.
+
+=item --msgmerge-opt options
+
+Extra options for msgmerge.
+
+=item -h, --help
+
+Show a short help message.
+
+=item --help-format
+
+List the documentation format handled by po4a.
+
+=item -V, --version
+
+Display the version of the script and exit.
+
+=item -v, --verbose
+
+Increase the verbosity of the program.
+
+=item -d, --debug
+
+Output some debugging information.
+
+=back
+
+=head1 SEE ALSO
+
+L<po4a(7)>, L<po4a-gettextize(1)>, L<po4a-translate(1)>, L<po4a-normalize(1)>.
+
+=head1 AUTHORS
+
+ Denis Barbier <barbier@linuxfr.org>
+ Martin Quinson (mquinson#debian.org)
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2002, 2003, 2004, 2005 by SPI, inc.
+
+This program is free software; you may redistribute it and/or modify it
+under the terms of GPL (see the COPYING file).
+
+=cut
+
+use 5.006;
+use strict;
+use warnings;
+
+use Getopt::Long qw(GetOptions);
+use Locale::Po4a::Po;
+
+use Locale::Po4a::Chooser;
+use Locale::Po4a::TransTractor;
+use Locale::Po4a::Common;
+
+use Pod::Usage qw(pod2usage);
+
+use File::Temp;
+
+Locale::Po4a::Common::textdomain('po4a');
+
+sub show_version {
+    Locale::Po4a::Common::show_version("po4a-updatepo");
+    exit 0;
+}
+
+
+# init commandline parser
+Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
+
+# Parse our options
+my (@masterfiles,@pofiles);
+my ($help,$help_fmt,$verbose,$debug,$format,@options);
+my $mastchar;
+my $previous;
+my $msgmerge_opt = "";
+GetOptions('help|h'      => \$help,
+	   'help-format' => \$help_fmt,
+
+	   'master|m=s'  => \@masterfiles,
+	   'po|p=s'      => \@pofiles,
+	   'format|f=s'  => \$format,
+
+	   'master-charset|M=s' => \$mastchar,
+
+	   'option|o=s'  => \@options,
+
+	   'previous'    => \$previous,
+	   'msgmerge-opt=s' => \$msgmerge_opt,
+    
+	   'verbose|v'   => \$verbose,
+	   'debug|d'     => \$debug,
+	   'version|V'   => \&show_version)
+    or pod2usage();
+
+$help && pod2usage (-verbose => 1, -exitval => 0);
+$help_fmt && Locale::Po4a::Chooser::list(0);
+pod2usage () if scalar @masterfiles < 1 || scalar @pofiles < 1;
+
+$msgmerge_opt .= " --previous" if $previous;
+
+my %options = (
+    "verbose" => $verbose,
+    "debug" => $debug);
+
+foreach (@options) {
+    if (m/^([^=]*)=(.*)$/) {
+	$options{$1}="$2";
+    } else {
+	$options{$_}=1;
+    }
+}
+
+# parser
+my ($doc)=Locale::Po4a::Chooser::new($format,%options);
+
+map { -e $_ || die wrap_msg(gettext("File %s does not exist."), $_) } @masterfiles;
+map { die wrap_msg(gettext("po4a-updatepo can't take the input po from stdin."))
+	if $_ eq '-'  && !-e '-'} @pofiles;
+
+my ($pot_filename);
+(undef,$pot_filename)=File::Temp->tempfile("po4a-updatepoXXXX",
+					   DIR    => "/tmp",
+					   SUFFIX => ".pot",
+					   OPEN   => 0,
+					   UNLINK => 0)
+    or die wrap_msg(gettext("Can't create a temporary pot file: %s"), $!);
+
+
+print STDERR wrap_msg(gettext("Parse input files... ")) if $verbose;
+
+$doc->{TT}{utf_mode} = 1;
+
+$doc->process('file_in_name'    => \@masterfiles,
+	      'file_in_charset' => $mastchar,
+	      'po_out_name'     => $pot_filename,
+	      'debug'           => $debug,
+	      'verbose'         => $verbose);
+
+print STDERR wrap_msg(gettext("done.")) if $verbose;
+
+
+while (my $po_filename=shift @pofiles) {
+    if (-e $po_filename) {
+	print STDERR wrap_msg(gettext("Updating %s:"), $po_filename)
+	    if $verbose;
+	my $cmd = "msgmerge $msgmerge_opt -U $po_filename $pot_filename";
+	system ($cmd) == 0
+	    or die wrap_msg(gettext("Error while running msgmerge: %s"), $!);
+	system "msgfmt --statistics -v -o /dev/null $po_filename"
+	  if $verbose;
+    } else {
+	print STDERR wrap_msg(gettext("Creating %s:"), $po_filename)
+	    if $verbose;
+	system ("cp",$pot_filename,$po_filename) == 0
+	    or die wrap_msg(gettext("Error while copying the po file: %s"), $!);
+    }
+}
+
+unlink($pot_filename);
--- a/xsl/all-ids.xsl	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-<?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>
--- a/xsl/base-html-stylesheet.xsl	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-<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 src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
-    <script type="text/javascript">_uacct = "UA-1805907-3"; urchinTracker();</script>
-  </xsl:template>
-</xsl:stylesheet>
--- a/xsl/chunk-stylesheet.xsl	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<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>
--- a/xsl/dtd-profile.xsl	Fri Mar 27 00:41:15 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<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>