changeset 9487:90ae579924e4

Merge with crew
author Bryan O'Sullivan <bos@serpentine.com>
date Mon, 28 Sep 2009 13:21:41 -0700
parents 7d6ac5d7917c (diff) dd8d10c36c9c (current diff)
children 33a6213a974e
files hgext/notify.py
diffstat 108 files changed, 2024 insertions(+), 621 deletions(-) [+]
line wrap: on
line diff
--- a/doc/Makefile	Mon Aug 24 16:30:42 2009 -0700
+++ b/doc/Makefile	Mon Sep 28 13:21:41 2009 -0700
@@ -5,8 +5,7 @@
 MANDIR=$(PREFIX)/share/man
 INSTALL=install -c -m 644
 PYTHON=python
-RST2HTML=rst2html
-RST2MAN=rst2man
+RST2HTML=$(shell which rst2html 2> /dev/null || which rst2html.py)
 
 all: man html
 
@@ -18,20 +17,18 @@
 	touch hg.1.txt
 
 hg.1.gendoc.txt: gendoc.py ../mercurial/commands.py ../mercurial/help.py
-	${PYTHON} gendoc.py > $@
+	${PYTHON} gendoc.py > $@.tmp
+	mv $@.tmp $@
 
 %: %.txt common.txt
-	# add newline after all literal blocks and fix backslash escape
-	$(RST2MAN) $*.txt \
-	  | sed -e 's/^\.fi$$/.fi\n/' \
-	  | sed -e 's/\\fB\\\\fP/\\fB\\e\\fP/' \
-	  > $*
+	$(PYTHON) rst2man.py --halt warning \
+	  --strip-elements-with-class htmlonly $*.txt $*
 
 %.html: %.txt common.txt
-	$(RST2HTML) $*.txt > $*.html
+	$(RST2HTML) --halt warning $*.txt $*.html
 
 MANIFEST: man html
-	# tracked files are already in the main MANIFEST
+# tracked files are already in the main MANIFEST
 	$(RM) $@
 	for i in $(MAN) $(HTML) hg.1.gendoc.txt; do \
 	  echo "doc/$$i" >> $@ ; \
--- a/doc/README	Mon Aug 24 16:30:42 2009 -0700
+++ b/doc/README	Mon Sep 28 13:21:41 2009 -0700
@@ -4,14 +4,8 @@
   http://docutils.sourceforge.net/rst.html
 
 It's also convertible to a variety of other formats including standard
-UNIX man page format and HTML.
-
-To do this, you'll need to install the rst2html and rst2man tools,
-which are part of Docutils:
+UNIX man page format and HTML. You'll need to install Docutils:
 
   http://docutils.sourceforge.net/
 
-The rst2man tool is still in their so-called "sandbox". The above page
-has links to tarballs of both Docutils and their sandbox.
-
 Use the Makefile in this directory to generate the man and HTML pages.
--- a/doc/gendoc.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/doc/gendoc.py	Mon Sep 28 13:21:41 2009 -0700
@@ -1,9 +1,10 @@
-import os, sys, textwrap
+import os, sys
 # import from the live mercurial repo
 sys.path.insert(0, "..")
 # fall back to pure modules if required C extensions are not available
 sys.path.append(os.path.join('..', 'mercurial', 'pure'))
 from mercurial import demandimport; demandimport.enable()
+from mercurial import encoding
 from mercurial.commands import table, globalopts
 from mercurial.i18n import _
 from mercurial.help import helptable
@@ -55,9 +56,9 @@
 
 def show_doc(ui):
     def section(s):
-        ui.write("%s\n%s\n\n" % (s, "-" * len(s)))
+        ui.write("%s\n%s\n\n" % (s, "-" * encoding.colwidth(s)))
     def subsection(s):
-        ui.write("%s\n%s\n\n" % (s, '"' * len(s)))
+        ui.write("%s\n%s\n\n" % (s, '"' * encoding.colwidth(s)))
 
     # print options
     section(_("OPTIONS"))
@@ -92,9 +93,7 @@
                     s = "%-*s  %s" % (opts_len, optstr, desc)
                 else:
                     s = optstr
-                s = textwrap.fill(s, initial_indent=4 * " ",
-                                  subsequent_indent=(6 + opts_len) * " ")
-                ui.write("%s\n" % s)
+                ui.write("    %s\n" % s)
             ui.write("\n")
         # aliases
         if d['aliases']:
--- a/doc/hg.1.txt	Mon Aug 24 16:30:42 2009 -0700
+++ b/doc/hg.1.txt	Mon Sep 28 13:21:41 2009 -0700
@@ -11,6 +11,10 @@
 :Manual section: 1
 :Manual group:   Mercurial Manual
 
+.. contents::
+   :backlinks: top
+   :class: htmlonly
+
 
 SYNOPSIS
 --------
--- a/doc/hgrc.5.txt	Mon Aug 24 16:30:42 2009 -0700
+++ b/doc/hgrc.5.txt	Mon Sep 28 13:21:41 2009 -0700
@@ -11,6 +11,10 @@
 :Manual section: 5
 :Manual group:   Mercurial Manual
 
+.. contents::
+   :backlinks: top
+   :class: htmlonly
+
 
 SYNOPSIS
 --------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/rst2man.py	Mon Sep 28 13:21:41 2009 -0700
@@ -0,0 +1,1112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# $Id: manpage.py 6110 2009-08-31 14:40:33Z grubert $
+# Author: Engelbert Gruber <grubert@users.sourceforge.net>
+# Copyright: This module is put into the public domain.
+
+"""
+Simple man page writer for reStructuredText.
+
+Man pages (short for "manual pages") contain system documentation on unix-like
+systems. The pages are grouped in numbered sections: 
+
+ 1 executable programs and shell commands
+ 2 system calls
+ 3 library functions
+ 4 special files
+ 5 file formats
+ 6 games
+ 7 miscellaneous
+ 8 system administration
+
+Man pages are written *troff*, a text file formatting system.
+
+See http://www.tldp.org/HOWTO/Man-Page for a start.
+
+Man pages have no subsection only parts.
+Standard parts
+
+  NAME ,
+  SYNOPSIS ,
+  DESCRIPTION ,
+  OPTIONS ,
+  FILES ,
+  SEE ALSO ,
+  BUGS ,
+
+and
+
+  AUTHOR .
+
+A unix-like system keeps an index of the DESCRIPTIONs, which is accesable
+by the command whatis or apropos.
+
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+import os
+import time
+import re
+from types import ListType
+
+import docutils
+from docutils import nodes, utils, writers, languages
+import roman
+
+FIELD_LIST_INDENT = 7
+DEFINITION_LIST_INDENT = 7
+OPTION_LIST_INDENT = 7
+BLOCKQOUTE_INDENT = 3.5
+
+# Define two macros so man/roff can calculate the
+# indent/unindent margins by itself
+MACRO_DEF = (r""".
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+""")
+
+class Writer(writers.Writer):
+
+    supported = ('manpage')
+    """Formats this writer supports."""
+
+    output = None
+    """Final translated form of `document`."""
+
+    def __init__(self):
+        writers.Writer.__init__(self)
+        self.translator_class = Translator
+
+    def translate(self):
+        visitor = self.translator_class(self.document)
+        self.document.walkabout(visitor)
+        self.output = visitor.astext()
+
+
+class Table:
+    def __init__(self):
+        self._rows = []
+        self._options = ['center', ]
+        self._tab_char = '\t'
+        self._coldefs = []
+    def new_row(self):
+        self._rows.append([])
+    def append_separator(self, separator):
+        """Append the separator for table head."""
+        self._rows.append([separator])
+    def append_cell(self, cell_lines):
+        """cell_lines is an array of lines"""
+        start = 0
+        if len(cell_lines)>0 and cell_lines[0] == '.sp\n':
+            start = 1
+        self._rows[-1].append(cell_lines[start:])
+        if len(self._coldefs) < len(self._rows[-1]):
+            self._coldefs.append('l')
+    def _minimize_cell(self, cell_lines):
+        """Remove leading and trailing blank and ``.sp`` lines"""
+        while (cell_lines and cell_lines[0] in ('\n', '.sp\n')):
+            del cell_lines[0]
+        while (cell_lines and cell_lines[-1] in ('\n', '.sp\n')):
+            del cell_lines[-1]
+    def as_list(self):
+        text = ['.TS\n']
+        text.append(' '.join(self._options) + ';\n')
+        text.append('|%s|.\n' % ('|'.join(self._coldefs)))
+        for row in self._rows:
+            # row = array of cells. cell = array of lines.
+            text.append('_\n')       # line above 
+            text.append('T{\n')
+            for i in range(len(row)):
+                cell = row[i]
+                self._minimize_cell(cell)
+                text.extend(cell)
+                if not text[-1].endswith('\n'):
+                    text[-1] += '\n'
+                if i < len(row)-1:
+                    text.append('T}'+self._tab_char+'T{\n')
+                else:
+                    text.append('T}\n')
+        text.append('_\n')
+        text.append('.TE\n')
+        return text
+
+class Translator(nodes.NodeVisitor):
+    """"""
+
+    words_and_spaces = re.compile(r'\S+| +|\n')
+    document_start = """Man page generated from reStructeredText."""
+
+    def __init__(self, document):
+        nodes.NodeVisitor.__init__(self, document)
+        self.settings = settings = document.settings
+        lcode = settings.language_code
+        self.language = languages.get_language(lcode)
+        self.head = []
+        self.body = []
+        self.foot = []
+        self.section_level = 0
+        self.context = []
+        self.topic_class = ''
+        self.colspecs = []
+        self.compact_p = 1
+        self.compact_simple = None
+        # the list style "*" bullet or "#" numbered
+        self._list_char = []
+        # writing the header .TH and .SH NAME is postboned after
+        # docinfo.
+        self._docinfo = {
+                "title" : "", "title_upper": "",
+                "subtitle" : "",
+                "manual_section" : "", "manual_group" : "",
+                "author" : [], 
+                "date" : "", 
+                "copyright" : "",
+                "version" : "",
+                    }
+        self._docinfo_keys = []     # a list to keep the sequence as in source.
+        self._docinfo_names = {}    # to get name from text not normalized.
+        self._in_docinfo = None
+        self._active_table = None
+        self._in_literal = False
+        self.header_written = 0
+        self._line_block = 0
+        self.authors = []
+        self.section_level = 0
+        self._indent = [0]
+        # central definition of simple processing rules
+        # what to output on : visit, depart
+        # Do not use paragraph requests ``.PP`` because these set indentation.
+        # use ``.sp``. Remove superfluous ``.sp`` in ``astext``.
+        #
+        # Fonts are put on a stack, the top one is used.
+        # ``.ft P`` or ``\\fP`` pop from stack.
+        # ``B`` bold, ``I`` italic, ``R`` roman should be available.
+        # Hopefully ``C`` courier too.
+        self.defs = {
+                'indent' : ('.INDENT %.1f\n', '.UNINDENT\n'),
+                'definition_list_item' : ('.TP', ''),
+                'field_name' : ('.TP\n.B ', '\n'),
+                'literal' : ('\\fC', '\\fP'),
+                'literal_block' : ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'),
+
+                'option_list_item' : ('.TP\n', ''),
+                
+                'reference' : (r'\fI\%', r'\fP'),
+                'emphasis': ('\\fI', '\\fP'),
+                'strong' : ('\\fB', '\\fP'),
+                'term' : ('\n.B ', '\n'),
+                'title_reference' : ('\\fI', '\\fP'),
+
+                'topic-title' : ('.SS ', ),
+                'sidebar-title' : ('.SS ', ),
+
+                'problematic' : ('\n.nf\n', '\n.fi\n'),
+                    }
+        # NOTE dont specify the newline before a dot-command, but ensure
+        # it is there.
+
+    def comment_begin(self, text):
+        """Return commented version of the passed text WITHOUT end of
+        line/comment."""
+        prefix = '.\\" '
+        out_text = ''.join(
+            [(prefix + in_line + '\n')
+            for in_line in text.split('\n')])
+        return out_text
+
+    def comment(self, text):
+        """Return commented version of the passed text."""
+        return self.comment_begin(text)+'.\n'
+
+    def ensure_eol(self):
+        """Ensure the last line in body is terminated by new line."""
+        if self.body[-1][-1] != '\n':
+            self.body.append('\n')
+
+    def astext(self):
+        """Return the final formatted document as a string."""
+        if not self.header_written:
+            # ensure we get a ".TH" as viewers require it.
+            self.head.append(self.header())
+        # filter body
+        for i in xrange(len(self.body)-1,0,-1):
+            # remove superfluous vertical gaps.
+            if self.body[i] == '.sp\n':
+                if self.body[i-1][:4] in ('.BI ','.IP '):
+                    self.body[i] = '.\n'
+                elif (self.body[i-1][:3] == '.B ' and
+                    self.body[i-2][:4] == '.TP\n'):
+                    self.body[i] = '.\n'
+                elif (self.body[i-1] == '\n' and 
+                    self.body[i-2][0] != '.' and
+                    (self.body[i-3][:7] == '.TP\n.B '
+                        or self.body[i-3][:4] == '\n.B ')
+                     ):
+                    self.body[i] = '.\n'
+        return ''.join(self.head + self.body + self.foot)
+
+    def deunicode(self, text):
+        text = text.replace(u'\xa0', '\\ ')
+        text = text.replace(u'\u2020', '\\(dg')
+        return text
+
+    def visit_Text(self, node):
+        text = node.astext()
+        text = text.replace('\\','\\e')
+        replace_pairs = [
+            (u'-', ur'\-'),
+            (u'\'', ur'\(aq'),
+            (u'´', ur'\''),
+            (u'`', ur'\(ga'),
+            ]
+        for (in_char, out_markup) in replace_pairs:
+            text = text.replace(in_char, out_markup)
+        # unicode
+        text = self.deunicode(text)
+        if self._in_literal:
+            # prevent interpretation of "." at line start
+            if text[0] == '.':
+                text = '\\&' + text
+            text = text.replace('\n.', '\n\\&.')
+        self.body.append(text)
+
+    def depart_Text(self, node):
+        pass
+
+    def list_start(self, node):
+        class enum_char:
+            enum_style = {
+                    'bullet'     : '\\(bu',
+                    'emdash'     : '\\(em',
+                     }
+
+            def __init__(self, style):
+                self._style = style
+                if node.has_key('start'):
+                    self._cnt = node['start'] - 1
+                else:
+                    self._cnt = 0
+                self._indent = 2
+                if style == 'arabic':
+                    # indentation depends on number of childrens
+                    # and start value.
+                    self._indent = len(str(len(node.children)))
+                    self._indent += len(str(self._cnt)) + 1
+                elif style == 'loweralpha':
+                    self._cnt += ord('a') - 1
+                    self._indent = 3
+                elif style == 'upperalpha':
+                    self._cnt += ord('A') - 1
+                    self._indent = 3
+                elif style.endswith('roman'):
+                    self._indent = 5
+
+            def next(self):
+                if self._style == 'bullet':
+                    return self.enum_style[self._style]
+                elif self._style == 'emdash':
+                    return self.enum_style[self._style]
+                self._cnt += 1
+                # TODO add prefix postfix
+                if self._style == 'arabic':
+                    return "%d." % self._cnt
+                elif self._style in ('loweralpha', 'upperalpha'):
+                    return "%c." % self._cnt
+                elif self._style.endswith('roman'):
+                    res = roman.toRoman(self._cnt) + '.'
+                    if self._style.startswith('upper'):
+                        return res.upper()
+                    return res.lower()
+                else:
+                    return "%d." % self._cnt
+            def get_width(self):
+                return self._indent
+            def __repr__(self):
+                return 'enum_style-%s' % list(self._style)
+
+        if node.has_key('enumtype'):
+            self._list_char.append(enum_char(node['enumtype']))
+        else:
+            self._list_char.append(enum_char('bullet'))
+        if len(self._list_char) > 1:
+            # indent nested lists
+            self.indent(self._list_char[-2].get_width())
+        else:
+            self.indent(self._list_char[-1].get_width())
+
+    def list_end(self):
+        self.dedent()
+        self._list_char.pop()
+
+    def header(self):
+        tmpl = (".TH %(title_upper)s %(manual_section)s"
+                " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
+                ".SH NAME\n"
+                "%(title)s \- %(subtitle)s\n")
+        return tmpl % self._docinfo
+
+    def append_header(self):
+        """append header with .TH and .SH NAME"""
+        # NOTE before everything
+        # .TH title_upper section date source manual
+        if self.header_written:
+            return
+        self.body.append(self.header())
+        self.body.append(MACRO_DEF)
+        self.header_written = 1
+
+    def visit_address(self, node):
+        self.visit_docinfo_item(node, 'address')
+
+    def depart_address(self, node):
+        pass
+
+    def visit_admonition(self, node, name=None):
+        if name:
+            self.body.append('.IP %s\n' %
+                        self.language.labels.get(name, name))
+
+    def depart_admonition(self, node):
+        self.body.append('.RE\n')
+
+    def visit_attention(self, node):
+        self.visit_admonition(node, 'attention')
+
+    depart_attention = depart_admonition
+
+    def visit_docinfo_item(self, node, name):
+        if name == 'author':
+            self._docinfo[name].append(node.astext())
+        else:
+            self._docinfo[name] = node.astext()
+        self._docinfo_keys.append(name)
+        raise nodes.SkipNode
+
+    def depart_docinfo_item(self, node):
+        pass
+
+    def visit_author(self, node):
+        self.visit_docinfo_item(node, 'author')
+
+    depart_author = depart_docinfo_item
+
+    def visit_authors(self, node):
+        # _author is called anyway.
+        pass
+
+    def depart_authors(self, node):
+        pass
+
+    def visit_block_quote(self, node):
+        # BUG/HACK: indent alway uses the _last_ indention,
+        # thus we need two of them.
+        self.indent(BLOCKQOUTE_INDENT)
+        self.indent(0)
+
+    def depart_block_quote(self, node):
+        self.dedent()
+        self.dedent()
+
+    def visit_bullet_list(self, node):
+        self.list_start(node)
+
+    def depart_bullet_list(self, node):
+        self.list_end()
+
+    def visit_caption(self, node):
+        pass
+
+    def depart_caption(self, node):
+        pass
+
+    def visit_caution(self, node):
+        self.visit_admonition(node, 'caution')
+
+    depart_caution = depart_admonition
+
+    def visit_citation(self, node):
+        num,text = node.astext().split(None,1)
+        num = num.strip()
+        self.body.append('.IP [%s] 5\n' % num)
+
+    def depart_citation(self, node):
+        pass
+
+    def visit_citation_reference(self, node):
+        self.body.append('['+node.astext()+']')
+        raise nodes.SkipNode
+
+    def visit_classifier(self, node):
+        pass
+
+    def depart_classifier(self, node):
+        pass
+
+    def visit_colspec(self, node):
+        self.colspecs.append(node)
+
+    def depart_colspec(self, node):
+        pass
+
+    def write_colspecs(self):
+        self.body.append("%s.\n" % ('L '*len(self.colspecs)))
+
+    def visit_comment(self, node,
+                      sub=re.compile('-(?=-)').sub):
+        self.body.append(self.comment(node.astext()))
+        raise nodes.SkipNode
+
+    def visit_contact(self, node):
+        self.visit_docinfo_item(node, 'contact')
+
+    depart_contact = depart_docinfo_item
+
+    def visit_container(self, node):
+        pass
+
+    def depart_container(self, node):
+        pass
+
+    def visit_compound(self, node):
+        pass
+
+    def depart_compound(self, node):
+        pass
+
+    def visit_copyright(self, node):
+        self.visit_docinfo_item(node, 'copyright')
+
+    def visit_danger(self, node):
+        self.visit_admonition(node, 'danger')
+
+    depart_danger = depart_admonition
+
+    def visit_date(self, node):
+        self.visit_docinfo_item(node, 'date')
+
+    def visit_decoration(self, node):
+        pass
+
+    def depart_decoration(self, node):
+        pass
+
+    def visit_definition(self, node):
+        pass
+
+    def depart_definition(self, node):
+        pass
+
+    def visit_definition_list(self, node):
+        self.indent(DEFINITION_LIST_INDENT)
+
+    def depart_definition_list(self, node):
+        self.dedent()
+
+    def visit_definition_list_item(self, node):
+        self.body.append(self.defs['definition_list_item'][0])
+
+    def depart_definition_list_item(self, node):
+        self.body.append(self.defs['definition_list_item'][1])
+
+    def visit_description(self, node):
+        pass
+
+    def depart_description(self, node):
+        pass
+
+    def visit_docinfo(self, node):
+        self._in_docinfo = 1
+
+    def depart_docinfo(self, node):
+        self._in_docinfo = None
+        # NOTE nothing should be written before this
+        self.append_header()
+
+    def visit_doctest_block(self, node):
+        self.body.append(self.defs['literal_block'][0])
+        self._in_literal = True
+
+    def depart_doctest_block(self, node):
+        self._in_literal = False
+        self.body.append(self.defs['literal_block'][1])
+
+    def visit_document(self, node):
+        # no blank line between comment and header.
+        self.body.append(self.comment(self.document_start).rstrip()+'\n')
+        # writing header is postboned
+        self.header_written = 0
+
+    def depart_document(self, node):
+        if self._docinfo['author']:
+            self.body.append('.SH AUTHOR\n%s\n' 
+                    % ', '.join(self._docinfo['author']))
+        skip = ('author', 'copyright', 'date',
+                'manual_group', 'manual_section', 
+                'subtitle',
+                'title', 'title_upper', 'version')
+        for name in self._docinfo_keys:
+            if name == 'address':
+                self.body.append("\n%s:\n%s%s.nf\n%s\n.fi\n%s%s" % (
+                                    self.language.labels.get(name, name),
+                                    self.defs['indent'][0] % 0,
+                                    self.defs['indent'][0] % BLOCKQOUTE_INDENT,
+                                    self._docinfo[name],
+                                    self.defs['indent'][1],
+                                    self.defs['indent'][1],
+                                    ) )
+            elif not name in skip:
+                if name in self._docinfo_names:
+                    label = self._docinfo_names[name]
+                else:
+                    label = self.language.labels.get(name, name)
+                self.body.append("\n%s: %s\n" % (label, self._docinfo[name]) )
+        if self._docinfo['copyright']:
+            self.body.append('.SH COPYRIGHT\n%s\n' 
+                    % self._docinfo['copyright'])
+        self.body.append( self.comment(
+                        'Generated by docutils manpage writer.\n' ) )
+
+    def visit_emphasis(self, node):
+        self.body.append(self.defs['emphasis'][0])
+
+    def depart_emphasis(self, node):
+        self.body.append(self.defs['emphasis'][1])
+
+    def visit_entry(self, node):
+        # a cell in a table row
+        if 'morerows' in node:
+            self.document.reporter.warning('"table row spanning" not supported',
+                    base_node=node)
+        if 'morecols' in node:
+            self.document.reporter.warning(
+                    '"table cell spanning" not supported', base_node=node)
+        self.context.append(len(self.body))
+
+    def depart_entry(self, node):
+        start = self.context.pop()
+        self._active_table.append_cell(self.body[start:])
+        del self.body[start:]
+
+    def visit_enumerated_list(self, node):
+        self.list_start(node)
+
+    def depart_enumerated_list(self, node):
+        self.list_end()
+
+    def visit_error(self, node):
+        self.visit_admonition(node, 'error')
+
+    depart_error = depart_admonition
+
+    def visit_field(self, node):
+        pass
+
+    def depart_field(self, node):
+        pass
+
+    def visit_field_body(self, node):
+        if self._in_docinfo:
+            name_normalized = self._field_name.lower().replace(" ","_")
+            self._docinfo_names[name_normalized] = self._field_name
+            self.visit_docinfo_item(node, name_normalized)
+            raise nodes.SkipNode
+
+    def depart_field_body(self, node):
+        pass
+
+    def visit_field_list(self, node):
+        self.indent(FIELD_LIST_INDENT)
+
+    def depart_field_list(self, node):
+        self.dedent()
+
+    def visit_field_name(self, node):
+        if self._in_docinfo:
+            self._field_name = node.astext()
+            raise nodes.SkipNode
+        else:
+            self.body.append(self.defs['field_name'][0])
+
+    def depart_field_name(self, node):
+        self.body.append(self.defs['field_name'][1])
+
+    def visit_figure(self, node):
+        self.indent(2.5)
+        self.indent(0)
+
+    def depart_figure(self, node):
+        self.dedent()
+        self.dedent()
+
+    def visit_footer(self, node):
+        self.document.reporter.warning('"footer" not supported',
+                base_node=node)
+
+    def depart_footer(self, node):
+        pass
+
+    def visit_footnote(self, node):
+        num,text = node.astext().split(None,1)
+        num = num.strip()
+        self.body.append('.IP [%s] 5\n' % self.deunicode(num))
+
+    def depart_footnote(self, node):
+        pass
+
+    def footnote_backrefs(self, node):
+        self.document.reporter.warning('"footnote_backrefs" not supported',
+                base_node=node)
+
+    def visit_footnote_reference(self, node):
+        self.body.append('['+self.deunicode(node.astext())+']')
+        raise nodes.SkipNode
+
+    def depart_footnote_reference(self, node):
+        pass
+
+    def visit_generated(self, node):
+        pass
+
+    def depart_generated(self, node):
+        pass
+
+    def visit_header(self, node):
+        raise NotImplementedError, node.astext()
+
+    def depart_header(self, node):
+        pass
+
+    def visit_hint(self, node):
+        self.visit_admonition(node, 'hint')
+
+    depart_hint = depart_admonition
+
+    def visit_subscript(self, node):
+        self.body.append('\\s-2\\d')
+
+    def depart_subscript(self, node):
+        self.body.append('\\u\\s0')
+
+    def visit_superscript(self, node):
+        self.body.append('\\s-2\\u')
+
+    def depart_superscript(self, node):
+        self.body.append('\\d\\s0')
+
+    def visit_attribution(self, node):
+        self.body.append('\\(em ')
+
+    def depart_attribution(self, node):
+        self.body.append('\n')
+
+    def visit_image(self, node):
+        self.document.reporter.warning('"image" not supported',
+                base_node=node)
+        text = []
+        if 'alt' in node.attributes:
+            text.append(node.attributes['alt'])
+        if 'uri' in node.attributes:
+            text.append(node.attributes['uri'])
+        self.body.append('[image: %s]\n' % ('/'.join(text)))
+        raise nodes.SkipNode
+
+    def visit_important(self, node):
+        self.visit_admonition(node, 'important')
+
+    depart_important = depart_admonition
+
+    def visit_label(self, node):
+        # footnote and citation
+        if (isinstance(node.parent, nodes.footnote)
+            or isinstance(node.parent, nodes.citation)):
+            raise nodes.SkipNode
+        self.document.reporter.warning('"unsupported "label"',
+                base_node=node)
+        self.body.append('[')
+
+    def depart_label(self, node):
+        self.body.append(']\n')
+
+    def visit_legend(self, node):
+        pass
+
+    def depart_legend(self, node):
+        pass
+
+    # WHAT should we use .INDENT, .UNINDENT ?
+    def visit_line_block(self, node):
+        self._line_block += 1
+        if self._line_block == 1:
+            self.body.append('.nf\n')
+        else:
+            self.body.append('.in +2\n')
+
+    def depart_line_block(self, node):
+        self._line_block -= 1
+        if self._line_block == 0:
+            self.body.append('.fi\n')
+            self.body.append('.sp\n')
+        else:
+            self.body.append('.in -2\n')
+
+    def visit_line(self, node):
+        pass
+
+    def depart_line(self, node):
+        self.body.append('\n')
+
+    def visit_list_item(self, node):
+        # man 7 man argues to use ".IP" instead of ".TP"
+        self.body.append('.IP %s %d\n' % (
+                self._list_char[-1].next(),
+                self._list_char[-1].get_width(),) )
+
+    def depart_list_item(self, node):
+        pass
+
+    def visit_literal(self, node):
+        self.body.append(self.defs['literal'][0])
+
+    def depart_literal(self, node):
+        self.body.append(self.defs['literal'][1])
+
+    def visit_literal_block(self, node):
+        self.body.append(self.defs['literal_block'][0])
+        self._in_literal = True
+
+    def depart_literal_block(self, node):
+        self._in_literal = False
+        self.body.append(self.defs['literal_block'][1])
+
+    def visit_meta(self, node):
+        raise NotImplementedError, node.astext()
+
+    def depart_meta(self, node):
+        pass
+
+    def visit_note(self, node):
+        self.visit_admonition(node, 'note')
+
+    depart_note = depart_admonition
+
+    def indent(self, by=0.5):
+        # if we are in a section ".SH" there already is a .RS
+        step = self._indent[-1]
+        self._indent.append(by)
+        self.body.append(self.defs['indent'][0] % step)
+
+    def dedent(self):
+        self._indent.pop()
+        self.body.append(self.defs['indent'][1])
+
+    def visit_option_list(self, node):
+        self.indent(OPTION_LIST_INDENT)
+
+    def depart_option_list(self, node):
+        self.dedent()
+
+    def visit_option_list_item(self, node):
+        # one item of the list
+        self.body.append(self.defs['option_list_item'][0])
+
+    def depart_option_list_item(self, node):
+        self.body.append(self.defs['option_list_item'][1])
+
+    def visit_option_group(self, node):
+        # as one option could have several forms it is a group
+        # options without parameter bold only, .B, -v
+        # options with parameter bold italic, .BI, -f file
+        #
+        # we do not know if .B or .BI
+        self.context.append('.B')           # blind guess
+        self.context.append(len(self.body)) # to be able to insert later
+        self.context.append(0)              # option counter
+
+    def depart_option_group(self, node):
+        self.context.pop()  # the counter
+        start_position = self.context.pop()
+        text = self.body[start_position:]
+        del self.body[start_position:]
+        self.body.append('%s%s\n' % (self.context.pop(), ''.join(text)))
+
+    def visit_option(self, node):
+        # each form of the option will be presented separately
+        if self.context[-1]>0:
+            self.body.append(', ')
+        if self.context[-3] == '.BI':
+            self.body.append('\\')
+        self.body.append(' ')
+
+    def depart_option(self, node):
+        self.context[-1] += 1
+
+    def visit_option_string(self, node):
+        # do not know if .B or .BI
+        pass
+
+    def depart_option_string(self, node):
+        pass
+
+    def visit_option_argument(self, node):
+        self.context[-3] = '.BI' # bold/italic alternate
+        if node['delimiter'] != ' ':
+            self.body.append('\\fB%s ' % node['delimiter'] )
+        elif self.body[len(self.body)-1].endswith('='):
+            # a blank only means no blank in output, just changing font
+            self.body.append(' ')
+        else:
+            # blank backslash blank, switch font then a blank
+            self.body.append(' \\ ')
+
+    def depart_option_argument(self, node):
+        pass
+
+    def visit_organization(self, node):
+        self.visit_docinfo_item(node, 'organization')
+
+    def depart_organization(self, node):
+        pass
+
+    def visit_paragraph(self, node):
+        # ``.PP`` : Start standard indented paragraph.
+        # ``.LP`` : Start block paragraph, all except the first.
+        # ``.P [type]``  : Start paragraph type. 
+        # NOTE dont use paragraph starts because they reset indentation.
+        # ``.sp`` is only vertical space
+        self.ensure_eol()
+        self.body.append('.sp\n')
+
+    def depart_paragraph(self, node):
+        self.body.append('\n')
+
+    def visit_problematic(self, node):
+        self.body.append(self.defs['problematic'][0])
+
+    def depart_problematic(self, node):
+        self.body.append(self.defs['problematic'][1])
+
+    def visit_raw(self, node):
+        if node.get('format') == 'manpage':
+            self.body.append(node.astext() + "\n")
+        # Keep non-manpage raw text out of output:
+        raise nodes.SkipNode
+
+    def visit_reference(self, node):
+        """E.g. link or email address."""
+        self.body.append(self.defs['reference'][0])
+
+    def depart_reference(self, node):
+        self.body.append(self.defs['reference'][1])
+
+    def visit_revision(self, node):
+        self.visit_docinfo_item(node, 'revision')
+
+    depart_revision = depart_docinfo_item
+
+    def visit_row(self, node):
+        self._active_table.new_row()
+
+    def depart_row(self, node):
+        pass
+
+    def visit_section(self, node):
+        self.section_level += 1
+
+    def depart_section(self, node):
+        self.section_level -= 1
+
+    def visit_status(self, node):
+        self.visit_docinfo_item(node, 'status')
+
+    depart_status = depart_docinfo_item
+
+    def visit_strong(self, node):
+        self.body.append(self.defs['strong'][0])
+
+    def depart_strong(self, node):
+        self.body.append(self.defs['strong'][1])
+
+    def visit_substitution_definition(self, node):
+        """Internal only."""
+        raise nodes.SkipNode
+
+    def visit_substitution_reference(self, node):
+        self.document.reporter.warning('"substitution_reference" not supported',
+                base_node=node)
+
+    def visit_subtitle(self, node):
+        if isinstance(node.parent, nodes.sidebar):
+            self.body.append(self.defs['strong'][0])
+        elif isinstance(node.parent, nodes.document):
+            self.visit_docinfo_item(node, 'subtitle')
+        elif isinstance(node.parent, nodes.section):
+            self.body.append(self.defs['strong'][0])
+
+    def depart_subtitle(self, node):
+        # document subtitle calls SkipNode
+        self.body.append(self.defs['strong'][1]+'\n.PP\n')
+
+    def visit_system_message(self, node):
+        # TODO add report_level
+        #if node['level'] < self.document.reporter['writer'].report_level:
+        #    Level is too low to display:
+        #    raise nodes.SkipNode
+        attr = {}
+        backref_text = ''
+        if node.hasattr('id'):
+            attr['name'] = node['id']
+        if node.hasattr('line'):
+            line = ', line %s' % node['line']
+        else:
+            line = ''
+        self.body.append('.IP "System Message: %s/%s (%s:%s)"\n'
+                         % (node['type'], node['level'], node['source'], line))
+
+    def depart_system_message(self, node):
+        pass
+
+    def visit_table(self, node):
+        self._active_table = Table()
+
+    def depart_table(self, node):
+        self.ensure_eol()
+        self.body.extend(self._active_table.as_list())
+        self._active_table = None
+
+    def visit_target(self, node):
+        # targets are in-document hyper targets, without any use for man-pages.
+        raise nodes.SkipNode
+
+    def visit_tbody(self, node):
+        pass
+
+    def depart_tbody(self, node):
+        pass
+
+    def visit_term(self, node):
+        self.body.append(self.defs['term'][0])
+
+    def depart_term(self, node):
+        self.body.append(self.defs['term'][1])
+
+    def visit_tgroup(self, node):
+        pass
+
+    def depart_tgroup(self, node):
+        pass
+
+    def visit_thead(self, node):
+        # MAYBE double line '='
+        pass
+
+    def depart_thead(self, node):
+        # MAYBE double line '='
+        pass
+
+    def visit_tip(self, node):
+        self.visit_admonition(node, 'tip')
+
+    depart_tip = depart_admonition
+
+    def visit_title(self, node):
+        if isinstance(node.parent, nodes.topic):
+            self.body.append(self.defs['topic-title'][0])
+        elif isinstance(node.parent, nodes.sidebar):
+            self.body.append(self.defs['sidebar-title'][0])
+        elif isinstance(node.parent, nodes.admonition):
+            self.body.append('.IP "')
+        elif self.section_level == 0:
+            self._docinfo['title'] = node.astext()
+            # document title for .TH
+            self._docinfo['title_upper'] = node.astext().upper()
+            raise nodes.SkipNode
+        elif self.section_level == 1:
+            self.body.append('.SH ')
+        else:
+            self.body.append('.SS ')
+
+    def depart_title(self, node):
+        if isinstance(node.parent, nodes.admonition):
+            self.body.append('"')
+        self.body.append('\n')
+
+    def visit_title_reference(self, node):
+        """inline citation reference"""
+        self.body.append(self.defs['title_reference'][0])
+
+    def depart_title_reference(self, node):
+        self.body.append(self.defs['title_reference'][1])
+
+    def visit_topic(self, node):
+        pass
+
+    def depart_topic(self, node):
+        pass
+
+    def visit_sidebar(self, node):
+        pass
+
+    def depart_sidebar(self, node):
+        pass
+
+    def visit_rubric(self, node):
+        pass
+
+    def depart_rubric(self, node):
+        pass
+
+    def visit_transition(self, node):
+        # .PP      Begin a new paragraph and reset prevailing indent.
+        # .sp N    leaves N lines of blank space.
+        # .ce      centers the next line
+        self.body.append('\n.sp\n.ce\n----\n')
+
+    def depart_transition(self, node):
+        self.body.append('\n.ce 0\n.sp\n')
+
+    def visit_version(self, node):
+        self.visit_docinfo_item(node, 'version')
+
+    def visit_warning(self, node):
+        self.visit_admonition(node, 'warning')
+
+    depart_warning = depart_admonition
+
+    def unimplemented_visit(self, node):
+        raise NotImplementedError('visiting unimplemented node type: %s'
+                                  % node.__class__.__name__)
+
+# The following part is taken from the Docutils rst2man.py script:
+if __name__ == "__main__":
+    from docutils.core import publish_cmdline, default_description
+    description = ("Generates plain unix manual documents.  " +
+                   default_description)
+    publish_cmdline(writer=Writer(), description=description)
+
+# vim: set fileencoding=utf-8 et ts=4 ai :
--- a/hgext/acl.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/acl.py	Mon Sep 28 13:21:41 2009 -0700
@@ -60,12 +60,12 @@
 def buildmatch(ui, repo, user, key):
     '''return tuple of (match function, list enabled).'''
     if not ui.has_section(key):
-        ui.debug(_('acl: %s not enabled\n') % key)
+        ui.debug('acl: %s not enabled\n' % key)
         return None
 
     pats = [pat for pat, users in ui.configitems(key)
             if user in users.replace(',', ' ').split()]
-    ui.debug(_('acl: %s enabled, %d entries for user %s\n') %
+    ui.debug('acl: %s enabled, %d entries for user %s\n' %
              (key, len(pats), user))
     if pats:
         return match.match(repo.root, '', pats)
@@ -77,7 +77,7 @@
         raise util.Abort(_('config error - hook type "%s" cannot stop '
                            'incoming changesets') % hooktype)
     if source not in ui.config('acl', 'sources', 'serve').split():
-        ui.debug(_('acl: changes have source "%s" - skipping\n') % source)
+        ui.debug('acl: changes have source "%s" - skipping\n' % source)
         return
 
     user = None
@@ -99,9 +99,9 @@
         ctx = repo[rev]
         for f in ctx.files():
             if deny and deny(f):
-                ui.debug(_('acl: user %s denied on %s\n') % (user, f))
+                ui.debug('acl: user %s denied on %s\n' % (user, f))
                 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
             if allow and not allow(f):
-                ui.debug(_('acl: user %s not allowed on %s\n') % (user, f))
+                ui.debug('acl: user %s not allowed on %s\n' % (user, f))
                 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
-        ui.debug(_('acl: allowing changeset %s\n') % ctx)
+        ui.debug('acl: allowing changeset %s\n' % ctx)
--- a/hgext/churn.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/churn.py	Mon Sep 28 13:21:41 2009 -0700
@@ -148,11 +148,12 @@
     sortkey = ((not opts.get('sort')) and (lambda x: -x[1]) or None)
     rate.sort(key=sortkey)
 
-    maxcount = float(max([v for k, v in rate]))
-    maxname = max([len(k) for k, v in rate])
+    # Be careful not to have a zero maxcount (issue833)
+    maxcount = float(max(v for k, v in rate)) or 1.0
+    maxname = max(len(k) for k, v in rate)
 
     ttywidth = util.termwidth()
-    ui.debug(_("assuming %i character terminal\n") % ttywidth)
+    ui.debug("assuming %i character terminal\n" % ttywidth)
     width = ttywidth - maxname - 2 - 6 - 2 - 2
 
     for date, count in rate:
--- a/hgext/color.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/color.py	Mon Sep 28 13:21:41 2009 -0700
@@ -218,12 +218,8 @@
                  'changed': ['white'],
                  'trailingwhitespace': ['bold', 'red_background']}
 
-_ui = None
-
 def uisetup(ui):
     '''Initialize the extension.'''
-    global _ui
-    _ui = ui
     _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
     _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
     _setupcmd(ui, 'log', commands.table, None, _diff_effects)
@@ -231,17 +227,10 @@
     _setupcmd(ui, 'tip', commands.table, None, _diff_effects)
     _setupcmd(ui, 'status', commands.table, colorstatus, _status_effects)
 
-def extsetup():
     try:
         mq = extensions.find('mq')
-        try:
-            # If we are loaded after mq, we must wrap commands.table
-            _setupcmd(_ui, 'qdiff', commands.table, colordiff, _diff_effects)
-            _setupcmd(_ui, 'qseries', commands.table, colorqseries, _patch_effects)
-        except error.UnknownCommand:
-            # Otherwise we wrap mq.cmdtable
-            _setupcmd(_ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
-            _setupcmd(_ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
+        _setupcmd(ui, 'qdiff', mq.cmdtable, colordiff, _diff_effects)
+        _setupcmd(ui, 'qseries', mq.cmdtable, colorqseries, _patch_effects)
     except KeyError:
         # The mq extension is not enabled
         pass
@@ -267,7 +256,7 @@
     entry = extensions.wrapcommand(table, cmd, nocolor)
     entry[1].extend([
         ('', 'color', 'auto', _("when to colorize (always, auto, or never)")),
-        ('', 'no-color', None, _("don't colorize output")),
+        ('', 'no-color', None, _("don't colorize output (DEPRECATED)")),
     ])
 
     for status in effectsmap:
--- a/hgext/convert/__init__.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/__init__.py	Mon Sep 28 13:21:41 2009 -0700
@@ -178,9 +178,10 @@
         add the most recent revision on the branch indicated in the
         regex as the second parent of the changeset.
 
-    The hgext/convert/cvsps wrapper script allows the builtin
+    An additional "debugcvsps" Mercurial command allows the builtin
     changeset merging code to be run without doing a conversion. Its
-    parameters and output are similar to that of cvsps 2.1.
+    parameters and output are similar to that of cvsps 2.1. Please see
+    the command help for more details.
 
     Subversion Source
     -----------------
--- a/hgext/convert/common.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/common.py	Mon Sep 28 13:21:41 2009 -0700
@@ -203,6 +203,8 @@
         """Put tags into sink.
 
         tags: {tagname: sink_rev_id, ...} where tagname is an UTF-8 string.
+        Return a pair (tag_revision, tag_parent_revision), or (None, None)
+        if nothing was changed.
         """
         raise NotImplementedError()
 
@@ -264,7 +266,7 @@
 
     def _run(self, cmd, *args, **kwargs):
         cmdline = self._cmdline(cmd, *args, **kwargs)
-        self.ui.debug(_('running: %s\n') % (cmdline,))
+        self.ui.debug('running: %s\n' % (cmdline,))
         self.prerun()
         try:
             return util.popen(cmdline)
--- a/hgext/convert/convcmd.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/convcmd.py	Mon Sep 28 13:21:41 2009 -0700
@@ -336,11 +336,14 @@
                     ctags[k] = self.map[v]
 
             if c and ctags:
-                nrev = self.dest.puttags(ctags)
-                # write another hash correspondence to override the previous
-                # one so we don't end up with extra tag heads
-                if nrev:
-                    self.map[c] = nrev
+                nrev, tagsparent = self.dest.puttags(ctags)
+                if nrev and tagsparent:
+                    # write another hash correspondence to override the previous
+                    # one so we don't end up with extra tag heads
+                    tagsparents = [e for e in self.map.iteritems()
+                                   if e[1] == tagsparent]
+                    if tagsparents:
+                        self.map[tagsparents[0][0]] = nrev
 
             self.writeauthormap()
         finally:
--- a/hgext/convert/cvsps.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/cvsps.py	Mon Sep 28 13:21:41 2009 -0700
@@ -199,7 +199,7 @@
 
     cmd = [util.shellquote(arg) for arg in cmd]
     ui.note(_("running %s\n") % (' '.join(cmd)))
-    ui.debug(_("prefix=%r directory=%r root=%r\n") % (prefix, directory, root))
+    ui.debug("prefix=%r directory=%r root=%r\n" % (prefix, directory, root))
 
     pfp = util.popen(' '.join(cmd))
     peek = pfp.readline()
@@ -378,7 +378,7 @@
               e.revision[-1] == 1 and      # 1.1 or 1.1.x.1
               len(e.comment) == 1 and
               file_added_re.match(e.comment[0])):
-            ui.debug(_('found synthetic revision in %s: %r\n')
+            ui.debug('found synthetic revision in %s: %r\n'
                      % (e.rcs, e.comment[0]))
             e.synthetic = True
 
--- a/hgext/convert/darcs.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/darcs.py	Mon Sep 28 13:21:41 2009 -0700
@@ -75,7 +75,7 @@
         self.parents[child] = []
 
     def after(self):
-        self.ui.debug(_('cleaning up %s\n') % self.tmppath)
+        self.ui.debug('cleaning up %s\n' % self.tmppath)
         shutil.rmtree(self.tmppath, ignore_errors=True)
 
     def xml(self, cmd, **kwargs):
--- a/hgext/convert/gnuarch.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/gnuarch.py	Mon Sep 28 13:21:41 2009 -0700
@@ -125,7 +125,7 @@
                     break
 
     def after(self):
-        self.ui.debug(_('cleaning up %s\n') % self.tmppath)
+        self.ui.debug('cleaning up %s\n' % self.tmppath)
         shutil.rmtree(self.tmppath, ignore_errors=True)
 
     def getheads(self):
@@ -195,7 +195,7 @@
         return os.system(cmdline)
 
     def _update(self, rev):
-        self.ui.debug(_('applying revision %s...\n') % rev)
+        self.ui.debug('applying revision %s...\n' % rev)
         changeset, status = self.runlines('replay', '-d', self.tmppath,
                                               rev)
         if status:
@@ -205,7 +205,7 @@
             self._obtainrevision(rev)
         else:
             old_rev = self.parents[rev][0]
-            self.ui.debug(_('computing changeset between %s and %s...\n')
+            self.ui.debug('computing changeset between %s and %s...\n'
                           % (old_rev, rev))
             self._parsechangeset(changeset, rev)
 
@@ -254,10 +254,10 @@
         return changes, copies
 
     def _obtainrevision(self, rev):
-        self.ui.debug(_('obtaining revision %s...\n') % rev)
+        self.ui.debug('obtaining revision %s...\n' % rev)
         output = self._execute('get', rev, self.tmppath)
         self.checkexit(output)
-        self.ui.debug(_('analyzing revision %s...\n') % rev)
+        self.ui.debug('analyzing revision %s...\n' % rev)
         files = self._readcontents(self.tmppath)
         self.changes[rev].add_files += files
 
@@ -284,7 +284,7 @@
             self.changes[rev].summary = self.recode(self.changes[rev].summary)
 
             # Commit revision origin when dealing with a branch or tag
-            if catlog.has_key('Continuation-of'):
+            if 'Continuation-of' in catlog:
                 self.changes[rev].continuationof = self.recode(catlog['Continuation-of'])
         except Exception:
             raise util.Abort(_('could not parse cat-log of %s') % rev)
--- a/hgext/convert/hg.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/hg.py	Mon Sep 28 13:21:41 2009 -0700
@@ -55,12 +55,12 @@
         self.filemapmode = False
 
     def before(self):
-        self.ui.debug(_('run hg sink pre-conversion action\n'))
+        self.ui.debug('run hg sink pre-conversion action\n')
         self.wlock = self.repo.wlock()
         self.lock = self.repo.lock()
 
     def after(self):
-        self.ui.debug(_('run hg sink post-conversion action\n'))
+        self.ui.debug('run hg sink post-conversion action\n')
         self.lock.release()
         self.wlock.release()
 
@@ -189,7 +189,7 @@
 
         newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
         if newlines == oldlines:
-            return None
+            return None, None
         data = "".join(newlines)
         def getfilectx(repo, memctx, f):
             return context.memfilectx(f, data, False, False, None)
@@ -201,7 +201,7 @@
                              [".hgtags"], getfilectx, "convert-repo", date,
                              extra)
         self.repo.commitctx(ctx)
-        return hex(self.repo.changelog.tip())
+        return hex(self.repo.changelog.tip()), hex(tagparent)
 
     def setfilemapmode(self, active):
         self.filemapmode = active
@@ -348,10 +348,10 @@
         self.convertfp.flush()
 
     def before(self):
-        self.ui.debug(_('run hg source pre-conversion action\n'))
+        self.ui.debug('run hg source pre-conversion action\n')
 
     def after(self):
-        self.ui.debug(_('run hg source post-conversion action\n'))
+        self.ui.debug('run hg source post-conversion action\n')
 
     def hasnativeorder(self):
         return True
--- a/hgext/convert/p4.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/p4.py	Mon Sep 28 13:21:41 2009 -0700
@@ -53,7 +53,7 @@
     def _parse_view(self, path):
         "Read changes affecting the path"
         cmd = 'p4 -G changes -s submitted "%s"' % path
-        stdout = util.popen(cmd)
+        stdout = util.popen(cmd, mode='rb')
         for d in loaditer(stdout):
             c = d.get("change", None)
             if c:
@@ -72,7 +72,7 @@
                 views = {"//": ""}
         else:
             cmd = 'p4 -G client -o "%s"' % path
-            clientspec = marshal.load(util.popen(cmd))
+            clientspec = marshal.load(util.popen(cmd, mode='rb'))
 
             views = {}
             for client in clientspec:
@@ -105,7 +105,7 @@
         lastid = None
         for change in self.p4changes:
             cmd = "p4 -G describe %s" % change
-            stdout = util.popen(cmd)
+            stdout = util.popen(cmd, mode='rb')
             d = marshal.load(stdout)
 
             desc = self.recode(d["desc"])
@@ -147,7 +147,7 @@
 
     def getfile(self, name, rev):
         cmd = 'p4 -G print "%s#%s"' % (self.depotname[name], rev)
-        stdout = util.popen(cmd)
+        stdout = util.popen(cmd, mode='rb')
 
         mode = None
         contents = ""
--- a/hgext/convert/subversion.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/convert/subversion.py	Mon Sep 28 13:21:41 2009 -0700
@@ -22,6 +22,7 @@
 from common import commandline, converter_source, converter_sink, mapfile
 
 try:
+    raise "SVN support disabled due to license incompatibility"
     from svn.core import SubversionException, Pool
     import svn
     import svn.client
@@ -531,7 +532,7 @@
         """
         if not path.startswith(self.rootmodule):
             # Requests on foreign branches may be forbidden at server level
-            self.ui.debug(_('ignoring foreign branch %r\n') % path)
+            self.ui.debug('ignoring foreign branch %r\n' % path)
             return None
 
         if not stop:
@@ -559,7 +560,7 @@
                     if not path.startswith(p) or not paths[p].copyfrom_path:
                         continue
                     newpath = paths[p].copyfrom_path + path[len(p):]
-                    self.ui.debug(_("branch renamed from %s to %s at %d\n") %
+                    self.ui.debug("branch renamed from %s to %s at %d\n" %
                                   (path, newpath, revnum))
                     path = newpath
                     break
@@ -567,7 +568,7 @@
             stream.close()
 
         if not path.startswith(self.rootmodule):
-            self.ui.debug(_('ignoring foreign branch %r\n') % path)
+            self.ui.debug('ignoring foreign branch %r\n' % path)
             return None
         return self.revid(dirent.created_rev, path)
 
@@ -579,7 +580,7 @@
         prevmodule = self.prevmodule
         if prevmodule is None:
             prevmodule = ''
-        self.ui.debug(_("reparent to %s\n") % svnurl)
+        self.ui.debug("reparent to %s\n" % svnurl)
         svn.ra.reparent(self.ra, svnurl)
         self.prevmodule = module
         return prevmodule
@@ -612,14 +613,14 @@
                 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
                 if not copyfrom_path:
                     continue
-                self.ui.debug(_("copied to %s from %s@%s\n") %
+                self.ui.debug("copied to %s from %s@%s\n" %
                               (entrypath, copyfrom_path, ent.copyfrom_rev))
                 copies[self.recode(entrypath)] = self.recode(copyfrom_path)
             elif kind == 0: # gone, but had better be a deleted *file*
-                self.ui.debug(_("gone from %s\n") % ent.copyfrom_rev)
+                self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
                 pmodule, prevnum = self.revsplit(parents[0])[1:]
                 parentpath = pmodule + "/" + entrypath
-                self.ui.debug(_("entry %s\n") % parentpath)
+                self.ui.debug("entry %s\n" % parentpath)
 
                 # We can avoid the reparent calls if the module has
                 # not changed but it probably does not worth the pain.
@@ -646,7 +647,7 @@
                             del copies[childpath]
                         entries.append(childpath)
                 else:
-                    self.ui.debug(_('unknown path in revision %d: %s\n') % \
+                    self.ui.debug('unknown path in revision %d: %s\n' % \
                                   (revnum, path))
             elif kind == svn.core.svn_node_dir:
                 # If the directory just had a prop change,
@@ -679,7 +680,7 @@
                 if not copyfrompath:
                     continue
                 copyfrom[path] = ent
-                self.ui.debug(_("mark %s came from %s:%d\n")
+                self.ui.debug("mark %s came from %s:%d\n"
                               % (path, copyfrompath, ent.copyfrom_rev))
                 children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev)
                 children.sort()
@@ -703,7 +704,7 @@
             """Return the parsed commit object or None, and True if
             the revision is a branch root.
             """
-            self.ui.debug(_("parsing revision %d (%d changes)\n") %
+            self.ui.debug("parsing revision %d (%d changes)\n" %
                           (revnum, len(orig_paths)))
 
             branched = False
@@ -732,7 +733,7 @@
                             self.ui.note(_('found parent of branch %s at %d: %s\n') %
                                          (self.module, prevnum, prevmodule))
                 else:
-                    self.ui.debug(_("no copyfrom path, don't know what to do.\n"))
+                    self.ui.debug("no copyfrom path, don't know what to do.\n")
 
             paths = []
             # filter out unrelated paths
@@ -785,7 +786,7 @@
                         lastonbranch = True
                         break
                     if not paths:
-                        self.ui.debug(_('revision %d has no entries\n') % revnum)
+                        self.ui.debug('revision %d has no entries\n' % revnum)
                         continue
                     cset, lastonbranch = parselogentry(paths, revnum, author,
                                                        date, message)
@@ -867,7 +868,7 @@
                 return relative
 
         # The path is outside our tracked tree...
-        self.ui.debug(_('%r is not under %r, ignoring\n') % (path, module))
+        self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
         return None
 
     def _checkpath(self, path, revnum):
--- a/hgext/extdiff.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/extdiff.py	Mon Sep 28 13:21:41 2009 -0700
@@ -142,13 +142,13 @@
         cmdline = ('%s %s %s %s' %
                    (util.shellquote(diffcmd), ' '.join(diffopts),
                     util.shellquote(dir1), util.shellquote(dir2)))
-        ui.debug(_('running %r in %s\n') % (cmdline, tmproot))
+        ui.debug('running %r in %s\n' % (cmdline, tmproot))
         util.system(cmdline, cwd=tmproot)
 
         for copy_fn, working_fn, mtime in fns_and_mtime:
             if os.path.getmtime(copy_fn) != mtime:
-                ui.debug(_('file changed while diffing. '
-                         'Overwriting: %s (src: %s)\n') % (working_fn, copy_fn))
+                ui.debug('file changed while diffing. '
+                         'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
                 util.copyfile(copy_fn, working_fn)
 
         return 1
--- a/hgext/hgcia.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/hgcia.py	Mon Sep 28 13:21:41 2009 -0700
@@ -229,10 +229,10 @@
     n = bin(node)
     cia = hgcia(ui, repo)
     if not cia.user:
-        ui.debug(_('cia: no user specified'))
+        ui.debug('cia: no user specified')
         return
     if not cia.project:
-        ui.debug(_('cia: no project specified'))
+        ui.debug('cia: no project specified')
         return
     if hooktype == 'changegroup':
         start = repo.changelog.rev(n)
--- a/hgext/hgk.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/hgk.py	Mon Sep 28 13:21:41 2009 -0700
@@ -308,7 +308,7 @@
     os.chdir(repo.root)
     optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
     cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
-    ui.debug(_("running %s\n") % cmd)
+    ui.debug("running %s\n" % cmd)
     util.system(cmd)
 
 cmdtable = {
--- a/hgext/highlight/__init__.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/highlight/__init__.py	Mon Sep 28 13:21:41 2009 -0700
@@ -53,8 +53,9 @@
     req.respond(common.HTTP_OK, 'text/css')
     return ['/* pygments_style = %s */\n\n' % pg_style, fmter.get_style_defs('')]
 
-# monkeypatch in the new version
-extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight)
-extensions.wrapfunction(webcommands, 'annotate', annotate_highlight)
-webcommands.highlightcss = generate_css
-webcommands.__all__.append('highlightcss')
+def extsetup():
+    # monkeypatch in the new version
+    extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight)
+    extensions.wrapfunction(webcommands, 'annotate', annotate_highlight)
+    webcommands.highlightcss = generate_css
+    webcommands.__all__.append('highlightcss')
--- a/hgext/highlight/highlight.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/highlight/highlight.py	Mon Sep 28 13:21:41 2009 -0700
@@ -32,26 +32,27 @@
     if util.binary(text):
         return
 
-    # avoid UnicodeDecodeError in pygments
-    text = encoding.tolocal(text)
+    # Pygments is best used with Unicode strings:
+    # <http://pygments.org/docs/unicode/>
+    text = text.decode(encoding.encoding, 'replace')
 
     # To get multi-line strings right, we can't format line-by-line
     try:
-        lexer = guess_lexer_for_filename(fctx.path(), text[:1024],
-                                         encoding=encoding.encoding)
+        lexer = guess_lexer_for_filename(fctx.path(), text[:1024])
     except (ClassNotFound, ValueError):
         try:
-            lexer = guess_lexer(text[:1024], encoding=encoding.encoding)
+            lexer = guess_lexer(text[:1024])
         except (ClassNotFound, ValueError):
-            lexer = TextLexer(encoding=encoding.encoding)
+            lexer = TextLexer()
 
-    formatter = HtmlFormatter(style=style, encoding=encoding.encoding)
+    formatter = HtmlFormatter(style=style)
 
     colorized = highlight(text, lexer, formatter)
     # strip wrapping div
     colorized = colorized[:colorized.find('\n</pre>')]
     colorized = colorized[colorized.find('<pre>')+5:]
-    coloriter = iter(colorized.splitlines())
+    coloriter = (s.encode(encoding.encoding, 'replace')
+                 for s in colorized.splitlines())
 
     tmpl.filters['colorize'] = lambda x: coloriter.next()
 
--- a/hgext/inotify/client.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/inotify/client.py	Mon Sep 28 13:21:41 2009 -0700
@@ -31,7 +31,7 @@
                                'removing it)\n'))
                 os.unlink(os.path.join(self.root, '.hg', 'inotify.sock'))
             if err[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart:
-                self.ui.debug(_('(starting inotify server)\n'))
+                self.ui.debug('(starting inotify server)\n')
                 try:
                     try:
                         server.start(self.ui, self.dirstate, self.root)
@@ -50,7 +50,7 @@
                                        'server: %s\n') % err[-1])
             elif err[0] in (errno.ECONNREFUSED, errno.ENOENT):
                 # silently ignore normal errors if autostart is False
-                self.ui.debug(_('(inotify server not running)\n'))
+                self.ui.debug('(inotify server not running)\n')
             else:
                 self.ui.warn(_('failed to contact inotify server: %s\n')
                          % err[-1])
--- a/hgext/inotify/linux/_inotify.c	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/inotify/linux/_inotify.c	Mon Sep 28 13:21:41 2009 -0700
@@ -106,13 +106,12 @@
 
 static PyObject *remove_watch(PyObject *self, PyObject *args)
 {
-    PyObject *ret = NULL;
     uint32_t wd;
     int fd;
     int r;
 
     if (!PyArg_ParseTuple(args, "iI:remove_watch", &fd, &wd))
-	goto bail;
+	return NULL;
 
     Py_BEGIN_ALLOW_THREADS
     r = inotify_rm_watch(fd, wd);
@@ -120,18 +119,11 @@
 
     if (r == -1) {
 	PyErr_SetFromErrno(PyExc_OSError);
-	goto bail;
+	return NULL;
     }
 
     Py_INCREF(Py_None);
-
-    goto done;
-
-bail:
-    Py_CLEAR(ret);
-
-done:
-    return ret;
+    return Py_None;
 }
 
 PyDoc_STRVAR(
--- a/hgext/keyword.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/keyword.py	Mon Sep 28 13:21:41 2009 -0700
@@ -354,7 +354,7 @@
     repo.commit(text=msg)
     ui.status(_('\n\tkeywords expanded\n'))
     ui.write(repo.wread(fn))
-    ui.debug(_('\nremoving temporary repository %s\n') % tmpdir)
+    ui.debug('\nremoving temporary repository %s\n' % tmpdir)
     shutil.rmtree(tmpdir, ignore_errors=True)
 
 def expand(ui, repo, *pats, **opts):
--- a/hgext/mq.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/mq.py	Mon Sep 28 13:21:41 2009 -0700
@@ -321,7 +321,7 @@
             if bad:
                 raise util.Abort(bad)
         guards = sorted(set(guards))
-        self.ui.debug(_('active guards: %s\n') % ' '.join(guards))
+        self.ui.debug('active guards: %s\n' % ' '.join(guards))
         self.active_guards = guards
         self.guards_dirty = True
 
@@ -1865,6 +1865,39 @@
     repo.mq.qseries(repo, missing=opts['missing'], summary=opts['summary'])
     return 0
 
+def top(ui, repo, **opts):
+    """print the name of the current patch"""
+    q = repo.mq
+    t = q.applied and q.series_end(True) or 0
+    if t:
+        return q.qseries(repo, start=t-1, length=1, status='A',
+                         summary=opts.get('summary'))
+    else:
+        ui.write(_("no patches applied\n"))
+        return 1
+
+def next(ui, repo, **opts):
+    """print the name of the next patch"""
+    q = repo.mq
+    end = q.series_end()
+    if end == len(q.series):
+        ui.write(_("all patches applied\n"))
+        return 1
+    return q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
+
+def prev(ui, repo, **opts):
+    """print the name of the previous patch"""
+    q = repo.mq
+    l = len(q.applied)
+    if l == 1:
+        ui.write(_("only one patch applied\n"))
+        return 1
+    if not l:
+        ui.write(_("no patches applied\n"))
+        return 1
+    return q.qseries(repo, start=l-2, length=1, status='A',
+                     summary=opts.get('summary'))
+
 def setupheaderopts(ui, opts):
     def do(opt, val):
         if not opts[opt] and opts['current' + opt]:
@@ -2516,7 +2549,7 @@
     "qapplied":
         (applied,
          [('1', 'last', None, _('show only the last patch'))] + seriesopts,
-         _('hg qapplied [-s] [PATCH]')),
+         _('hg qapplied [-1] [-s] [PATCH]')),
     "qclone":
         (clone,
          [('', 'pull', None, _('use pull protocol to copy metadata')),
@@ -2579,6 +2612,8 @@
           ('d', 'date', '', _('add "Date: <given date>" to patch'))
           ] + commands.walkopts + commands.commitopts,
          _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
+    "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
+    "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
     "^qpop":
         (pop,
          [('a', 'all', None, _('pop all patches')),
@@ -2636,10 +2671,11 @@
           ('b', 'backup', None, _('bundle unrelated changesets')),
           ('n', 'nobackup', None, _('no backups'))],
          _('hg strip [-f] [-b] [-n] REV')),
+    "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
     "qunapplied":
         (unapplied,
          [('1', 'first', None, _('show only the first patch'))] + seriesopts,
-         _('hg qunapplied [-s] [PATCH]')),
+         _('hg qunapplied [-1] [-s] [PATCH]')),
     "qfinish":
         (finish,
          [('a', 'applied', None, _('finish all applied changesets'))],
--- a/hgext/notify.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/notify.py	Mon Sep 28 13:21:41 2009 -0700
@@ -276,10 +276,10 @@
     ctx = repo[node]
 
     if not n.subs:
-        ui.debug(_('notify: no subscribers to repository %s\n') % n.root)
+        ui.debug('notify: no subscribers to repository %s\n' % n.root)
         return
     if n.skipsource(source):
-        ui.debug(_('notify: changes have source "%s" - skipping\n') % source)
+        ui.debug('notify: changes have source "%s" - skipping\n' % source)
         return
 
     ui.pushbuffer()
--- a/hgext/rebase.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/rebase.py	Mon Sep 28 13:21:41 2009 -0700
@@ -35,7 +35,7 @@
     if not first:
         ancestor.ancestor = newancestor
     else:
-        repo.ui.debug(_("first revision, do not change ancestor\n"))
+        repo.ui.debug("first revision, do not change ancestor\n")
     stats = merge.update(repo, rev, True, True, False)
     return stats
 
@@ -149,7 +149,7 @@
     """Skip commit if collapsing has been required and rev is not the last
     revision, commit otherwise
     """
-    repo.ui.debug(_(" set parents\n"))
+    repo.ui.debug(" set parents\n")
     if collapse and not last:
         repo.dirstate.setparents(repo[p1].node())
         return None
@@ -187,23 +187,23 @@
 def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse,
                extrafn):
     'Rebase a single revision'
-    repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
+    repo.ui.debug("rebasing %d:%s\n" % (rev, repo[rev]))
 
     p1, p2 = defineparents(repo, rev, target, state, targetancestors)
 
-    repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(),
+    repo.ui.debug(" future parents are %d and %d\n" % (repo[p1].rev(),
                                                             repo[p2].rev()))
 
     # Merge phase
     if len(repo.parents()) != 2:
         # Update to target and merge it with local
         if repo['.'].rev() != repo[p1].rev():
-            repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1]))
+            repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
             merge.update(repo, p1, False, True, False)
         else:
-            repo.ui.debug(_(" already in target\n"))
+            repo.ui.debug(" already in target\n")
         repo.dirstate.write()
-        repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev]))
+        repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
         first = repo[rev].rev() == repo[min(state)].rev()
         stats = rebasemerge(repo, rev, first)
 
@@ -211,7 +211,7 @@
             raise util.Abort(_('fix unresolved conflicts with hg resolve then '
                                                 'run hg rebase --continue'))
     else: # we have an interrupted rebase
-        repo.ui.debug(_('resuming interrupted rebase\n'))
+        repo.ui.debug('resuming interrupted rebase\n')
 
     # Keep track of renamed files in the revision that is going to be rebased
     # Here we simulate the copies and renames in the source changeset
@@ -234,7 +234,7 @@
     else:
         if not collapse:
             repo.ui.note(_('no changes, revision %d skipped\n') % rev)
-            repo.ui.debug(_('next revision set to %s\n') % p1)
+            repo.ui.debug('next revision set to %s\n' % p1)
             skipped.add(rev)
         state[rev] = p1
 
@@ -280,7 +280,7 @@
     mqrebase = {}
     for p in repo.mq.applied:
         if repo[p.rev].rev() in state:
-            repo.ui.debug(_('revision %d is an mq patch (%s), finalize it.\n') %
+            repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
                                         (repo[p.rev].rev(), p.name))
             mqrebase[repo[p.rev].rev()] = (p.name, isagitpatch(repo, p.name))
 
@@ -290,7 +290,7 @@
         # We must start import from the newest revision
         for rev in sorted(mqrebase, reverse=True):
             if rev not in skipped:
-                repo.ui.debug(_('import mq patch %d (%s)\n')
+                repo.ui.debug('import mq patch %d (%s)\n'
                               % (state[rev], mqrebase[rev][0]))
                 repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
                             git=mqrebase[rev][1],rev=[str(state[rev])])
@@ -311,7 +311,7 @@
         newrev = repo[v].hex()
         f.write("%s:%s\n" % (oldrev, newrev))
     f.close()
-    repo.ui.debug(_('rebase status stored\n'))
+    repo.ui.debug('rebase status stored\n')
 
 def clearstatus(repo):
     'Remove the status files'
@@ -342,7 +342,7 @@
             else:
                 oldrev, newrev = l.split(':')
                 state[repo[oldrev].rev()] = repo[newrev].rev()
-        repo.ui.debug(_('rebase status resumed\n'))
+        repo.ui.debug('rebase status resumed\n')
         return originalwd, target, state, collapse, keep, keepbranches, external
     except IOError, err:
         if err.errno != errno.ENOENT:
@@ -392,12 +392,12 @@
             cwd = repo['.'].rev()
 
         if cwd == dest:
-            repo.ui.debug(_('already working on current\n'))
+            repo.ui.debug('already working on current\n')
             return None
 
         targetancestors = set(repo.changelog.ancestors(dest))
         if cwd in targetancestors:
-            repo.ui.debug(_('already working on the current branch\n'))
+            repo.ui.debug('already working on the current branch\n')
             return None
 
         cwdancestors = set(repo.changelog.ancestors(cwd))
@@ -405,7 +405,7 @@
         rebasingbranch = cwdancestors - targetancestors
         source = min(rebasingbranch)
 
-    repo.ui.debug(_('rebase onto %d starting from %d\n') % (dest, source))
+    repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
     state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
     external = nullrev
     if collapse:
@@ -429,8 +429,8 @@
     if opts.get('rebase'):
         if opts.get('update'):
             del opts['update']
-            ui.debug(_('--update and --rebase are not compatible, ignoring '
-                                        'the update flag\n'))
+            ui.debug('--update and --rebase are not compatible, ignoring '
+                     'the update flag\n')
 
         cmdutil.bail_if_changed(repo)
         revsprepull = len(repo)
--- a/hgext/record.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/record.py	Mon Sep 28 13:21:41 2009 -0700
@@ -463,7 +463,7 @@
                 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
                                                dir=backupdir)
                 os.close(fd)
-                ui.debug(_('backup %r as %r\n') % (f, tmpname))
+                ui.debug('backup %r as %r\n' % (f, tmpname))
                 util.copyfile(repo.wjoin(f), tmpname)
                 backups[f] = tmpname
 
@@ -481,7 +481,7 @@
             # 3b. (apply)
             if dopatch:
                 try:
-                    ui.debug(_('applying patch\n'))
+                    ui.debug('applying patch\n')
                     ui.debug(fp.getvalue())
                     pfiles = {}
                     patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
@@ -512,7 +512,7 @@
             # 5. finally restore backed-up files
             try:
                 for realname, tmpname in backups.iteritems():
-                    ui.debug(_('restoring %r to %r\n') % (tmpname, realname))
+                    ui.debug('restoring %r to %r\n' % (tmpname, realname))
                     util.copyfile(tmpname, repo.wjoin(realname))
                     os.unlink(tmpname)
                 os.rmdir(backupdir)
--- a/hgext/transplant.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/transplant.py	Mon Sep 28 13:21:41 2009 -0700
@@ -182,7 +182,7 @@
         fp.write("# HG changeset patch\n")
         fp.write("# User %s\n" % user)
         fp.write("# Date %d %d\n" % date)
-        fp.write(changelog[4])
+        fp.write(msg + '\n')
         fp.close()
 
         try:
--- a/hgext/win32mbcs.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/win32mbcs.py	Mon Sep 28 13:21:41 2009 -0700
@@ -101,7 +101,7 @@
     if args:
         args = list(args)
         args[0] = appendsep(args[0])
-    if kwds.has_key('path'):
+    if 'path' in kwds:
         kwds['path'] = appendsep(kwds['path'])
     return func(*args, **kwds)
 
@@ -123,7 +123,7 @@
 funcs = '''os.path.join os.path.split os.path.splitext
  os.path.splitunc os.path.normpath os.path.normcase os.makedirs
  mercurial.util.endswithsep mercurial.util.splitpath mercurial.util.checkcase
- mercurial.util.fspath mercurial.windows.pconvert'''
+ mercurial.util.fspath mercurial.util.pconvert mercurial.util.normpath'''
 
 # codec and alias names of sjis and big5 to be faked.
 problematic_encodings = '''big5 big5-tw csbig5 big5hkscs big5-hkscs
@@ -142,6 +142,6 @@
         for f in funcs.split():
             wrapname(f, wrapper)
         wrapname("mercurial.osutil.listdir", wrapperforlistdir)
-        ui.debug(_("[win32mbcs] activated with encoding: %s\n")
+        ui.debug("[win32mbcs] activated with encoding: %s\n"
                  % encoding.encoding)
 
--- a/hgext/zeroconf/__init__.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/hgext/zeroconf/__init__.py	Mon Sep 28 13:21:41 2009 -0700
@@ -101,17 +101,20 @@
     def __init__(self, repo, name=None):
         super(hgwebzc, self).__init__(repo, name)
         name = self.reponame or os.path.basename(repo.root)
+        path = self.repo.ui.config("web", "prefix", "").strip('/')
         desc = self.repo.ui.config("web", "description", name)
-        publish(name, desc, name, int(repo.ui.config("web", "port", 8000)))
+        publish(name, desc, path, int(repo.ui.config("web", "port", 8000)))
 
 class hgwebdirzc(hgwebdir_mod.hgwebdir):
-    def run(self):
+    def __init__(self, conf, baseui=None):
+        super(hgwebdirzc, self).__init__(conf, baseui)
+        prefix = self.ui.config("web", "prefix", "").strip('/') + '/'
         for r, p in self.repos:
             u = self.ui.copy()
             u.readconfig(os.path.join(p, '.hg', 'hgrc'))
             n = os.path.basename(r)
-            publish(n, "hgweb", p, int(u.config("web", "port", 8000)))
-        return super(hgwebdirzc, self).run()
+            path = (prefix + r).strip('/')
+            publish(n, "hgweb", path, int(u.config("web", "port", 8000)))
 
 # listen
 
--- a/mercurial/changegroup.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/changegroup.py	Mon Sep 28 13:21:41 2009 -0700
@@ -10,7 +10,7 @@
 import struct, os, bz2, zlib, tempfile
 
 def getchunk(source):
-    """get a chunk from a changegroup"""
+    """return the next chunk from changegroup 'source' as a string"""
     d = source.read(4)
     if not d:
         return ""
@@ -25,7 +25,8 @@
     return d
 
 def chunkiter(source):
-    """iterate through the chunks in source"""
+    """iterate through the chunks in source, yielding a sequence of chunks
+    (strings)"""
     while 1:
         c = getchunk(source)
         if not c:
@@ -33,10 +34,11 @@
         yield c
 
 def chunkheader(length):
-    """build a changegroup chunk header"""
+    """return a changegroup chunk header (string)"""
     return struct.pack(">l", length + 4)
 
 def closechunk():
+    """return a changegroup chunk header (string) for a zero-length chunk"""
     return struct.pack(">l", 0)
 
 class nocompress(object):
--- a/mercurial/commands.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/commands.py	Mon Sep 28 13:21:41 2009 -0700
@@ -1323,11 +1323,11 @@
                     continue
                 files.append(fn)
 
-                if not matches[rev].has_key(fn):
+                if fn not in matches[rev]:
                     grepbody(fn, rev, flog.read(fnode))
 
                 pfn = copy or fn
-                if not matches[parent].has_key(pfn):
+                if pfn not in matches[parent]:
                     try:
                         fnode = pctx.filenode(pfn)
                         grepbody(pfn, parent, flog.read(fnode))
@@ -1789,7 +1789,7 @@
                 else:
                     # launch the editor
                     message = None
-                ui.debug(_('message:\n%s\n') % message)
+                ui.debug('message:\n%s\n' % message)
 
                 wp = repo.parents()
                 if opts.get('exact'):
@@ -2044,7 +2044,7 @@
             if only_branches and ctx.branch() not in only_branches:
                 continue
 
-            if df and not df(ctx.date()):
+            if df and not df(ctx.date()[0]):
                 continue
 
             if opts.get('keyword'):
@@ -2155,7 +2155,8 @@
         roots, heads = [common.node()], [p2.node()]
         displayer = cmdutil.show_changeset(ui, repo, opts)
         for node in repo.changelog.nodesbetween(roots=roots, heads=heads)[0]:
-            displayer.show(repo[node])
+            if node not in roots:
+                displayer.show(repo[node])
         return 0
 
     return hg.merge(repo, node, force=opts.get('force'))
@@ -3046,7 +3047,10 @@
     if not rev:
         rev = node
 
-    if not clean and check:
+    if check and clean:
+        raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
+
+    if check:
         # we could use dirty() but we can ignore merge and branch trivia
         c = repo[None]
         if c.modified() or c.added() or c.removed():
@@ -3089,7 +3093,7 @@
 
 globalopts = [
     ('R', 'repository', '',
-     _('repository root directory or symbolic path name')),
+     _('repository root directory or name of overlay bundle file')),
     ('', 'cwd', '', _('change working directory')),
     ('y', 'noninteractive', None,
      _('do not prompt, assume \'yes\' for any required answers')),
--- a/mercurial/config.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/config.py	Mon Sep 28 13:21:41 2009 -0700
@@ -93,6 +93,7 @@
                     self.set(section, item, v, "%s:%d" % (src, line))
                     continue
                 item = None
+                cont = False
             m = includere.match(l)
             if m:
                 inc = m.group(1)
--- a/mercurial/copies.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/copies.py	Mon Sep 28 13:21:41 2009 -0700
@@ -144,16 +144,16 @@
             elif of in ma:
                 diverge.setdefault(of, []).append(f)
 
-    repo.ui.debug(_("  searching for copies back to rev %d\n") % limit)
+    repo.ui.debug("  searching for copies back to rev %d\n" % limit)
 
     u1 = _nonoverlap(m1, m2, ma)
     u2 = _nonoverlap(m2, m1, ma)
 
     if u1:
-        repo.ui.debug(_("  unmatched files in local:\n   %s\n")
+        repo.ui.debug("  unmatched files in local:\n   %s\n"
                       % "\n   ".join(u1))
     if u2:
-        repo.ui.debug(_("  unmatched files in other:\n   %s\n")
+        repo.ui.debug("  unmatched files in other:\n   %s\n"
                       % "\n   ".join(u2))
 
     for f in u1:
@@ -169,7 +169,7 @@
             diverge2.update(fl) # reverse map for below
 
     if fullcopy:
-        repo.ui.debug(_("  all copies found (* = to merge, ! = divergent):\n"))
+        repo.ui.debug("  all copies found (* = to merge, ! = divergent):\n")
         for f in fullcopy:
             note = ""
             if f in copy: note += "*"
@@ -180,7 +180,7 @@
     if not fullcopy or not checkdirs:
         return copy, diverge
 
-    repo.ui.debug(_("  checking for directory renames\n"))
+    repo.ui.debug("  checking for directory renames\n")
 
     # generate a directory move map
     d1, d2 = _dirs(m1), _dirs(m2)
@@ -216,7 +216,7 @@
         return copy, diverge
 
     for d in dirmove:
-        repo.ui.debug(_("  dir %s -> %s\n") % (d, dirmove[d]))
+        repo.ui.debug("  dir %s -> %s\n" % (d, dirmove[d]))
 
     # check unaccounted nonoverlapping files against directory moves
     for f in u1 + u2:
@@ -227,7 +227,7 @@
                     df = dirmove[d] + f[len(d):]
                     if df not in copy:
                         copy[f] = df
-                        repo.ui.debug(_("  file %s -> %s\n") % (f, copy[f]))
+                        repo.ui.debug("  file %s -> %s\n" % (f, copy[f]))
                     break
 
     return copy, diverge
--- a/mercurial/demandimport.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/demandimport.py	Mon Sep 28 13:21:41 2009 -0700
@@ -127,6 +127,8 @@
     # imported by profile, itself imported by hotshot.stats,
     # not available under Windows
     'resource',
+    # this trips up many extension authors
+    'gtk',
     ]
 
 def enable():
--- a/mercurial/dispatch.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/dispatch.py	Mon Sep 28 13:21:41 2009 -0700
@@ -24,6 +24,9 @@
     except util.Abort, inst:
         sys.stderr.write(_("abort: %s\n") % inst)
         return -1
+    except error.ConfigError, inst:
+        sys.stderr.write(_("hg: %s\n") % inst)
+        return -1
     return _runcatch(u, args)
 
 def _runcatch(ui, args):
@@ -214,7 +217,7 @@
 
     def __call__(self, ui, *args, **opts):
         if self.shadows:
-            ui.debug(_("alias '%s' shadows command\n") % self.name)
+            ui.debug("alias '%s' shadows command\n" % self.name)
 
         return self.fn(ui, *args, **opts)
 
@@ -335,7 +338,7 @@
     path = _findrepo(os.getcwd()) or ""
     if not path:
         lui = ui
-    if path:
+    else:
         try:
             lui = ui.copy()
             lui.readconfig(os.path.join(path, ".hg", "hgrc"))
@@ -349,19 +352,25 @@
         lui = ui.copy()
         lui.readconfig(os.path.join(path, ".hg", "hgrc"))
 
+    # Configure extensions in phases: uisetup, extsetup, cmdtable, and
+    # reposetup. Programs like TortoiseHg will call _dispatch several
+    # times so we keep track of configured extensions in _loaded.
     extensions.loadall(lui)
-    for name, module in extensions.extensions():
-        if name in _loaded:
-            continue
+    exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
 
-        # setup extensions
-        # TODO this should be generalized to scheme, where extensions can
-        #      redepend on other extensions.  then we should toposort them, and
-        #      do initialization in correct order
+    # (uisetup is handled in extensions.loadall)
+
+    for name, module in exts:
         extsetup = getattr(module, 'extsetup', None)
         if extsetup:
-            extsetup()
+            try:
+                extsetup(ui)
+            except TypeError:
+                if extsetup.func_code.co_argcount != 0:
+                    raise
+                extsetup() # old extsetup with no ui argument
 
+    for name, module in exts:
         cmdtable = getattr(module, 'cmdtable', {})
         overrides = [cmd for cmd in cmdtable if cmd in commands.table]
         if overrides:
@@ -370,6 +379,8 @@
         commands.table.update(cmdtable)
         _loaded.add(name)
 
+    # (reposetup is handled in hg.repository)
+
     addaliases(lui, commands.table)
 
     # check for fallback encoding
--- a/mercurial/error.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/error.py	Mon Sep 28 13:21:41 2009 -0700
@@ -36,6 +36,9 @@
 class RepoError(Exception):
     pass
 
+class RepoLookupError(RepoError):
+    pass
+
 class CapabilityError(RepoError):
     pass
 
--- a/mercurial/extensions.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/extensions.py	Mon Sep 28 13:21:41 2009 -0700
@@ -40,6 +40,7 @@
         return imp.load_source(module_name, path)
 
 def load(ui, name, path):
+    # unused ui argument kept for backwards compatibility
     if name.startswith('hgext.') or name.startswith('hgext/'):
         shortname = name[6:]
     else:
@@ -66,12 +67,9 @@
     _extensions[shortname] = mod
     _order.append(shortname)
 
-    uisetup = getattr(mod, 'uisetup', None)
-    if uisetup:
-        uisetup(ui)
-
 def loadall(ui):
     result = ui.configitems("extensions")
+    newindex = len(_order)
     for (name, path) in result:
         if path:
             if path[0] == '!':
@@ -90,6 +88,11 @@
             if ui.traceback():
                 return 1
 
+    for name in _order[newindex:]:
+        uisetup = getattr(_extensions[name], 'uisetup', None)
+        if uisetup:
+            uisetup(ui)
+
 def wrapcommand(table, command, wrapper):
     aliases, entry = cmdutil.findcmd(command, table)
     for alias, e in table.iteritems():
--- a/mercurial/filemerge.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/filemerge.py	Mon Sep 28 13:21:41 2009 -0700
@@ -140,7 +140,7 @@
     binary = isbin(fcd) or isbin(fco) or isbin(fca)
     symlink = 'l' in fcd.flags() + fco.flags()
     tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
-    ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") %
+    ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" %
                (tool, fd, binary, symlink))
 
     if not tool or tool == 'internal:prompt':
@@ -170,13 +170,13 @@
     else:
         ui.status(_("merging %s\n") % fd)
 
-    ui.debug(_("my %s other %s ancestor %s\n") % (fcd, fco, fca))
+    ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
 
     # do we attempt to simplemerge first?
     if _toolbool(ui, tool, "premerge", not (binary or symlink)):
         r = simplemerge.simplemerge(ui, a, b, c, quiet=True)
         if not r:
-            ui.debug(_(" premerge successful\n"))
+            ui.debug(" premerge successful\n")
             os.unlink(back)
             os.unlink(b)
             os.unlink(c)
--- a/mercurial/hg.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/hg.py	Mon Sep 28 13:21:41 2009 -0700
@@ -137,10 +137,12 @@
         if update is not True:
             checkout = update
         for test in (checkout, 'default', 'tip'):
+            if test is None:
+                continue
             try:
                 uprev = r.lookup(test)
                 break
-            except LookupError:
+            except error.RepoLookupError:
                 continue
         _update(r, uprev)
 
@@ -309,10 +311,12 @@
                 if update is not True:
                     checkout = update
                 for test in (checkout, 'default', 'tip'):
+                    if test is None:
+                        continue
                     try:
                         uprev = dest_repo.lookup(test)
                         break
-                    except:
+                    except error.RepoLookupError:
                         continue
                 _update(dest_repo, uprev)
 
@@ -323,12 +327,8 @@
             dir_cleanup.cleanup()
 
 def _showstats(repo, stats):
-    stats = ((stats[0], _("updated")),
-             (stats[1], _("merged")),
-             (stats[2], _("removed")),
-             (stats[3], _("unresolved")))
-    note = ", ".join([_("%d files %s") % s for s in stats])
-    repo.ui.status("%s\n" % note)
+    repo.ui.status(_("%d files updated, %d files merged, "
+                     "%d files removed, %d files unresolved\n") % stats)
 
 def update(repo, node):
     """update the working directory to node, merging linear changes"""
@@ -353,7 +353,7 @@
     _showstats(repo, stats)
     if stats[3]:
         repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
-                         "or 'hg up --clean' to abandon\n"))
+                         "or 'hg update -C' to abandon\n"))
     elif remind:
         repo.ui.status(_("(branch merge, don't forget to commit)\n"))
     return stats[3] > 0
--- a/mercurial/hgweb/webcommands.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/hgweb/webcommands.py	Mon Sep 28 13:21:41 2009 -0700
@@ -236,7 +236,11 @@
                           parity=parity.next()))
 
     parity = paritygen(web.stripecount)
-    diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity)
+    style = web.config('web', 'style', 'paper')
+    if 'style' in req.form:
+        style = req.form['style'][0]
+
+    diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style)
     return tmpl('changeset',
                 diff=diffs,
                 rev=ctx.rev(),
@@ -474,7 +478,11 @@
         # path already defined in except clause
 
     parity = paritygen(web.stripecount)
-    diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity)
+    style = web.config('web', 'style', 'paper')
+    if 'style' in req.form:
+        style = req.form['style'][0]
+
+    diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity, style)
     rename = fctx and webutil.renamelink(fctx) or []
     ctx = fctx and fctx or ctx
     return tmpl("filediff",
--- a/mercurial/hgweb/webutil.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/hgweb/webutil.py	Mon Sep 28 13:21:41 2009 -0700
@@ -153,7 +153,7 @@
     if len(files) > max:
         yield tmpl('fileellipses')
 
-def diffs(repo, tmpl, ctx, files, parity):
+def diffs(repo, tmpl, ctx, files, parity, style):
 
     def countgen():
         start = 1
@@ -195,7 +195,7 @@
             yield tmpl('diffblock', parity=parity.next(),
                        lines=prettyprintlines(''.join(block)))
             block = []
-        if chunk.startswith('diff'):
+        if chunk.startswith('diff') and style != 'raw':
             chunk = ''.join(chunk.splitlines(True)[1:])
         block.append(chunk)
     yield tmpl('diffblock', parity=parity.next(),
--- a/mercurial/httprepo.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/httprepo.py	Mon Sep 28 13:21:41 2009 -0700
@@ -35,7 +35,7 @@
         self._url, authinfo = url.getauthinfo(path)
 
         self.ui = ui
-        self.ui.debug(_('using %s\n') % self._url)
+        self.ui.debug('using %s\n' % self._url)
 
         self.urlopener = url.opener(ui, authinfo)
 
@@ -56,7 +56,7 @@
                 self.caps = set(self.do_read('capabilities').split())
             except error.RepoError:
                 self.caps = set()
-            self.ui.debug(_('capabilities: %s\n') %
+            self.ui.debug('capabilities: %s\n' %
                           (' '.join(self.caps or ['none'])))
         return self.caps
 
@@ -68,21 +68,21 @@
     def do_cmd(self, cmd, **args):
         data = args.pop('data', None)
         headers = args.pop('headers', {})
-        self.ui.debug(_("sending %s command\n") % cmd)
+        self.ui.debug("sending %s command\n" % cmd)
         q = {"cmd": cmd}
         q.update(args)
         qs = '?%s' % urllib.urlencode(q)
         cu = "%s%s" % (self._url, qs)
         try:
             if data:
-                self.ui.debug(_("sending %s bytes\n") % len(data))
+                self.ui.debug("sending %s bytes\n" % len(data))
             resp = self.urlopener.open(urllib2.Request(cu, data, headers))
         except urllib2.HTTPError, inst:
             if inst.code == 401:
                 raise util.Abort(_('authorization failed'))
             raise
         except httplib.HTTPException, inst:
-            self.ui.debug(_('http error while sending %s command\n') % cmd)
+            self.ui.debug('http error while sending %s command\n' % cmd)
             self.ui.traceback()
             raise IOError(None, inst)
         except IndexError:
@@ -105,7 +105,7 @@
         if not (proto.startswith('application/mercurial-') or
                 proto.startswith('text/plain') or
                 proto.startswith('application/hg-changegroup')):
-            self.ui.debug(_("requested URL: '%s'\n") % url.hidepassword(cu))
+            self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu))
             raise error.RepoError(_("'%s' does not appear to be an hg repository")
                                   % safeurl)
 
--- a/mercurial/localrepo.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/localrepo.py	Mon Sep 28 13:21:41 2009 -0700
@@ -459,7 +459,7 @@
                 key = hex(key)
         except:
             pass
-        raise error.RepoError(_("unknown revision '%s'") % key)
+        raise error.RepoLookupError(_("unknown revision '%s'") % key)
 
     def local(self):
         return True
@@ -527,7 +527,7 @@
 
         for mf, fn, cmd in self.filterpats[filter]:
             if mf(filename):
-                self.ui.debug(_("filtering %s through %s\n") % (filename, cmd))
+                self.ui.debug("filtering %s through %s\n" % (filename, cmd))
                 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
                 break
 
@@ -724,14 +724,14 @@
 
             # find source in nearest ancestor if we've lost track
             if not crev:
-                self.ui.debug(_(" %s: searching for copy revision for %s\n") %
+                self.ui.debug(" %s: searching for copy revision for %s\n" %
                               (fname, cfname))
                 for ancestor in self['.'].ancestors():
                     if cfname in ancestor:
                         crev = ancestor[cfname].filenode()
                         break
 
-            self.ui.debug(_(" %s: copy %s:%s\n") % (fname, cfname, hex(crev)))
+            self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
             meta["copy"] = cfname
             meta["copyrev"] = hex(crev)
             fparent1, fparent2 = nullid, newfparent
@@ -1159,17 +1159,24 @@
         return [n for (r, n) in sorted(heads)]
 
     def branchheads(self, branch=None, start=None, closed=False):
+        '''return a (possibly filtered) list of heads for the given branch
+
+        Heads are returned in topological order, from newest to oldest.
+        If branch is None, use the dirstate branch.
+        If start is not None, return only heads reachable from start.
+        If closed is True, return heads that are marked as closed as well.
+        '''
         if branch is None:
             branch = self[None].branch()
         branches = self.branchmap()
         if branch not in branches:
             return []
-        bheads = branches[branch]
         # the cache returns heads ordered lowest to highest
-        bheads.reverse()
+        bheads = list(reversed(branches[branch]))
         if start is not None:
             # filter out the heads that cannot be reached from startrev
-            bheads = self.changelog.nodesbetween([start], bheads)[2]
+            fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
+            bheads = [h for h in bheads if h in fbheads]
         if not closed:
             bheads = [h for h in bheads if
                       ('close' not in self.changelog.read(h)[5])]
@@ -1287,22 +1294,22 @@
                 if n[0] in seen:
                     continue
 
-                self.ui.debug(_("examining %s:%s\n")
+                self.ui.debug("examining %s:%s\n"
                               % (short(n[0]), short(n[1])))
                 if n[0] == nullid: # found the end of the branch
                     pass
                 elif n in seenbranch:
-                    self.ui.debug(_("branch already found\n"))
+                    self.ui.debug("branch already found\n")
                     continue
                 elif n[1] and n[1] in m: # do we know the base?
-                    self.ui.debug(_("found incomplete branch %s:%s\n")
+                    self.ui.debug("found incomplete branch %s:%s\n"
                                   % (short(n[0]), short(n[1])))
                     search.append(n[0:2]) # schedule branch range for scanning
                     seenbranch.add(n)
                 else:
                     if n[1] not in seen and n[1] not in fetch:
                         if n[2] in m and n[3] in m:
-                            self.ui.debug(_("found new changeset %s\n") %
+                            self.ui.debug("found new changeset %s\n" %
                                           short(n[1]))
                             fetch.add(n[1]) # earliest unknown
                         for p in n[2:4]:
@@ -1317,11 +1324,11 @@
 
             if r:
                 reqcnt += 1
-                self.ui.debug(_("request %d: %s\n") %
+                self.ui.debug("request %d: %s\n" %
                             (reqcnt, " ".join(map(short, r))))
                 for p in xrange(0, len(r), 10):
                     for b in remote.branches(r[p:p+10]):
-                        self.ui.debug(_("received %s:%s\n") %
+                        self.ui.debug("received %s:%s\n" %
                                       (short(b[0]), short(b[1])))
                         unknown.append(b)
 
@@ -1334,15 +1341,15 @@
                 p = n[0]
                 f = 1
                 for i in l:
-                    self.ui.debug(_("narrowing %d:%d %s\n") % (f, len(l), short(i)))
+                    self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
                     if i in m:
                         if f <= 2:
-                            self.ui.debug(_("found new branch changeset %s\n") %
+                            self.ui.debug("found new branch changeset %s\n" %
                                               short(p))
                             fetch.add(p)
                             base[i] = 1
                         else:
-                            self.ui.debug(_("narrowed branch search to %s:%s\n")
+                            self.ui.debug("narrowed branch search to %s:%s\n"
                                           % (short(p), short(i)))
                             newsearch.append((p, i))
                         break
@@ -1361,10 +1368,10 @@
             else:
                 raise util.Abort(_("repository is unrelated"))
 
-        self.ui.debug(_("found new changesets starting at ") +
+        self.ui.debug("found new changesets starting at " +
                      " ".join([short(f) for f in fetch]) + "\n")
 
-        self.ui.debug(_("%d total queries\n") % reqcnt)
+        self.ui.debug("%d total queries\n" % reqcnt)
 
         return base.keys(), list(fetch), heads
 
@@ -1381,7 +1388,7 @@
             base = {}
             self.findincoming(remote, base, heads, force=force)
 
-        self.ui.debug(_("common changesets up to ")
+        self.ui.debug("common changesets up to "
                       + " ".join(map(short, base.keys())) + "\n")
 
         remain = set(self.changelog.nodemap)
@@ -1457,24 +1464,27 @@
         return self.push_addchangegroup(remote, force, revs)
 
     def prepush(self, remote, force, revs):
+        '''Analyze the local and remote repositories and determine which
+        changesets need to be pushed to the remote.  Return a tuple
+        (changegroup, remoteheads).  changegroup is a readable file-like
+        object whose read() returns successive changegroup chunks ready to
+        be sent over the wire.  remoteheads is the list of remote heads.
+        '''
         common = {}
         remote_heads = remote.heads()
         inc = self.findincoming(remote, common, remote_heads, force=force)
 
         update, updated_heads = self.findoutgoing(remote, common, remote_heads)
-        if revs is not None:
-            msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
-        else:
-            bases, heads = update, self.changelog.heads()
+        msng_cl, bases, heads = self.changelog.nodesbetween(update, revs)
 
-        def checkbranch(lheads, rheads, updatelh):
+        def checkbranch(lheads, rheads, updatelb):
             '''
             check whether there are more local heads than remote heads on
             a specific branch.
 
             lheads: local branch heads
             rheads: remote branch heads
-            updatelh: outgoing local branch heads
+            updatelb: outgoing local branch bases
             '''
 
             warn = 0
@@ -1482,13 +1492,15 @@
             if not revs and len(lheads) > len(rheads):
                 warn = 1
             else:
+                # add local heads involved in the push
                 updatelheads = [self.changelog.heads(x, lheads)
-                                for x in updatelh]
+                                for x in updatelb]
                 newheads = set(sum(updatelheads, [])) & set(lheads)
 
                 if not newheads:
                     return True
 
+                # add heads we don't have or that are not involved in the push
                 for r in rheads:
                     if r in self.changelog.nodemap:
                         desc = self.changelog.heads(r, heads)
@@ -1504,7 +1516,7 @@
                 if not rheads: # new branch requires --force
                     self.ui.warn(_("abort: push creates new"
                                    " remote branch '%s'!\n") %
-                                   self[updatelh[0]].branch())
+                                   self[updatelb[0]].branch())
                 else:
                     self.ui.warn(_("abort: push creates new remote heads!\n"))
 
@@ -1547,11 +1559,11 @@
                         else:
                             rheads = []
                         lheads = localhds[lh]
-                        updatelh = [upd for upd in update
+                        updatelb = [upd for upd in update
                                     if self[upd].branch() == lh]
-                        if not updatelh:
+                        if not updatelb:
                             continue
-                        if not checkbranch(lheads, rheads, updatelh):
+                        if not checkbranch(lheads, rheads, updatelb):
                             return None, 0
                 else:
                     if not checkbranch(heads, remote_heads, update):
@@ -1596,14 +1608,15 @@
         if self.ui.verbose or source == 'bundle':
             self.ui.status(_("%d changesets found\n") % len(nodes))
         if self.ui.debugflag:
-            self.ui.debug(_("list of changesets:\n"))
+            self.ui.debug("list of changesets:\n")
             for node in nodes:
                 self.ui.debug("%s\n" % hex(node))
 
     def changegroupsubset(self, bases, heads, source, extranodes=None):
-        """This function generates a changegroup consisting of all the nodes
-        that are descendents of any of the bases, and ancestors of any of
-        the heads.
+        """Compute a changegroup consisting of all the nodes that are
+        descendents of any of the bases and ancestors of any of the heads.
+        Return a chunkbuffer object whose read() method will return
+        successive changegroup chunks.
 
         It is fairly complex as determining which filenodes and which
         manifest nodes need to be included for the changeset to be complete
@@ -1902,8 +1915,9 @@
         return self.changegroupsubset(basenodes, self.heads(), source)
 
     def _changegroup(self, common, source):
-        """Generate a changegroup of all nodes that we have that a recipient
-        doesn't.
+        """Compute the changegroup of all nodes that we have that a recipient
+        doesn't.  Return a chunkbuffer object whose read() method will return
+        successive changegroup chunks.
 
         This is much easier than the previous function as we can assume that
         the recipient has any changenode we aren't sending them.
@@ -1937,6 +1951,7 @@
             return lookuprevlink
 
         def gengroup():
+            '''yield a sequence of changegroup chunks (strings)'''
             # construct a list of all changed files
             changedfiles = set()
 
@@ -1979,7 +1994,7 @@
         - number of heads stays the same: 1
         """
         def csmap(x):
-            self.ui.debug(_("add changeset %s\n") % short(x))
+            self.ui.debug("add changeset %s\n" % short(x))
             return len(cl)
 
         def revmap(x):
@@ -2025,7 +2040,7 @@
                 f = changegroup.getchunk(source)
                 if not f:
                     break
-                self.ui.debug(_("adding %s revisions\n") % f)
+                self.ui.debug("adding %s revisions\n" % f)
                 fl = self.file(f)
                 o = len(fl)
                 chunkiter = changegroup.chunkiter(source)
@@ -2058,7 +2073,7 @@
 
         if changesets > 0:
             # forcefully update the on-disk branch cache
-            self.ui.debug(_("updating the branch cache\n"))
+            self.ui.debug("updating the branch cache\n")
             self.branchtags()
             self.hook("changegroup", node=hex(cl.node(clstart)),
                       source=srctype, url=url)
@@ -2107,7 +2122,7 @@
             except (ValueError, TypeError):
                 raise error.ResponseError(
                     _('Unexpected response from remote server:'), l)
-            self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size)))
+            self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
             # for backwards compat, name was partially encoded
             ofp = self.sopener(store.decodedir(name), 'w')
             for chunk in util.filechunkiter(fp, limit=size):
--- a/mercurial/manifest.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/manifest.py	Mon Sep 28 13:21:41 2009 -0700
@@ -20,12 +20,11 @@
     def set(self, f, flags):
         self._flags[f] = flags
     def copy(self):
-        return manifestdict(dict.copy(self), dict.copy(self._flags))
+        return manifestdict(self, dict.copy(self._flags))
 
 class manifest(revlog.revlog):
     def __init__(self, opener):
-        self.mapcache = None
-        self.listcache = None
+        self._mancache = None
         revlog.revlog.__init__(self, opener, "00manifest.i")
 
     def parse(self, lines):
@@ -40,12 +39,12 @@
     def read(self, node):
         if node == revlog.nullid:
             return manifestdict() # don't upset local cache
-        if self.mapcache and self.mapcache[0] == node:
-            return self.mapcache[1]
+        if self._mancache and self._mancache[0] == node:
+            return self._mancache[1]
         text = self.revision(node)
-        self.listcache = array.array('c', text)
+        arraytext = array.array('c', text)
         mapping = self.parse(text)
-        self.mapcache = (node, mapping)
+        self._mancache = (node, mapping, arraytext)
         return mapping
 
     def _search(self, m, s, lo=0, hi=None):
@@ -93,8 +92,8 @@
     def find(self, node, f):
         '''look up entry for a single file efficiently.
         return (node, flags) pair if found, (None, None) if not.'''
-        if self.mapcache and node == self.mapcache[0]:
-            return self.mapcache[1].get(f), self.mapcache[1].flags(f)
+        if self._mancache and self._mancache[0] == node:
+            return self._mancache[1].get(f), self._mancache[1].flags(f)
         text = self.revision(node)
         start, end = self._search(text, f)
         if start == end:
@@ -110,17 +109,13 @@
         def addlistdelta(addlist, x):
             # start from the bottom up
             # so changes to the offsets don't mess things up.
-            i = len(x)
-            while i > 0:
-                i -= 1
-                start = x[i][0]
-                end = x[i][1]
-                if x[i][2]:
-                    addlist[start:end] = array.array('c', x[i][2])
+            for start, end, content in reversed(x):
+                if content:
+                    addlist[start:end] = array.array('c', content)
                 else:
                     del addlist[start:end]
-            return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2]
-                            for d in x ])
+            return "".join(struct.pack(">lll", start, end, len(content)) + content
+                           for start, end, content in x)
 
         def checkforbidden(l):
             for f in l:
@@ -128,26 +123,29 @@
                     raise error.RevlogError(
                         _("'\\n' and '\\r' disallowed in filenames: %r") % f)
 
-        # if we're using the listcache, make sure it is valid and
+        # if we're using the cache, make sure it is valid and
         # parented by the same node we're diffing against
-        if not (changed and self.listcache and p1 and self.mapcache[0] == p1):
+        if not (changed and self._mancache and p1 and self._mancache[0] == p1):
             files = sorted(map)
             checkforbidden(files)
 
             # if this is changed to support newlines in filenames,
             # be sure to check the templates/ dir again (especially *-raw.tmpl)
             hex, flags = revlog.hex, map.flags
-            text = ["%s\000%s%s\n" % (f, hex(map[f]), flags(f))
-                    for f in files]
-            self.listcache = array.array('c', "".join(text))
+            text = ''.join("%s\000%s%s\n" % (f, hex(map[f]), flags(f))
+                           for f in files)
+            arraytext = array.array('c', text)
             cachedelta = None
         else:
-            addlist = self.listcache
+            added, removed = changed
+            addlist = self._mancache[2]
 
-            checkforbidden(changed[0])
+            checkforbidden(added)
             # combine the changed lists into one list for sorting
-            work = [[x, 0] for x in changed[0]]
-            work[len(work):] = [[x, 1] for x in changed[1]]
+            work = [(x, False) for x in added]
+            work.extend((x, True) for x in removed)
+            # this could use heapq.merge() (from python2.6+) or equivalent
+            # since the lists are already sorted
             work.sort()
 
             delta = []
@@ -160,18 +158,17 @@
 
             # start with a readonly loop that finds the offset of
             # each line and creates the deltas
-            for w in work:
-                f = w[0]
+            for f, todelete in work:
                 # bs will either be the index of the item or the insert point
                 start, end = self._search(addbuf, f, start)
-                if w[1] == 0:
+                if not todelete:
                     l = "%s\000%s%s\n" % (f, revlog.hex(map[f]), map.flags(f))
                 else:
+                    if start == end:
+                        # item we want to delete was not found, error out
+                        raise AssertionError(
+                                _("failed to remove %s from manifest") % f)
                     l = ""
-                if start == end and w[1] == 1:
-                    # item we want to delete was not found, error out
-                    raise AssertionError(
-                            _("failed to remove %s from manifest") % f)
                 if dstart != None and dstart <= start and dend >= start:
                     if dend < end:
                         dend = end
@@ -190,12 +187,12 @@
             cachedelta = addlistdelta(addlist, delta)
 
             # the delta is only valid if we've been processing the tip revision
-            if self.mapcache[0] != self.tip():
+            if p1 != self.tip():
                 cachedelta = None
-            self.listcache = addlist
+            arraytext = addlist
+            text = buffer(arraytext)
 
-        n = self.addrevision(buffer(self.listcache), transaction, link,
-                             p1, p2, cachedelta)
-        self.mapcache = (n, map)
+        n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
+        self._mancache = (n, map, arraytext)
 
         return n
--- a/mercurial/merge.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/merge.py	Mon Sep 28 13:21:41 2009 -0700
@@ -161,8 +161,8 @@
             act("divergent renames", "dr", of, fl)
 
     repo.ui.note(_("resolving manifests\n"))
-    repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
-    repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
+    repo.ui.debug(" overwrite %s partial %s\n" % (overwrite, bool(partial)))
+    repo.ui.debug(" ancestor %s local %s remote %s\n" % (pa, p1, p2))
 
     m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
     copied = set(copy.values())
@@ -252,7 +252,7 @@
             f2, fd, flags, move = a[2:]
             if f == '.hgsubstate': # merged internally
                 continue
-            repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
+            repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
             fcl = wctx[f]
             fco = mctx[f2]
             fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
@@ -263,7 +263,7 @@
     # remove renamed files after safely stored
     for f in moves:
         if util.lexists(repo.wjoin(f)):
-            repo.ui.debug(_("removing %s\n") % f)
+            repo.ui.debug("removing %s\n" % f)
             os.unlink(repo.wjoin(f))
 
     audit_path = util.path_auditor(repo.root)
@@ -299,7 +299,7 @@
                     merged += 1
             util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
             if f != fd and move and util.lexists(repo.wjoin(f)):
-                repo.ui.debug(_("removing %s\n") % f)
+                repo.ui.debug("removing %s\n" % f)
                 os.unlink(repo.wjoin(f))
         elif m == "g": # get
             flags = a[2]
--- a/mercurial/minirst.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/minirst.py	Mon Sep 28 13:21:41 2009 -0700
@@ -279,6 +279,8 @@
 
 def formatblock(block, width):
     """Format a block according to width."""
+    if width <= 0:
+        width = 78
     indent = ' ' * block['indent']
     if block['type'] == 'margin':
         return ''
--- a/mercurial/parsers.c	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/parsers.c	Mon Sep 28 13:21:41 2009 -0700
@@ -92,8 +92,6 @@
 			goto bail;
 
 		if (nlen > 40) {
-			PyObject *flags;
-
 			flags = PyString_FromStringAndSize(zero + 41,
 							   nlen - 40);
 			if (!flags)
--- a/mercurial/patch.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/patch.py	Mon Sep 28 13:21:41 2009 -0700
@@ -93,12 +93,12 @@
                 hgpatch = False
                 ignoretext = False
 
-                ui.debug(_('found patch at byte %d\n') % m.start(0))
+                ui.debug('found patch at byte %d\n' % m.start(0))
                 diffs_seen += 1
                 cfp = cStringIO.StringIO()
                 for line in payload[:m.start(0)].splitlines():
                     if line.startswith('# HG changeset patch'):
-                        ui.debug(_('patch generated by hg export\n'))
+                        ui.debug('patch generated by hg export\n')
                         hgpatch = True
                         # drop earlier commit message content
                         cfp.seek(0)
@@ -188,7 +188,7 @@
             if m:
                 if gp:
                     gitpatches.append(gp)
-                src, dst = m.group(1, 2)
+                dst = m.group(2)
                 gp = patchmeta(dst)
                 gp.lineno = lineno
         elif gp:
@@ -378,15 +378,13 @@
         self.write()
         self.write_rej()
 
-    def apply(self, h, reverse):
+    def apply(self, h):
         if not h.complete():
             raise PatchError(_("bad hunk #%d %s (%d %d %d %d)") %
                             (h.number, h.desc, len(h.a), h.lena, len(h.b),
                             h.lenb))
 
         self.hunks += 1
-        if reverse:
-            h.reverse()
 
         if self.missing:
             self.rej.append(h)
@@ -600,31 +598,6 @@
                                              self.startb, self.lenb)
         self.hunk[0] = self.desc
 
-    def reverse(self):
-        self.create, self.remove = self.remove, self.create
-        origlena = self.lena
-        origstarta = self.starta
-        self.lena = self.lenb
-        self.starta = self.startb
-        self.lenb = origlena
-        self.startb = origstarta
-        self.a = []
-        self.b = []
-        # self.hunk[0] is the @@ description
-        for x in xrange(1, len(self.hunk)):
-            o = self.hunk[x]
-            if o.startswith('-'):
-                n = '+' + o[1:]
-                self.b.append(o[1:])
-            elif o.startswith('+'):
-                n = '-' + o[1:]
-                self.a.append(n)
-            else:
-                n = o
-                self.b.append(o[1:])
-                self.a.append(o)
-            self.hunk[x] = o
-
     def fix_newline(self):
         diffhelpers.fix_newline(self.hunk, self.a, self.b)
 
@@ -762,7 +735,7 @@
             return s
     return s[:i]
 
-def selectfile(afile_orig, bfile_orig, hunk, strip, reverse):
+def selectfile(afile_orig, bfile_orig, hunk, strip):
     def pathstrip(path, count=1):
         pathlen = len(path)
         i = 0
@@ -790,8 +763,6 @@
     else:
         goodb = not nullb and os.path.exists(bfile)
     createfunc = hunk.createfile
-    if reverse:
-        createfunc = hunk.rmfile
     missing = not goodb and not gooda and not createfunc()
 
     # some diff programs apparently produce create patches where the
@@ -977,8 +948,7 @@
     if hunknum == 0 and dopatch and not gitworkdone:
         raise NoHunks
 
-def applydiff(ui, fp, changed, strip=1, sourcefile=None, reverse=False,
-              eol=None):
+def applydiff(ui, fp, changed, strip=1, sourcefile=None, eol=None):
     """
     Reads a patch from fp and tries to apply it.
 
@@ -1008,7 +978,7 @@
             if not current_file:
                 continue
             current_hunk = values
-            ret = current_file.apply(current_hunk, reverse)
+            ret = current_file.apply(current_hunk)
             if ret >= 0:
                 changed.setdefault(current_file.fname, None)
                 if ret > 0:
@@ -1021,7 +991,7 @@
                     current_file = patchfile(ui, sourcefile, opener, eol=eol)
                 else:
                     current_file, missing = selectfile(afile, bfile, first_hunk,
-                                            strip, reverse)
+                                            strip)
                     current_file = patchfile(ui, current_file, opener, missing, eol)
             except PatchError, err:
                 ui.warn(str(err) + '\n')
@@ -1185,7 +1155,7 @@
                 return internalpatch(patchname, ui, strip, cwd, files, eolmode)
             except NoHunks:
                 patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch'
-                ui.debug(_('no valid hunks found; trying with %r instead\n') %
+                ui.debug('no valid hunks found; trying with %r instead\n' %
                          patcher)
                 if util.needbinarypatch():
                     args.append('--binary')
--- a/mercurial/repo.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/repo.py	Mon Sep 28 13:21:41 2009 -0700
@@ -40,4 +40,5 @@
         url = self.url()
         if url.endswith('/'):
             return url + path
-        return url + '/' + path
+        else:
+            return url + '/' + path
--- a/mercurial/revlog.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/revlog.py	Mon Sep 28 13:21:41 2009 -0700
@@ -973,7 +973,7 @@
         if node == nullid:
             return ""
         if self._cache and self._cache[0] == node:
-            return str(self._cache[2])
+            return self._cache[2]
 
         # look up what we need to read
         text = None
@@ -988,7 +988,7 @@
         # do we have useful data cached?
         if self._cache and self._cache[1] >= base and self._cache[1] < rev:
             base = self._cache[1]
-            text = str(self._cache[2])
+            text = self._cache[2]
 
         self._loadindex(base, rev + 1)
         self._chunkraw(base, rev)
@@ -1111,7 +1111,8 @@
             ifh.write(data[1])
             self.checkinlinesize(transaction, ifh)
 
-        self._cache = (node, curr, text)
+        if type(text) == str: # only accept immutable objects
+            self._cache = (node, curr, text)
         return node
 
     def ancestor(self, a, b):
@@ -1127,7 +1128,8 @@
         return self.node(c)
 
     def group(self, nodelist, lookup, infocollect=None):
-        """calculate a delta group
+        """Calculate a delta group, yielding a sequence of changegroup chunks
+        (strings).
 
         Given a list of changeset revs, return a set of deltas and
         metadata corresponding to nodes. the first delta is
--- a/mercurial/sshrepo.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/sshrepo.py	Mon Sep 28 13:21:41 2009 -0700
@@ -75,7 +75,7 @@
             if lines[-1] == "1\n" and l == "\n":
                 break
             if l:
-                ui.debug(_("remote: "), l)
+                ui.debug("remote: ", l)
             lines.append(l)
             max_noise -= 1
         else:
@@ -113,7 +113,7 @@
     __del__ = cleanup
 
     def do_cmd(self, cmd, **args):
-        self.ui.debug(_("sending %s command\n") % cmd)
+        self.ui.debug("sending %s command\n" % cmd)
         self.pipeo.write("%s\n" % cmd)
         for k, v in args.iteritems():
             self.pipeo.write("%s %d\n" % (k, len(v)))
--- a/mercurial/streamclone.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/streamclone.py	Mon Sep 28 13:21:41 2009 -0700
@@ -46,7 +46,7 @@
         # get consistent snapshot of repo, lock during scan
         lock = repo.lock()
         try:
-            repo.ui.debug(_('scanning\n'))
+            repo.ui.debug('scanning\n')
             for name, ename, size in repo.store.walk():
                 # for backwards compat, name was partially encoded
                 entries.append((store.encodedir(name), size))
@@ -57,11 +57,11 @@
         raise StreamException(2)
 
     yield '0\n'
-    repo.ui.debug(_('%d files, %d bytes to transfer\n') %
+    repo.ui.debug('%d files, %d bytes to transfer\n' %
                   (len(entries), total_bytes))
     yield '%d %d\n' % (len(entries), total_bytes)
     for name, size in entries:
-        repo.ui.debug(_('sending %s (%d bytes)\n') % (name, size))
+        repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
         yield '%s\0%d\n' % (name, size)
         for chunk in util.filechunkiter(repo.sopener(name), limit=size):
             yield chunk
--- a/mercurial/ui.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/ui.py	Mon Sep 28 13:21:41 2009 -0700
@@ -199,7 +199,7 @@
     def _path(self, loc):
         p = self.config('paths', loc)
         if p and '%%' in p:
-            self.warn('(deprecated \'%%\' in path %s=%s from %s)\n' %
+            self.warn("(deprecated '%%' in path %s=%s from %s)\n" %
                     (loc, p, self.configsource('paths', loc)))
             p = p.replace('%%', '%')
         return p
@@ -358,7 +358,7 @@
         visible. 'topic' is the current operation, 'item' is a
         non-numeric marker of the current position (ie the currently
         in-process file), 'pos' is the current numeric position (ie
-        revision, bytes, etc.), units is a corresponding unit label,
+        revision, bytes, etc.), unit is a corresponding unit label,
         and total is the highest expected pos.
 
         Multiple nested topics may be active at a time. All topics
@@ -368,14 +368,14 @@
         if pos == None or not self.debugflag:
             return
 
-        if units:
-            units = ' ' + units
+        if unit:
+            unit = ' ' + unit
         if item:
             item = ' ' + item
 
         if total:
             pct = 100.0 * pos / total
             ui.debug('%s:%s %s/%s%s (%4.2g%%)\n'
-                     % (topic, item, pos, total, units, pct))
+                     % (topic, item, pos, total, unit, pct))
         else:
-            ui.debug('%s:%s %s%s\n' % (topic, item, pos, units))
+            ui.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
--- a/mercurial/url.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/url.py	Mon Sep 28 13:21:41 2009 -0700
@@ -197,7 +197,7 @@
                                                 proxyuser, proxypasswd or ''),
                 proxypath, proxyquery, proxyfrag))
             proxies = {'http': proxyurl, 'https': proxyurl}
-            ui.debug(_('proxying through http://%s:%s\n') %
+            ui.debug('proxying through http://%s:%s\n' %
                       (proxyhost, proxyport))
         else:
             proxies = {}
@@ -504,7 +504,7 @@
     if authinfo is not None:
         passmgr.add_password(*authinfo)
         user, passwd = authinfo[2:4]
-        ui.debug(_('http auth: user %s, password %s\n') %
+        ui.debug('http auth: user %s, password %s\n' %
                  (user, passwd and '*' * len(passwd) or 'not set'))
 
     handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr),
--- a/mercurial/util.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/util.py	Mon Sep 28 13:21:41 2009 -0700
@@ -14,7 +14,7 @@
 """
 
 from i18n import _
-import error, osutil
+import error, osutil, encoding
 import cStringIO, errno, re, shutil, sys, tempfile, traceback
 import os, stat, time, calendar, random, textwrap
 import imp
@@ -661,8 +661,9 @@
         contents = _fspathcache[dir]
 
         lpart = part.lower()
+        lenp = len(part)
         for n in contents:
-            if n.lower() == lpart:
+            if lenp == len(n) and n.lower() == lpart:
                 result.append(n)
                 break
         else:
@@ -1273,8 +1274,15 @@
 def wrap(line, hangindent, width=None):
     if width is None:
         width = termwidth() - 2
+    if width <= hangindent:
+        # adjust for weird terminal size
+        width = max(78, hangindent + 1)
     padding = '\n' + ' ' * hangindent
-    return padding.join(textwrap.wrap(line, width=width - hangindent))
+    # To avoid corrupting multi-byte characters in line, we must wrap
+    # a Unicode string instead of a bytestring.
+    u = line.decode(encoding.encoding)
+    w = padding.join(textwrap.wrap(u, width=width - hangindent))
+    return w.encode(encoding.encoding)
 
 def iterlines(iterator):
     for chunk in iterator:
--- a/mercurial/windows.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/mercurial/windows.py	Mon Sep 28 13:21:41 2009 -0700
@@ -17,7 +17,7 @@
     try:
         return osutil.posixfile(name, mode, buffering)
     except WindowsError, err:
-        raise IOError(err.errno, err.strerror)
+        raise IOError(err.errno, '%s: %s' % (name, err.strerror))
 posixfile.__doc__ = osutil.posixfile.__doc__
 
 class winstdout(object):
--- a/tests/hghave	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/hghave	Mon Sep 28 13:21:41 2009 -0700
@@ -78,7 +78,7 @@
 
 def has_icasefs():
     # Stolen from mercurial.util
-    fd, path = tempfile.mkstemp(prefix=tempprefix)
+    fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
     os.close(fd)
     try:
         s1 = os.stat(path)
@@ -123,6 +123,10 @@
 def has_git():
     return matchoutput('git --version 2>&1', r'^git version')
 
+def has_rst2html():
+    return matchoutput('rst2html --version', r'^rst2html \(Docutils') or \
+        matchoutput('rst2html.py --version', r'^rst2html.py \(Docutils')
+
 def has_svn():
     return matchoutput('svn --version 2>&1', r'^svn, version') and \
         matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
@@ -195,6 +199,7 @@
     "outer-repo": (has_outer_repo, "outer repo"),
     "p4": (has_p4, "Perforce server and client"),
     "pygments": (has_pygments, "Pygments source highlighting library"),
+    "rst2html": (has_rst2html, "Docutils rst2html tool"),
     "svn": (has_svn, "subversion client and admin tools"),
     "svn-bindings": (has_svn_bindings, "subversion python bindings"),
     "symlink": (has_symlink, "symbolic links"),
--- a/tests/printenv.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/printenv.py	Mon Sep 28 13:21:41 2009 -0700
@@ -46,12 +46,9 @@
 elif url.startswith("remote:http"):
     os.environ["HG_URL"] = "remote:http"
 
-if "HG_PENDING" in os.environ:
-    os.environ["HG_PENDING"] = os.environ["HG_PENDING"] and "true"
-
 out.write("%s hook: " % name)
 for v in env:
-    out.write("%s=%s " % (v, os.environ[v]))
+    out.write("%s=%s " % (v, os.environ[v].replace(os.environ["HGTMP"], '$HGTMP')))
 out.write("\n")
 out.close()
 
--- a/tests/run-tests.py	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/run-tests.py	Mon Sep 28 13:21:41 2009 -0700
@@ -167,16 +167,22 @@
     else:
         vlog = lambda *msg: None
 
+    if options.tmpdir:
+        options.tmpdir = os.path.expanduser(options.tmpdir)
+        try:
+            os.makedirs(options.tmpdir)
+        except OSError, err:
+            if err.errno != errno.EEXIST:
+                raise
+
     if options.jobs < 1:
-        print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
-        sys.exit(1)
+        parser.error('--jobs must be positive')
     if options.interactive and options.jobs > 1:
         print '(--interactive overrides --jobs)'
         options.jobs = 1
     if options.py3k_warnings:
         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
-            print 'ERROR: Py3k warnings switch can only be used on Python 2.6+'
-            sys.exit(1)
+            parser.error('--py3k-warnings can only be used on Python 2.6+')
 
     return (options, args)
 
--- a/tests/test-add.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-add.out	Mon Sep 28 13:21:41 2009 -0700
@@ -20,7 +20,7 @@
 warning: conflicts during merge.
 merging a failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 M a
 ? a.orig
 % should fail
--- a/tests/test-bheads.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-bheads.out	Mon Sep 28 13:21:41 2009 -0700
@@ -68,8 +68,8 @@
 3: Adding b branch head 1
 0
 -------
+6: Merging b branch head 2 and b branch head 3
 3: Adding b branch head 1
-6: Merging b branch head 2 and b branch head 3
 0
 -------
 no changes on branch b containing . are reachable from 7
--- a/tests/test-casefolding	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-casefolding	Mon Sep 28 13:21:41 2009 -0700
@@ -31,6 +31,9 @@
 hg rm a
 hg ci -Am removea
 echo A > A
+# on linux hfs keeps the old case stored, force it
+mv a aa
+mv aa A
 hg ci -Am addA
 # Used to fail under case insensitive fs
 hg up -C 0
--- a/tests/test-churn	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-churn	Mon Sep 28 13:21:41 2009 -0700
@@ -50,3 +50,13 @@
 echo % churn by hour
 hg churn -f '%H' -s
 
+cd ..
+
+# issue 833: ZeroDivisionError
+hg init issue-833
+cd issue-833
+touch foo
+hg ci -Am foo
+# this was failing with a ZeroDivisionError
+hg churn
+cd ..
--- a/tests/test-churn.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-churn.out	Mon Sep 28 13:21:41 2009 -0700
@@ -28,3 +28,5 @@
 09      2 *********************************
 12      4 ******************************************************************
 13      1 ****************
+adding foo
+test      0 
--- a/tests/test-commit-unresolved.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-commit-unresolved.out	Mon Sep 28 13:21:41 2009 -0700
@@ -6,7 +6,7 @@
 warning: conflicts during merge.
 merging A failed!
 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 
 % Correct the conflict without marking the file as resolved
 abort: unresolved merge conflicts (see hg resolve)
--- a/tests/test-conflict.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-conflict.out	Mon Sep 28 13:21:41 2009 -0700
@@ -4,7 +4,7 @@
 warning: conflicts during merge.
 merging a failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 e7fe8eb3e180+0d24b7662d3e+ tip
 <<<<<<< local
 something else
--- a/tests/test-convert-clonebranches.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-convert-clonebranches.out	Mon Sep 28 13:21:41 2009 -0700
@@ -18,12 +18,12 @@
 % incremental conversion
 2 c1
 pulling from branch0 into branch1
-2 changesets found
+4 changesets found
 1 c2
 pulling from branch0 into branch2
-2 changesets found
+4 changesets found
 0 c3
 pulling from branch2 into branch3
-3 changesets found
+5 changesets found
 pulling from branch1 into branch3
 1 changesets found
--- a/tests/test-convert-git	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-convert-git	Mon Sep 28 13:21:41 2009 -0700
@@ -42,7 +42,7 @@
 echo b >> a
 commit -a -m t4.1
 
-git checkout -b other HEAD^ >/dev/null 2>/dev/null
+git checkout -b other HEAD~ >/dev/null 2>/dev/null
 echo c > a
 echo a >> a
 commit -a -m t4.2
@@ -68,7 +68,7 @@
 echo >> foo
 commit -a -m 'change foo'
 
-git checkout -b Bar HEAD^ >/dev/null 2>/dev/null
+git checkout -b Bar HEAD~ >/dev/null 2>/dev/null
 echo quux >> quux
 git add quux
 commit -a -m 'add quux'
@@ -77,7 +77,7 @@
 git add bar
 commit -a -m 'add bar'
 
-git checkout -b Baz HEAD^ >/dev/null 2>/dev/null
+git checkout -b Baz HEAD~ >/dev/null 2>/dev/null
 echo baz > baz
 git add baz
 commit -a -m 'add baz'
@@ -89,7 +89,7 @@
 echo bar >> bar
 commit -a -m 'change bar'
 
-git checkout -b Foo HEAD^ >/dev/null 2>/dev/null
+git checkout -b Foo HEAD~ >/dev/null 2>/dev/null
 echo >> foo
 commit -a -m 'change foo'
 
--- a/tests/test-convert-svn-sink.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-convert-svn-sink.out	Mon Sep 28 13:21:41 2009 -0700
@@ -265,7 +265,7 @@
 warning: conflicts during merge.
 merging b failed!
 2 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 assuming destination b-hg
 initializing svn repo 'b-hg'
 initializing svn wc 'b-hg-wc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-tagsbranch-topology	Mon Sep 28 13:21:41 2009 -0700
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+"$TESTDIR/hghave" git || exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "convert=" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo '[convert]' >> $HGRCPATH
+echo 'hg.usebranchnames = True' >> $HGRCPATH
+echo 'hg.tagsbranch = tags-update' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+action()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git "$@" >/dev/null 2>/dev/null || echo "git command error"
+    count=`expr $count + 1`
+}
+
+glog()
+{
+    hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
+}
+
+convertrepo()
+{
+    hg convert --datesort git-repo hg-repo
+}
+
+# Build a GIT repo with at least 1 tag
+mkdir git-repo
+cd git-repo
+git init >/dev/null 2>&1
+echo a > a
+git add a
+action commit -m "rev1"
+action tag -m "tag1" tag1
+cd ..
+
+# Do a first conversion
+convertrepo
+
+# Simulate upstream  updates after first conversion
+cd git-repo
+echo b > a
+git add a
+action commit -m "rev2"
+action tag -m "tag2" tag2
+cd ..
+
+# Perform an incremental conversion
+convertrepo
+
+# Print the log
+cd hg-repo
+glog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-tagsbranch-topology.out	Mon Sep 28 13:21:41 2009 -0700
@@ -0,0 +1,19 @@
+initializing destination hg-repo repository
+scanning source...
+sorting...
+converting...
+0 rev1
+updating tags
+scanning source...
+sorting...
+converting...
+0 rev2
+updating tags
+o  3 "update tags" files: .hgtags
+|
+| o  2 "rev2" files: a
+| |
+o |  1 "update tags" files: .hgtags
+ /
+o  0 "rev1" files: a
+
--- a/tests/test-convert.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-convert.out	Mon Sep 28 13:21:41 2009 -0700
@@ -153,9 +153,10 @@
         recent revision on the branch indicated in the regex as the second
         parent of the changeset.
 
-    The hgext/convert/cvsps wrapper script allows the builtin changeset
+    An additional "debugcvsps" Mercurial command allows the builtin changeset
     merging code to be run without doing a conversion. Its parameters and
-    output are similar to that of cvsps 2.1.
+    output are similar to that of cvsps 2.1. Please see the command help for
+    more details.
 
     Subversion Source
     -----------------
--- a/tests/test-double-merge.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-double-merge.out	Mon Sep 28 13:21:41 2009 -0700
@@ -1,9 +1,4 @@
 created new head
-changeset:   0:310fd17130da
-user:        test
-date:        Mon Jan 12 13:46:40 1970 +0000
-summary:     add foo
-
 changeset:   1:7731dad1c2b9
 user:        test
 date:        Mon Jan 12 13:46:40 1970 +0000
--- a/tests/test-encoding	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-encoding	Mon Sep 28 13:21:41 2009 -0700
@@ -29,30 +29,31 @@
 HGENCODING=latin-1 hg ci -d "1000000 0" -m 'latin1 branch'
 rm .hg/branch
 
-echo % ascii
+echo "% hg log (ascii)"
 hg --encoding ascii log
-echo % latin-1
+echo "% hg log (latin-1)"
 hg --encoding latin-1 log
-echo % utf-8
+echo "% hg log (utf-8)"
 hg --encoding utf-8 log
-echo % ascii
+echo "% hg tags (ascii)"
 HGENCODING=ascii hg tags
-echo % latin-1
+echo "% hg tags (latin-1)"
 HGENCODING=latin-1 hg tags
-echo % utf-8
+echo "% hg tags (utf-8)"
 HGENCODING=utf-8 hg tags
-echo % ascii
+echo "% hg branches (ascii)"
 HGENCODING=ascii hg branches
-echo % latin-1
+echo "% hg branches (latin-1)"
 HGENCODING=latin-1 hg branches
-echo % utf-8
+echo "% hg branches (utf-8)"
 HGENCODING=utf-8 hg branches
 
 echo '[ui]' >> .hg/hgrc
 echo 'fallbackencoding = koi8-r' >> .hg/hgrc
-echo % utf-8
+echo "% hg log (utf-8)"
 HGENCODING=utf-8 hg log
 
+echo "% hg log (dolphin)"
 HGENCODING=dolphin hg log
 
 HGENCODING=ascii hg branch `cat latin-1-tag`
--- a/tests/test-encoding.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-encoding.out	Mon Sep 28 13:21:41 2009 -0700
@@ -14,7 +14,7 @@
 abort: decoding near ' encoded: é': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)!
 % these should work
 marked working directory as branch é
-% ascii
+% hg log (ascii)
 changeset:   5:db5520b4645f
 branch:      ?
 tag:         tip
@@ -48,7 +48,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     latin-1 e': ? = u'\xe9'
 
-% latin-1
+% hg log (latin-1)
 changeset:   5:db5520b4645f
 branch:      é
 tag:         tip
@@ -82,7 +82,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     latin-1 e': é = u'\xe9'
 
-% utf-8
+% hg log (utf-8)
 changeset:   5:db5520b4645f
 branch:      é
 tag:         tip
@@ -116,25 +116,25 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     latin-1 e': é = u'\xe9'
 
-% ascii
+% hg tags (ascii)
 tip                                5:db5520b4645f
 ?                                  3:770b9b11621d
-% latin-1
+% hg tags (latin-1)
 tip                                5:db5520b4645f
 é                                  3:770b9b11621d
-% utf-8
+% hg tags (utf-8)
 tip                                5:db5520b4645f
 é                                  3:770b9b11621d
-% ascii
+% hg branches (ascii)
 ?                              5:db5520b4645f
 default                        4:9cff3c980b58 (inactive)
-% latin-1
+% hg branches (latin-1)
 é                              5:db5520b4645f
 default                        4:9cff3c980b58 (inactive)
-% utf-8
+% hg branches (utf-8)
 é                              5:db5520b4645f
 default                        4:9cff3c980b58 (inactive)
-% utf-8
+% hg log (utf-8)
 changeset:   5:db5520b4645f
 branch:      é
 tag:         tip
@@ -168,6 +168,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     latin-1 e': И = u'\xe9'
 
+% hg log (dolphin)
 abort: unknown encoding: dolphin, please check your locale settings
 abort: decoding near 'é': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)!
 abort: branch name not in UTF-8!
--- a/tests/test-extension	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-extension	Mon Sep 28 13:21:41 2009 -0700
@@ -55,6 +55,29 @@
 hg foo
 echo 'barfoo = !' >> $HGRCPATH
 
+# check that extensions are loaded in phases
+cat > foo.py <<EOF
+import os
+name = os.path.basename(__file__).rsplit('.', 1)[0]
+print "1) %s imported" % name
+def uisetup(ui):
+    print "2) %s uisetup" % name
+def extsetup():
+    print "3) %s extsetup" % name
+def reposetup(ui, repo):
+    print "4) %s reposetup" % name
+EOF
+
+cp foo.py bar.py
+echo 'foo = foo.py' >> $HGRCPATH
+echo 'bar = bar.py' >> $HGRCPATH
+
+# command with no output, we just want to see the extensions loaded
+hg paths
+
+echo 'foo = !' >> $HGRCPATH
+echo 'bar = !' >> $HGRCPATH
+
 cd ..
 cat > empty.py <<EOF
 '''empty cmdtable
--- a/tests/test-extension.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-extension.out	Mon Sep 28 13:21:41 2009 -0700
@@ -16,6 +16,14 @@
 reposetup called for a
 ui == repo.ui
 Foo
+1) foo imported
+1) bar imported
+2) foo uisetup
+2) bar uisetup
+3) foo extsetup
+3) bar extsetup
+4) foo reposetup
+4) bar reposetup
 empty extension - empty cmdtable
 
 no commands defined
@@ -36,7 +44,7 @@
  debugextension   only debugcommands
 
 global options:
- -R --repository      repository root directory or symbolic path name
+ -R --repository      repository root directory or name of overlay bundle file
     --cwd             change working directory
  -y --noninteractive  do not prompt, assume 'yes' for any required answers
  -q --quiet           suppress output
@@ -66,7 +74,7 @@
  debugextension   only debugcommands
 
 global options:
- -R --repository      repository root directory or symbolic path name
+ -R --repository      repository root directory or name of overlay bundle file
     --cwd             change working directory
  -y --noninteractive  do not prompt, assume 'yes' for any required answers
  -q --quiet           suppress output
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-gendoc	Mon Sep 28 13:21:41 2009 -0700
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+"$TESTDIR/hghave" rst2html || exit 80
+RST2HTML=$(which rst2html 2> /dev/null || which rst2html.py)
+
+HGENCODING=UTF-8
+export HGENCODING
+
+for PO in C $TESTDIR/../i18n/*.po; do
+    LOCALE=$(basename $PO .po)
+    echo
+    echo "% extracting documentation from $LOCALE"
+    echo ".. -*- coding: utf-8 -*-" > gendoc-$LOCALE.txt
+    echo "" >> gendoc-$LOCALE.txt
+    LC_ALL=$LOCALE python $TESTDIR/../doc/gendoc.py >> gendoc-$LOCALE.txt || exit
+
+    # We run rst2html over the file without adding "--halt warning" to
+    # make it report all errors instead of stopping on the first one.
+    echo "checking for parse errors with rst2html"
+    $RST2HTML gendoc-$LOCALE.txt /dev/null
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-gendoc.out	Mon Sep 28 13:21:41 2009 -0700
@@ -0,0 +1,30 @@
+
+% extracting documentation from C
+checking for parse errors with rst2html
+
+% extracting documentation from da
+checking for parse errors with rst2html
+
+% extracting documentation from de
+checking for parse errors with rst2html
+
+% extracting documentation from el
+checking for parse errors with rst2html
+
+% extracting documentation from fr
+checking for parse errors with rst2html
+
+% extracting documentation from it
+checking for parse errors with rst2html
+
+% extracting documentation from ja
+checking for parse errors with rst2html
+
+% extracting documentation from pt_BR
+checking for parse errors with rst2html
+
+% extracting documentation from zh_CN
+checking for parse errors with rst2html
+
+% extracting documentation from zh_TW
+checking for parse errors with rst2html
--- a/tests/test-hgrc	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hgrc	Mon Sep 28 13:21:41 2009 -0700
@@ -16,3 +16,9 @@
 cat .hg/hgrc |sed -e "s:$p:...:"
 hg paths |sed -e "s:$p:...:"
 hg showconfig |sed -e "s:$p:...:"
+
+# issue1829: wrong indentation
+cd ..
+echo '[foo]' >> $HGRCPATH
+echo '  x = y' >> $HGRCPATH
+hg version 2>&1 | sed -e "s|$HGRCPATH|\$HGRCPATH|"
--- a/tests/test-hgrc.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hgrc.out	Mon Sep 28 13:21:41 2009 -0700
@@ -10,3 +10,4 @@
 defaults.tag=-d "0 0"
 paths.default=.../foo%bar
 ui.slash=True
+hg: config error at $HGRCPATH:8: '  x = y'
--- a/tests/test-hgweb-commands.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hgweb-commands.out	Mon Sep 28 13:21:41 2009 -0700
@@ -337,6 +337,7 @@
 # Parent  2ef0ac749a14e4f57a5a822464a0902c6f7f448f
 Added tag 1.0 for changeset 2ef0ac749a14
 
+diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 +++ b/.hgtags	Thu Jan 01 00:00:00 1970 +0000
 @@ -0,0 +1,1 @@
@@ -451,6 +452,7 @@
 200 Script output follows
 
 
+diff -r 000000000000 -r a4f92ed23982 foo
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 +++ b/foo	Thu Jan 01 00:00:00 1970 +0000
 @@ -0,0 +1,1 @@
--- a/tests/test-hgweb-diffs	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hgweb-diffs	Mon Sep 28 13:21:41 2009 -0700
@@ -18,6 +18,9 @@
 echo % revision
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
 
+echo % raw revision
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0'
+
 echo % diff removed file
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
 
@@ -29,6 +32,9 @@
 echo % revision
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/0'
 
+echo % revision
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT '/raw-rev/0'
+
 echo % diff removed file
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
 
--- a/tests/test-hgweb-diffs.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hgweb-diffs.out	Mon Sep 28 13:21:41 2009 -0700
@@ -95,6 +95,28 @@
 </body>
 </html>
 
+% raw revision
+200 Script output follows
+
+
+# HG changeset patch
+# User test
+# Date 0 0
+# Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
+
+a
+
+diff -r 000000000000 -r 0cd96de13884 a
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/a	Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,1 @@
++a
+diff -r 000000000000 -r 0cd96de13884 b
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/b	Thu Jan 01 00:00:00 1970 +0000
+@@ -0,0 +1,1 @@
++b
+
 % diff removed file
 200 Script output follows
 
@@ -279,6 +301,30 @@
 </body>
 </html>
 
+% revision
+200 Script output follows
+
+
+# HG changeset patch
+# User test
+# Date 0 0
+# Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
+
+a
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++a
+diff --git a/b b/b
+new file mode 100644
+--- /dev/null
++++ b/b
+@@ -0,0 +1,1 @@
++b
+
 % diff removed file
 200 Script output follows
 
--- a/tests/test-highlight	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-highlight	Mon Sep 28 13:21:41 2009 -0700
@@ -47,9 +47,6 @@
     print "The first %d primes: %s" % (n, list(islice(p, n)))
 EOF
 
-# check for UnicodeDecodeError with iso-8859-1 file contents
-python -c 'fp = open("isolatin.txt", "w"); fp.write("h\xFCbsch\n"); fp.close();'
-
 hg ci -Ama
 
 echo % hg serve
@@ -60,10 +57,6 @@
 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/primes.py') \
     | sed "s/class=\"k\"/class=\"kn\"/g" | sed "s/class=\"mf\"/class=\"mi\"/g"
 
-echo % hgweb filerevision, html
-("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/isolatin.txt') \
-    | sed "s/class=\"k\"/class=\"kn\"/g"
-
 echo % hgweb fileannotate, html
 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/annotate/tip/primes.py') \
     | sed "s/class=\"k\"/class=\"kn\"/g" | sed "s/class=\"mi\"/class=\"mf\"/g"
@@ -121,3 +114,28 @@
 
 echo % errors encountered
 cat errors.log
+
+cd ..
+hg init eucjp
+cd eucjp
+
+printf '\265\376\n' >> eucjp.txt  # Japanese kanji "Kyo"
+
+hg ci -Ama
+
+hgserveget () {
+    "$TESTDIR/killdaemons.py"
+    echo % HGENCODING="$1" hg serve
+    HGENCODING="$1" hg serve -p $HGPORT -d -n test --pid-file=hg.pid -E errors.log
+    cat hg.pid >> $DAEMON_PIDS
+
+    echo % hgweb filerevision, html
+    "$TESTDIR/get-with-headers.py" localhost:$HGPORT "/file/tip/$2" \
+        | grep '<div class="parity0 source">' | $TESTDIR/printrepr.py
+    echo % errors encountered
+    cat errors.log
+}
+
+hgserveget euc-jp eucjp.txt
+hgserveget utf-8 eucjp.txt
+hgserveget us-ascii eucjp.txt
--- a/tests/test-highlight.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-highlight.out	Mon Sep 28 13:21:41 2009 -0700
@@ -1,4 +1,3 @@
-adding isolatin.txt
 adding primes.py
 % hg serve
 % hgweb filerevision, html
@@ -12,7 +11,7 @@
 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
 
 <link rel="stylesheet" href="/highlightcss" type="text/css" />
-<title>test: 3e1445510fe7 primes.py</title>
+<title>test: 853dcd4de2a6 primes.py</title>
 </head>
 <body>
 
@@ -23,27 +22,27 @@
 <img src="/static/hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
-<li><a href="/shortlog/3e1445510fe7">log</a></li>
-<li><a href="/graph/3e1445510fe7">graph</a></li>
+<li><a href="/shortlog/853dcd4de2a6">log</a></li>
+<li><a href="/graph/853dcd4de2a6">graph</a></li>
 <li><a href="/tags">tags</a></li>
 <li><a href="/branches">branches</a></li>
 </ul>
 <ul>
-<li><a href="/rev/3e1445510fe7">changeset</a></li>
-<li><a href="/file/3e1445510fe7/">browse</a></li>
+<li><a href="/rev/853dcd4de2a6">changeset</a></li>
+<li><a href="/file/853dcd4de2a6/">browse</a></li>
 </ul>
 <ul>
 <li class="active">file</li>
-<li><a href="/diff/3e1445510fe7/primes.py">diff</a></li>
-<li><a href="/annotate/3e1445510fe7/primes.py">annotate</a></li>
-<li><a href="/log/3e1445510fe7/primes.py">file log</a></li>
-<li><a href="/raw-file/3e1445510fe7/primes.py">raw</a></li>
+<li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li>
+<li><a href="/annotate/853dcd4de2a6/primes.py">annotate</a></li>
+<li><a href="/log/853dcd4de2a6/primes.py">file log</a></li>
+<li><a href="/raw-file/853dcd4de2a6/primes.py">raw</a></li>
 </ul>
 </div>
 
 <div class="main">
 <h2><a href="/">test</a></h2>
-<h3>view primes.py @ 0:3e1445510fe7</h3>
+<h3>view primes.py @ 0:853dcd4de2a6</h3>
 
 <form class="search" action="/log">
 
@@ -119,93 +118,6 @@
 </body>
 </html>
 
-% hgweb filerevision, html
-200 Script output follows
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
-<head>
-<link rel="icon" href="/static/hgicon.png" type="image/png" />
-<meta name="robots" content="index, nofollow" />
-<link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
-
-<link rel="stylesheet" href="/highlightcss" type="text/css" />
-<title>test: 3e1445510fe7 isolatin.txt</title>
-</head>
-<body>
-
-<div class="container">
-<div class="menu">
-<div class="logo">
-<a href="http://mercurial.selenic.com/">
-<img src="/static/hglogo.png" alt="mercurial" /></a>
-</div>
-<ul>
-<li><a href="/shortlog/3e1445510fe7">log</a></li>
-<li><a href="/graph/3e1445510fe7">graph</a></li>
-<li><a href="/tags">tags</a></li>
-<li><a href="/branches">branches</a></li>
-</ul>
-<ul>
-<li><a href="/rev/3e1445510fe7">changeset</a></li>
-<li><a href="/file/3e1445510fe7/">browse</a></li>
-</ul>
-<ul>
-<li class="active">file</li>
-<li><a href="/diff/3e1445510fe7/isolatin.txt">diff</a></li>
-<li><a href="/annotate/3e1445510fe7/isolatin.txt">annotate</a></li>
-<li><a href="/log/3e1445510fe7/isolatin.txt">file log</a></li>
-<li><a href="/raw-file/3e1445510fe7/isolatin.txt">raw</a></li>
-</ul>
-</div>
-
-<div class="main">
-<h2><a href="/">test</a></h2>
-<h3>view isolatin.txt @ 0:3e1445510fe7</h3>
-
-<form class="search" action="/log">
-
-<p><input name="rev" id="search1" type="text" size="30" /></p>
-<div id="hint">find changesets by author, revision,
-files, or words in the commit message</div>
-</form>
-
-<div class="description">a</div>
-
-<table id="changesetEntry">
-<tr>
- <th class="author">author</th>
- <td class="author">&#116;&#101;&#115;&#116;</td>
-</tr>
-<tr>
- <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
-</tr>
-<tr>
- <th class="author">parents</th>
- <td class="author"></td>
-</tr>
-<tr>
- <th class="author">children</th>
- <td class="author"></td>
-</tr>
-
-</table>
-
-<div class="overflow">
-<div class="sourcefirst"> line source</div>
-
-<div class="parity0 source"><a href="#l1" id="l1">     1</a> h?bsch</div>
-<div class="sourcelast"></div>
-</div>
-</div>
-</div>
-
-
-
-</body>
-</html>
-
 % hgweb fileannotate, html
 200 Script output follows
 
@@ -228,28 +140,28 @@
 <img src="/static/hglogo.png" alt="mercurial" /></a>
 </div>
 <ul>
-<li><a href="/shortlog/3e1445510fe7">log</a></li>
-<li><a href="/graph/3e1445510fe7">graph</a></li>
+<li><a href="/shortlog/853dcd4de2a6">log</a></li>
+<li><a href="/graph/853dcd4de2a6">graph</a></li>
 <li><a href="/tags">tags</a></li>
 <li><a href="/branches">branches</a></li>
 </ul>
 
 <ul>
-<li><a href="/rev/3e1445510fe7">changeset</a></li>
-<li><a href="/file/3e1445510fe7/">browse</a></li>
+<li><a href="/rev/853dcd4de2a6">changeset</a></li>
+<li><a href="/file/853dcd4de2a6/">browse</a></li>
 </ul>
 <ul>
-<li><a href="/file/3e1445510fe7/primes.py">file</a></li>
-<li><a href="/diff/3e1445510fe7/primes.py">diff</a></li>
+<li><a href="/file/853dcd4de2a6/primes.py">file</a></li>
+<li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li>
 <li class="active">annotate</li>
-<li><a href="/log/3e1445510fe7/primes.py">file log</a></li>
-<li><a href="/raw-annotate/3e1445510fe7/primes.py">raw</a></li>
+<li><a href="/log/853dcd4de2a6/primes.py">file log</a></li>
+<li><a href="/raw-annotate/853dcd4de2a6/primes.py">raw</a></li>
 </ul>
 </div>
 
 <div class="main">
 <h2><a href="/">test</a></h2>
-<h3>annotate primes.py @ 0:3e1445510fe7</h3>
+<h3>annotate primes.py @ 0:853dcd4de2a6</h3>
 
 <form class="search" action="/log">
 
@@ -289,225 +201,225 @@
 
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#1"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#1"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l1" id="l1">     1</a> <span class="c">#!/usr/bin/env python</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#2"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#2"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l2" id="l2">     2</a> </td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#3"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#3"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l3" id="l3">     3</a> <span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#4"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#4"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l4" id="l4">     4</a> </td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#5"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#5"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l5" id="l5">     5</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#6"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#6"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l6" id="l6">     6</a> <span class="sd">    where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#7"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#7"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l7" id="l7">     7</a> <span class="sd">&quot;&quot;&quot;</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#8"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#8"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l8" id="l8">     8</a> </td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#9"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#9"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l9" id="l9">     9</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#10"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#10"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l10" id="l10">    10</a> </td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#11"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#11"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l11" id="l11">    11</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#12"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#12"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l12" id="l12">    12</a>     <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#13"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#13"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l13" id="l13">    13</a>     <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#14"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#14"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l14" id="l14">    14</a>         <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#15"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#15"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l15" id="l15">    15</a>         <span class="c"># It is important to yield *here* in order to stop the</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#16"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#16"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l16" id="l16">    16</a>         <span class="c"># infinite recursion.</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#17"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#17"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l17" id="l17">    17</a>         <span class="kn">yield</span> <span class="n">p</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#18"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#18"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l18" id="l18">    18</a>         <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mf">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#19"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#19"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l19" id="l19">    19</a>         <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#20"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#20"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l20" id="l20">    20</a>             <span class="kn">yield</span> <span class="n">n</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#21"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#21"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l21" id="l21">    21</a> </td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#22"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#22"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l22" id="l22">    22</a>     <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mf">2</span> <span class="o">==</span> <span class="mf">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#23"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#23"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l23" id="l23">    23</a>     <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mf">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mf">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#24"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#24"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l24" id="l24">    24</a> </td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#25"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#25"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l25" id="l25">    25</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#26"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#26"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l26" id="l26">    26</a>     <span class="kn">import</span> <span class="nn">sys</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#27"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#27"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l27" id="l27">    27</a>     <span class="kn">try</span><span class="p">:</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#28"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#28"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l28" id="l28">    28</a>         <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mf">1</span><span class="p">])</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#29"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#29"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l29" id="l29">    29</a>     <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#30"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#30"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l30" id="l30">    30</a>         <span class="n">n</span> <span class="o">=</span> <span class="mf">10</span></td>
 </tr>
 <tr class="parity0">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#31"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#31"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l31" id="l31">    31</a>     <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></td>
 </tr>
 <tr class="parity1">
 <td class="annotate">
-<a href="/annotate/3e1445510fe7/primes.py#32"
-title="3e1445510fe7: a">test@0</a>
+<a href="/annotate/853dcd4de2a6/primes.py#32"
+title="853dcd4de2a6: a">test@0</a>
 </td>
 <td class="source"><a href="#l32" id="l32">    32</a>     <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></td>
 </tr>
@@ -538,3 +450,16 @@
 /* pygments_style = fruity */
 
 % errors encountered
+adding eucjp.txt
+% HGENCODING=euc-jp hg serve
+% hgweb filerevision, html
+<div class="parity0 source"><a href="#l1" id="l1">     1</a> \xb5\xfe</div>
+% errors encountered
+% HGENCODING=utf-8 hg serve
+% hgweb filerevision, html
+<div class="parity0 source"><a href="#l1" id="l1">     1</a> \xef\xbf\xbd\xef\xbf\xbd</div>
+% errors encountered
+% HGENCODING=us-ascii hg serve
+% hgweb filerevision, html
+<div class="parity0 source"><a href="#l1" id="l1">     1</a> ??</div>
+% errors encountered
--- a/tests/test-hook.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-hook.out	Mon Sep 28 13:21:41 2009 -0700
@@ -1,18 +1,18 @@
 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000 
-pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=true 
+pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$HGTMP/test-hook/a 
 0:29b62aeb769f
 commit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 
 commit.b hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 
 updating working directory
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
-pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=true 
+pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a 
 1:b702efe96888
 commit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
 commit.b hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
-pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=true 
+pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a 
 2:1324a5531bac
 commit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
 commit.b hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b 
@@ -20,7 +20,7 @@
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 precommit hook: HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 
-pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=true 
+pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=$HGTMP/test-hook/a 
 3:4c52fb2e4022
 commit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 
 commit.b hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 
@@ -43,7 +43,7 @@
 (run 'hg update' to get a working copy)
 pretag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a 
 precommit hook: HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 
-pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=true 
+pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=$HGTMP/test-hook/a 
 4:8ea2ef7ad3e8
 commit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 
 commit.b hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 
@@ -58,10 +58,10 @@
 abort: pretag.forbid hook exited with status 1
 4:8ea2ef7ad3e8
 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 
-pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true 
+pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a 
 5:fad284daf8c0
 5:fad284daf8c0
-pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true 
+pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a 
 transaction abort!
 rollback completed
 abort: pretxncommit.forbid1 hook exited with status 1
@@ -81,7 +81,7 @@
 searching for changes
 abort: prechangegroup.forbid hook exited with status 1
 4:8ea2ef7ad3e8
-pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=true HG_SOURCE=pull HG_URL=file: 
+pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/b HG_SOURCE=pull HG_URL=file: 
 pulling from ../a
 searching for changes
 adding changesets
--- a/tests/test-keyword.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-keyword.out	Mon Sep 28 13:21:41 2009 -0700
@@ -359,6 +359,7 @@
 # Parent  bb948857c743469b22bbf51f7ec8112279ca5d83
 xa
 
+diff -r bb948857c743 -r cfa68229c116 x/a
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 +++ b/x/a	Thu Jan 01 00:00:03 1970 +0000
 @@ -0,0 +1,4 @@
@@ -371,6 +372,7 @@
 200 Script output follows
 
 
+diff -r ef63ca68695b -r bb948857c743 a
 --- a/a	Thu Jan 01 00:00:00 1970 +0000
 +++ b/a	Thu Jan 01 00:00:02 1970 +0000
 @@ -1,3 +1,4 @@
@@ -398,7 +400,7 @@
 warning: conflicts during merge.
 merging m failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 % keyword stays outside conflict zone
 $Id$
 <<<<<<< local
--- a/tests/test-log	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-log	Mon Sep 28 13:21:41 2009 -0700
@@ -107,6 +107,9 @@
 echo '% log -k r1'
 hg log -k r1
 
+echo '% log -d -1'
+hg log -d -1
+
 cd ..
 
 hg init usertest
--- a/tests/test-log.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-log.out	Mon Sep 28 13:21:41 2009 -0700
@@ -245,6 +245,7 @@
 date:        Thu Jan 01 00:00:01 1970 +0000
 summary:     r1
 
+% log -d -1
 adding a
 adding b
 changeset:   0:29a4c94f1924
--- a/tests/test-merge-default.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge-default.out	Mon Sep 28 13:21:41 2009 -0700
@@ -13,11 +13,6 @@
 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 % should succeed - 2 heads
-changeset:   1:ba677d0156c1
-user:        test
-date:        Thu Jan 01 00:00:00 1970 +0000
-summary:     b
-
 changeset:   3:903c264cdf57
 parent:      1:ba677d0156c1
 user:        test
--- a/tests/test-merge-internal-tools-pattern.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge-internal-tools-pattern.out	Mon Sep 28 13:21:41 2009 -0700
@@ -9,7 +9,7 @@
 created new head
 # merge using internal:fail tool
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 line 1
 line 2
 third line
--- a/tests/test-merge-tools.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge-tools.out	Mon Sep 28 13:21:41 2009 -0700
@@ -17,7 +17,7 @@
 warning: conflicts during merge.
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 <<<<<<< local
 revision 1
@@ -37,7 +37,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -69,7 +69,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -86,7 +86,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -103,7 +103,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -120,7 +120,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -185,7 +185,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -204,7 +204,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -223,7 +223,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -244,7 +244,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -260,7 +260,7 @@
 # hg update -C 1
 # hg merge -r 2 --config ui.merge=internal:fail
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -323,7 +323,7 @@
 # hg merge -r 2 --config ui.merge=internal:dump
 merging f
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -354,7 +354,7 @@
 merging f
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
@@ -518,7 +518,7 @@
 was merge successful (yn)? n
 merging f failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 # cat f
 revision 1
 space
--- a/tests/test-merge1.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge1.out	Mon Sep 28 13:21:41 2009 -0700
@@ -1,11 +1,6 @@
 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
 created new head
 %% no merges expected
-changeset:   0:98e00378acd0
-user:        test
-date:        Mon Jan 12 13:46:40 1970 +0000
-summary:     commit #0
-
 changeset:   1:4ee19afe4659
 user:        test
 date:        Mon Jan 12 13:46:40 1970 +0000
--- a/tests/test-merge7.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge7.out	Mon Sep 28 13:21:41 2009 -0700
@@ -11,7 +11,7 @@
 warning: conflicts during merge.
 merging test.txt failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 pulling from ../test-a
 searching for changes
 adding changesets
@@ -31,7 +31,7 @@
 warning: conflicts during merge.
 merging test.txt failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 one
 <<<<<<< local
 two-point-five
--- a/tests/test-merge9.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-merge9.out	Mon Sep 28 13:21:41 2009 -0700
@@ -7,7 +7,7 @@
 merging bar failed!
 merging foo and baz to baz
 1 files updated, 1 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 U bar
 R baz
 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -15,7 +15,7 @@
 merging bar failed!
 merging baz and foo to baz
 1 files updated, 1 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 % show unresolved
 U bar
 R baz
--- a/tests/test-mq	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-mq	Mon Sep 28 13:21:41 2009 -0700
@@ -152,6 +152,9 @@
 echo % qapplied
 hg qapplied
 
+echo % qtop
+hg qtop
+
 echo % prev
 hg qapp -1
 
--- a/tests/test-mq-guards	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-mq-guards	Mon Sep 28 13:21:41 2009 -0700
@@ -59,6 +59,8 @@
 
 echo % should skip c.patch
 hg qpush -a
+echo % should display b.patch
+hg qtop
 
 hg qguard -n c.patch
 echo % should push c.patch
@@ -82,6 +84,9 @@
 echo % should push b.patch
 hg qpush
 hg qpush -a
+# Used to be an issue with holes in the patch sequence
+# So, put one hole on the base and ask for topmost patch.
+hg qtop
 hg qpop -a
 
 hg qselect 1 2
--- a/tests/test-mq-guards.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-mq-guards.out	Mon Sep 28 13:21:41 2009 -0700
@@ -34,6 +34,8 @@
 applying b.patch
 skipping c.patch - guarded by '-a'
 now at: b.patch
+% should display b.patch
+b.patch
 % should push c.patch
 applying c.patch
 now at: c.patch
@@ -64,6 +66,7 @@
 now at: b.patch
 applying c.patch
 now at: c.patch
+c.patch
 popping c.patch
 popping b.patch
 patch queue now empty
--- a/tests/test-mq.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-mq.out	Mon Sep 28 13:21:41 2009 -0700
@@ -36,7 +36,9 @@
  qimport      import a patch
  qinit        init a new queue repository
  qnew         create a new patch
+ qnext        print the name of the next patch
  qpop         pop the current patch off the stack
+ qprev        print the name of the previous patch
  qpush        push the next patch onto the stack
  qrefresh     update the current patch
  qrename      rename a patch
@@ -44,6 +46,7 @@
  qsave        save current queue state
  qselect      set or print guarded patches to push
  qseries      print the entire series file
+ qtop         print the name of the current patch
  qunapplied   print the patches not yet applied
  strip        strip a revision and all its descendants from the repository
 
@@ -140,6 +143,8 @@
 % qapplied
 test.patch
 test2.patch
+% qtop
+test2.patch
 % prev
 test.patch
 % next
--- a/tests/test-push-warn	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-push-warn	Mon Sep 28 13:21:41 2009 -0700
@@ -123,4 +123,21 @@
 hg -q ci -d "1000000 0" -m 11
 hg push -r 10 -r 11 ../f; echo $?
 
+echo % checking prepush logic does not allow silently pushing multiple new heads
+cd ..
+hg init g
+echo init > g/init
+hg -R g ci -Am init
+echo a > g/a
+hg -R g ci -Am a
+hg clone g h
+hg -R g up 0
+echo b > g/b
+hg -R g ci -Am b
+hg -R h up 0
+echo c > h/c
+hg -R h ci -Am c
+hg -R h push g
+echo
+
 exit 0
--- a/tests/test-push-warn.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-push-warn.out	Mon Sep 28 13:21:41 2009 -0700
@@ -124,3 +124,20 @@
 adding file changes
 added 2 changesets with 2 changes to 1 files
 0
+% checking prepush logic does not allow silently pushing multiple new heads
+abort: repository g already exists!
+adding init
+adding a
+updating working directory
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+adding b
+created new head
+1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+adding c
+created new head
+pushing to g
+searching for changes
+abort: push creates new remote heads!
+(did you forget to merge? use push -f to force)
+
--- a/tests/test-resolve.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-resolve.out	Mon Sep 28 13:21:41 2009 -0700
@@ -4,5 +4,5 @@
 created new head
 % failing merge
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 % resolve -l, should be empty
--- a/tests/test-subrepo.out	Mon Aug 24 16:30:42 2009 -0700
+++ b/tests/test-subrepo.out	Mon Sep 28 13:21:41 2009 -0700
@@ -87,7 +87,7 @@
 warning: conflicts during merge.
 merging t failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 % should conflict