changeset 9778:6cb1808e5ae7

Merge with i18n
author Matt Mackall <mpm@selenic.com>
date Sat, 07 Nov 2009 14:13:15 -0600
parents ffda19f351fa (diff) b2dfe76459dc (current diff)
children 58a6f3f4d553 54d292da1df7 a0bf760c0dae
files
diffstat 120 files changed, 1876 insertions(+), 918 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/hg-relink	Wed Nov 04 22:14:26 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2007 Brendan Cully <brendan@kublai.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2, incorporated herein by reference.
-
-import os, sys
-
-class ConfigError(Exception): pass
-
-def usage():
-    print """relink <source> <destination>
-    Recreate hard links between source and destination repositories"""
-
-class Config:
-    def __init__(self, args):
-        if len(args) != 3:
-            raise ConfigError("wrong number of arguments")
-        self.src = os.path.abspath(args[1])
-        self.dst = os.path.abspath(args[2])
-        for d in (self.src, self.dst):
-            if not os.path.exists(os.path.join(d, '.hg')):
-                raise ConfigError("%s: not a mercurial repository" % d)
-
-def collect(src):
-    seplen = len(os.path.sep)
-    candidates = []
-    for dirpath, dirnames, filenames in os.walk(src):
-        relpath = dirpath[len(src) + seplen:]
-        for filename in filenames:
-            if not filename.endswith('.i'):
-                continue
-            st = os.stat(os.path.join(dirpath, filename))
-            candidates.append((os.path.join(relpath, filename), st))
-
-    return candidates
-
-def prune(candidates, dst):
-    def getdatafile(path):
-        if not path.endswith('.i'):
-            return None, None
-        df = path[:-1] + 'd'
-        try:
-            st = os.stat(df)
-        except OSError:
-            return None, None
-        return df, st
-
-    def linkfilter(dst, st):
-        try:
-            ts = os.stat(dst)
-        except OSError:
-            # Destination doesn't have this file?
-            return False
-        if st.st_ino == ts.st_ino:
-            return False
-        if st.st_dev != ts.st_dev:
-            # No point in continuing
-            raise Exception('Source and destination are on different devices')
-        if st.st_size != ts.st_size:
-            # TODO: compare revlog heads
-            return False
-        return st
-
-    targets = []
-    for fn, st in candidates:
-        tgt = os.path.join(dst, fn)
-        ts = linkfilter(tgt, st)
-        if not ts:
-            continue
-        targets.append((fn, ts.st_size))
-        df, ts = getdatafile(tgt)
-        if df:
-            targets.append((fn[:-1] + 'd', ts.st_size))
-
-    return targets
-
-def relink(src, dst, files):
-    def relinkfile(src, dst):
-        bak = dst + '.bak'
-        os.rename(dst, bak)
-        try:
-            os.link(src, dst)
-        except OSError:
-            os.rename(bak, dst)
-            raise
-        os.remove(bak)
-
-    CHUNKLEN = 65536
-    relinked = 0
-    savedbytes = 0
-
-    for f, sz in files:
-        source = os.path.join(src, f)
-        tgt = os.path.join(dst, f)
-        sfp = file(source)
-        dfp = file(tgt)
-        sin = sfp.read(CHUNKLEN)
-        while sin:
-            din = dfp.read(CHUNKLEN)
-            if sin != din:
-                break
-            sin = sfp.read(CHUNKLEN)
-        if sin:
-            continue
-        try:
-            relinkfile(source, tgt)
-            print 'Relinked %s' % f
-            relinked += 1
-            savedbytes += sz
-        except OSError, inst:
-            print '%s: %s' % (tgt, str(inst))
-
-    print 'Relinked %d files (%d bytes reclaimed)' % (relinked, savedbytes)
-
-try:
-    cfg = Config(sys.argv)
-except ConfigError, inst:
-    print str(inst)
-    usage()
-    sys.exit(1)
-
-src = os.path.join(cfg.src, '.hg')
-dst = os.path.join(cfg.dst, '.hg')
-candidates = collect(src)
-targets = prune(candidates, dst)
-relink(src, dst, targets)
--- a/contrib/shrink-revlog.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/contrib/shrink-revlog.py	Sat Nov 07 14:13:15 2009 -0600
@@ -87,12 +87,12 @@
             count += 1
     finally:
         write('\n')
-    
+
 def report(olddatafn, newdatafn):
     oldsize = float(os.stat(olddatafn).st_size)
     newsize = float(os.stat(newdatafn).st_size)
 
-    # argh: have to pass an int to %d, because a float >= 2^32 
+    # argh: have to pass an int to %d, because a float >= 2^32
     # blows up under Python 2.5 or earlier
     sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n'
                      % (int(oldsize), oldsize/1024/1024))
--- a/doc/Makefile	Wed Nov 04 22:14:26 2009 +0100
+++ b/doc/Makefile	Sat Nov 07 14:13:15 2009 -0600
@@ -1,6 +1,7 @@
 SOURCES=$(wildcard *.[0-9].txt)
 MAN=$(SOURCES:%.txt=%)
 HTML=$(SOURCES:%.txt=%.html)
+GENDOC=gendoc.py ../mercurial/commands.py ../mercurial/help.py ../help/*.txt
 PREFIX=/usr/local
 MANDIR=$(PREFIX)/share/man
 INSTALL=install -c -m 644
@@ -16,7 +17,7 @@
 hg.1.txt: hg.1.gendoc.txt
 	touch hg.1.txt
 
-hg.1.gendoc.txt: gendoc.py ../mercurial/commands.py ../mercurial/help.py
+hg.1.gendoc.txt: $(GENDOC)
 	${PYTHON} gendoc.py > $@.tmp
 	mv $@.tmp $@
 
--- a/doc/hg.1.txt	Wed Nov 04 22:14:26 2009 +0100
+++ b/doc/hg.1.txt	Sat Nov 07 14:13:15 2009 -0600
@@ -30,7 +30,7 @@
 
 files...
     indicates one or more filename or relative path filenames; see
-    "FILE NAME PATTERNS" for information on pattern matching
+    `File Name Patterns`_ for information on pattern matching
 
 path
     indicates a path on the local machine
@@ -72,7 +72,7 @@
 
 BUGS
 ----
-Probably lots, please post them to the mailing list (See Resources
+Probably lots, please post them to the mailing list (see Resources_
 below) when you find them.
 
 SEE ALSO
@@ -93,7 +93,7 @@
 
 COPYING
 -------
-Copyright \(C) 2005-2009 Matt Mackall.
+Copyright (C) 2005-2009 Matt Mackall.
 Free use of this software is granted under the terms of the GNU General
 Public License version 2.
 
--- a/doc/hgrc.5.txt	Wed Nov 04 22:14:26 2009 +0100
+++ b/doc/hgrc.5.txt	Sat Nov 07 14:13:15 2009 -0600
@@ -29,50 +29,9 @@
 The names of these files depend on the system on which Mercurial is
 installed. ``*.rc`` files from a single directory are read in
 alphabetical order, later ones overriding earlier ones. Where multiple
-paths are given below, settings from later paths override earlier
+paths are given below, settings from earlier paths override later
 ones.
 
-| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
-| (Unix) ``<install-root>/etc/mercurial/hgrc``
-
-    Per-installation configuration files, searched for in the
-    directory where Mercurial is installed. ``<install-root>`` is the
-    parent directory of the **hg** executable (or symlink) being run. For
-    example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
-    in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
-    to all Mercurial commands executed by any user in any directory.
-
-| (Unix) ``/etc/mercurial/hgrc.d/*.rc``
-| (Unix) ``/etc/mercurial/hgrc``
-
-    Per-system configuration files, for the system on which Mercurial
-    is running. Options in these files apply to all Mercurial commands
-    executed by any user in any directory. Options in these files
-    override per-installation options.
-
-| (Windows) ``<install-dir>\Mercurial.ini`` or else
-| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` or else
-| (Windows) ``C:\Mercurial\Mercurial.ini``
-
-    Per-installation/system configuration files, for the system on
-    which Mercurial is running. Options in these files apply to all
-    Mercurial commands executed by any user in any directory. Registry
-    keys contain PATH-like strings, every part of which must reference
-    a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
-    be read.
-
-| (Unix) ``$HOME/.hgrc``
-| (Windows) ``%HOME%\Mercurial.ini``
-| (Windows) ``%HOME%\.hgrc``
-| (Windows) ``%USERPROFILE%\Mercurial.ini``
-| (Windows) ``%USERPROFILE%\.hgrc``
-
-    Per-user configuration file(s), for the user running Mercurial. On
-    Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
-    files apply to all Mercurial commands executed by this user in any
-    directory. Options in these files override per-installation and
-    per-system options.
-
 | (Unix, Windows) ``<repo>/.hg/hgrc``
 
     Per-repository configuration options that only apply in a
@@ -81,7 +40,48 @@
     this file override options in all other configuration files. On
     Unix, most of this file will be ignored if it doesn't belong to a
     trusted user or to a trusted group. See the documentation for the
-    trusted section below for more details.
+    trusted_ section below for more details.
+
+| (Unix) ``$HOME/.hgrc``
+| (Windows) ``%USERPROFILE%\.hgrc``
+| (Windows) ``%USERPROFILE%\Mercurial.ini``
+| (Windows) ``%HOME%\.hgrc``
+| (Windows) ``%HOME%\Mercurial.ini``
+
+    Per-user configuration file(s), for the user running Mercurial. On
+    Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``. Options in these
+    files apply to all Mercurial commands executed by this user in any
+    directory. Options in these files override per-system and per-installation
+    options.
+
+| (Unix) ``/etc/mercurial/hgrc``
+| (Unix) ``/etc/mercurial/hgrc.d/*.rc``
+
+    Per-system configuration files, for the system on which Mercurial
+    is running. Options in these files apply to all Mercurial commands
+    executed by any user in any directory. Options in these files
+    override per-installation options.
+
+| (Unix) ``<install-root>/etc/mercurial/hgrc``
+| (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
+
+    Per-installation configuration files, searched for in the
+    directory where Mercurial is installed. ``<install-root>`` is the
+    parent directory of the **hg** executable (or symlink) being run. For
+    example, if installed in ``/shared/tools/bin/hg``, Mercurial will look
+    in ``/shared/tools/etc/mercurial/hgrc``. Options in these files apply
+    to all Mercurial commands executed by any user in any directory.
+
+| (Windows) ``C:\Mercurial\Mercurial.ini``
+| (Windows) ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial``
+| (Windows) ``<install-dir>\Mercurial.ini``
+
+    Per-installation/system configuration files, for the system on
+    which Mercurial is running. Options in these files apply to all
+    Mercurial commands executed by any user in any directory. Registry
+    keys contain PATH-like strings, every part of which must reference
+    a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
+    be read.
 
 SYNTAX
 ------
@@ -97,12 +97,9 @@
        eggs
 
 Each line contains one entry. If the lines that follow are indented,
-they are treated as continuations of that entry.
-
-Leading whitespace is removed from values. Empty lines are skipped.
-
-Lines beginning with ``#`` or ``;`` are ignored and may be used to provide
-comments.
+they are treated as continuations of that entry. Leading whitespace is
+removed from values. Empty lines are skipped. Lines beginning with
+``#`` or ``;`` are ignored and may be used to provide comments.
 
 A line of the form ``%include file`` will include ``file`` into the
 current configuration file. The inclusion is recursive, which means
@@ -139,9 +136,9 @@
 
     stable5 = latest -b stable
 
-NOTE: It is possible to create aliases with the same names as existing
-commands, which will then override the original definitions. This is
-almost always a bad idea!
+.. note:: It is possible to create aliases with the same names as
+   existing commands, which will then override the original
+   definitions. This is almost always a bad idea!
 
 
 ``auth``
@@ -232,9 +229,9 @@
 of an empty temporary file, where the filtered data must be written by
 the command.
 
-NOTE: the tempfile mechanism is recommended for Windows systems, where
-the standard shell I/O redirection operators often have strange
-effects and may corrupt the contents of your files.
+.. note:: The tempfile mechanism is recommended for Windows systems,
+   where the standard shell I/O redirection operators often have
+   strange effects and may corrupt the contents of your files.
 
 The most common usage is for LF <-> CRLF translation on Windows. For
 this, use the "smart" converters which check for binary files::
@@ -264,8 +261,8 @@
 Use the [defaults] section to define command defaults, i.e. the
 default options/arguments to pass to the specified commands.
 
-The following example makes 'hg log' run in verbose mode, and 'hg
-status' show only the modified files, by default::
+The following example makes ``hg log`` run in verbose mode, and ``hg
+status`` show only the modified files, by default::
 
   [defaults]
   log = -v
@@ -312,7 +309,7 @@
     email addresses. Cannot be set interactively.
 ``method``
     Optional. Method to use to send email messages. If value is "smtp"
-    (default), use SMTP (see section "[smtp]" for configuration).
+    (default), use SMTP (see the SMTP_ section for configuration).
     Otherwise, use as name of program to run that acts like sendmail
     (takes "-f" option for sender, list of recipients on command line,
     message on stdin). Normally, setting this to "sendmail" or
@@ -326,13 +323,13 @@
     conversion fails, the text in question is sent as is. Defaults to
     empty (explicit) list.
 
-Order of outgoing email character sets::
+    Order of outgoing email character sets:
 
-  us-ascii             always first, regardless of settings
-  email.charsets       in order given by user
-  ui.fallbackencoding  if not in email.charsets
-  $HGENCODING          if not in email.charsets
-  utf-8                always last, regardless of settings
+    1. ``us-ascii``: always first, regardless of settings
+    2. ``email.charsets``: in order given by user
+    3. ``ui.fallbackencoding``: if not in email.charsets
+    4. ``$HGENCODING``: if not in email.charsets
+    5. ``utf-8``: always last, regardless of settings
 
 Email example::
 
@@ -494,7 +491,7 @@
 
 Most hooks are run with environment variables set that give useful
 additional information. For each hook below, the environment
-variables it is passed are listed with names of the form "$HG_foo".
+variables it is passed are listed with names of the form ``$HG_foo``.
 
 ``changegroup``
   Run after a changegroup has been added via push, pull or unbundle.
@@ -575,16 +572,16 @@
   in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
   update failed (e.g. because conflicts not resolved), ``$HG_ERROR=1``.
 
-NOTE: it is generally better to use standard hooks rather than the
-generic pre- and post- command hooks as they are guaranteed to be
-called in the appropriate contexts for influencing transactions.
-Also, hooks like "commit" will be called in all contexts that
-generate a commit (e.g. tag) and not just the commit command.
+.. note:: It is generally better to use standard hooks rather than the
+   generic pre- and post- command hooks as they are guaranteed to be
+   called in the appropriate contexts for influencing transactions.
+   Also, hooks like "commit" will be called in all contexts that
+   generate a commit (e.g. tag) and not just the commit command.
 
-NOTE: Environment variables with empty values may not be passed to
-hooks on platforms such as Windows. As an example, ``$HG_PARENT2`` will
-have an empty value under Unix-like platforms for non-merge
-changesets, while it will not be available at all under Windows.
+.. note:: Environment variables with empty values may not be passed to
+   hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
+   will have an empty value under Unix-like platforms for non-merge
+   changesets, while it will not be available at all under Windows.
 
 The syntax for Python hooks is as follows::
 
@@ -649,7 +646,7 @@
 
 ``eol``
     When set to 'strict' patch content and patched files end of lines
-    are preserved. When set to 'lf' or 'crlf', both files end of lines
+    are preserved. When set to ``lf`` or ``crlf``, both files end of lines
     are ignored when patching and the result line endings are
     normalized to either LF (Unix) or CRLF (Windows).
     Default: strict.
@@ -738,17 +735,17 @@
     Whether to include the .hg_archival.txt file containing meta data
     (hashes for the repository base and for tip) in archives created
     by the hg archive command or downloaded via hgweb.
-    Default is true.
+    Default is True.
 ``askusername``
     Whether to prompt for a username when committing. If True, and
     neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
     be prompted to enter a username. If no username is entered, the
-    default USER@HOST is used instead.
+    default ``USER@HOST`` is used instead.
     Default is False.
 ``debug``
     Print debugging information. True or False. Default is False.
 ``editor``
-    The editor to use during a commit. Default is ``$EDITOR`` or "vi".
+    The editor to use during a commit. Default is ``$EDITOR`` or ``vi``.
 ``fallbackencoding``
     Encoding to try if it's not possible to decode the changelog using
     UTF-8. Default is ISO-8859-1.
@@ -777,15 +774,15 @@
         fail to merge
 
 For more information on configuring merge tools see the
-merge-tools section.
+merge-tools_ section.
 
 ``patch``
-    command to use to apply patches. Look for 'gpatch' or 'patch' in
+    command to use to apply patches. Look for ``gpatch`` or ``patch`` in
     PATH if unset.
 ``quiet``
     Reduce the amount of output printed. True or False. Default is False.
 ``remotecmd``
-    remote command to use for clone/push/pull operations. Default is 'hg'.
+    remote command to use for clone/push/pull operations. Default is ``hg``.
 ``report_untrusted``
     Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
     trusted user or group. True or False. Default is True.
@@ -796,7 +793,7 @@
     backslash character (``\``)).
     Default is False.
 ``ssh``
-    command to use for SSH connections. Default is 'ssh'.
+    command to use for SSH connections. Default is ``ssh``.
 ``strict``
     Require exact command names, instead of allowing unambiguous
     abbreviations. True or False. Default is False.
@@ -805,13 +802,18 @@
 ``timeout``
     The timeout used when a lock is held (in seconds), a negative value
     means no timeout. Default is 600.
+``traceback``
+    Mercurial always prints a traceback when an unknown exception
+    occurs. Setting this to True will make Mercurial print a traceback
+    on all exceptions, even those recognized by Mercurial (such as
+    IOError or MemoryError). Default is False.
 ``username``
     The committer of a changeset created when running "commit".
-    Typically a person's name and email address, e.g. "Fred Widget
-    <fred@example.com>". Default is ``$EMAIL`` or username@hostname. If
+    Typically a person's name and email address, e.g. ``Fred Widget
+    <fred@example.com>``. Default is ``$EMAIL`` or ``username@hostname``. If
     the username in hgrc is empty, it has to be specified manually or
     in a different hgrc file (e.g. ``$HOME/.hgrc``, if the admin set
-    "username =" in the system hgrc).
+    ``username =``  in the system hgrc).
 ``verbose``
     Increase the amount of output printed. True or False. Default is False.
 
@@ -830,19 +832,19 @@
 ``allowbz2``
     (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
     revisions.
-    Default is false.
+    Default is False.
 ``allowgz``
     (DEPRECATED) Whether to allow .tar.gz downloading of repository
     revisions.
-    Default is false.
+    Default is False.
 ``allowpull``
-    Whether to allow pulling from the repository. Default is true.
+    Whether to allow pulling from the repository. Default is True.
 ``allow_push``
     Whether to allow pushing to the repository. If empty or not set,
     push is not allowed. If the special value ``*``, any remote user can
     push, including unauthenticated users. Otherwise, the remote user
     must have been authenticated, and the authenticated user name must
-    be present in this list (separated by whitespace or ","). The
+    be present in this list (separated by whitespace or ``,``). The
     contents of the allow_push list are examined after the deny_push
     list.
 ``allow_read``
@@ -850,7 +852,7 @@
     the contents of deny_read, this list determines whether to grant
     repository access to the user. If this list is not empty, and the
     user is unauthenticated or not present in the list (separated by
-    whitespace or ","), then access is denied for the user. If the
+    whitespace or ``,``), then access is denied for the user. If the
     list is empty or not set, then access is permitted to all users by
     default. Setting allow_read to the special value ``*`` is equivalent
     to it not being set (i.e. access is permitted to all users). The
@@ -858,11 +860,11 @@
     list.
 ``allowzip``
     (DEPRECATED) Whether to allow .zip downloading of repository
-    revisions. Default is false. This feature creates temporary files.
+    revisions. Default is False. This feature creates temporary files.
 ``baseurl``
     Base URL to use when publishing URLs in other locations, so
     third-party tools like email notification hooks can construct
-    URLs. Example: "http://hgserver/repos/"
+    URLs. Example: ``http://hgserver/repos/``.
 ``contact``
     Name or email address of the person in charge of the repository.
     Defaults to ui.username or ``$EMAIL`` or "unknown" if unset or empty.
@@ -871,13 +873,13 @@
     push is not denied. If the special value ``*``, all remote users are
     denied push. Otherwise, unauthenticated users are all denied, and
     any authenticated user name present in this list (separated by
-    whitespace or ",") is also denied. The contents of the deny_push
+    whitespace or ``,``) is also denied. The contents of the deny_push
     list are examined before the allow_push list.
 ``deny_read``
     Whether to deny reading/viewing of the repository. If this list is
     not empty, unauthenticated users are all denied, and any
     authenticated user name present in this list (separated by
-    whitespace or ",") is also denied access to the repository. If set
+    whitespace or ``,``) is also denied access to the repository. If set
     to the special value ``*``, all remote users are denied access
     (rarely needed ;). If deny_read is empty or not set, the
     determination of repository access depends on the presence and
@@ -902,9 +904,9 @@
     Where to output the error log. Default is stderr.
 ``hidden``
     Whether to hide the repository in the hgwebdir index.
-    Default is false.
+    Default is False.
 ``ipv6``
-    Whether to use IPv6. Default is false.
+    Whether to use IPv6. Default is False.
 ``name``
     Repository name to use in the web interface. Default is current
     working directory.
@@ -918,12 +920,12 @@
     Prefix path to serve from. Default is '' (server root).
 ``push_ssl``
     Whether to require that inbound pushes be transported over SSL to
-    prevent password sniffing. Default is true.
+    prevent password sniffing. Default is True.
 ``staticurl``
     Base URL to use for static files. If unset, static files (e.g. the
     hgicon.png favicon) will be served by the CGI script itself. Use
     this setting to serve them directly with the HTTP server.
-    Example: "http://hgserver/static/"
+    Example: ``http://hgserver/static/``.
 ``stripes``
     How many lines a "zebra stripe" should span in multiline output.
     Default is 1; set to 0 to disable.
--- a/doc/rst2man.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/doc/rst2man.py	Sat Nov 07 14:13:15 2009 -0600
@@ -8,7 +8,7 @@
 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: 
+systems. The pages are grouped in numbered sections:
 
  1 executable programs and shell commands
  2 system calls
@@ -140,7 +140,7 @@
         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('_\n')       # line above
             text.append('T{\n')
             for i in range(len(row)):
                 cell = row[i]
@@ -184,8 +184,8 @@
                 "title" : "", "title_upper": "",
                 "subtitle" : "",
                 "manual_section" : "", "manual_group" : "",
-                "author" : [], 
-                "date" : "", 
+                "author" : [],
+                "date" : "",
                 "copyright" : "",
                 "version" : "",
                     }
@@ -216,7 +216,7 @@
                 'literal_block' : ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'),
 
                 'option_list_item' : ('.TP\n', ''),
-                
+
                 'reference' : (r'\%', r'\:'),
                 'emphasis': ('\\fI', '\\fP'),
                 'strong' : ('\\fB', '\\fP'),
@@ -263,7 +263,7 @@
                 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 
+                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 ')
@@ -564,10 +564,10 @@
 
     def depart_document(self, node):
         if self._docinfo['author']:
-            self.body.append('.SH AUTHOR\n%s\n' 
+            self.body.append('.SH AUTHOR\n%s\n'
                     % ', '.join(self._docinfo['author']))
         skip = ('author', 'copyright', 'date',
-                'manual_group', 'manual_section', 
+                'manual_group', 'manual_section',
                 'subtitle',
                 'title', 'title_upper', 'version')
         for name in self._docinfo_keys:
@@ -587,7 +587,7 @@
                     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.body.append('.SH COPYRIGHT\n%s\n'
                     % self._docinfo['copyright'])
         self.body.append( self.comment(
                         'Generated by docutils manpage writer.\n' ) )
@@ -896,7 +896,7 @@
     def visit_paragraph(self, node):
         # ``.PP`` : Start standard indented paragraph.
         # ``.LP`` : Start block paragraph, all except the first.
-        # ``.P [type]``  : Start paragraph type. 
+        # ``.P [type]``  : Start paragraph type.
         # NOTE dont use paragraph starts because they reset indentation.
         # ``.sp`` is only vertical space
         self.ensure_eol()
--- a/help/environment.txt	Wed Nov 04 22:14:26 2009 +0100
+++ b/help/environment.txt	Sat Nov 07 14:13:15 2009 -0600
@@ -50,7 +50,7 @@
     - hgrc files from the HGRCPATH
     - EMAIL
     - interactive prompt
-    - LOGNAME (with '@hostname' appended)
+    - LOGNAME (with ``@hostname`` appended)
 
     (deprecated, use .hgrc)
 
--- a/help/templates.txt	Wed Nov 04 22:14:26 2009 +0100
+++ b/help/templates.txt	Sat Nov 07 14:13:15 2009 -0600
@@ -75,11 +75,11 @@
               the timezone: "Mon Sep 04 15:13:13 2006 0700".
 :domain:      Any text. Finds the first string that looks like an
               email address, and extracts just the domain
-              component. Example: 'User <user@example.com>' becomes
-              'example.com'.
+              component. Example: ``User <user@example.com>`` becomes
+              ``example.com``.
 :email:       Any text. Extracts the first string that looks like
-              an email address. Example: 'User <user@example.com>'
-              becomes 'user@example.com'.
+              an email address. Example: ``User <user@example.com>``
+              becomes ``user@example.com``.
 :escape:      Any text. Replaces the special XML/XHTML characters
               "&", "<" and ">" with XML entities.
 :fill68:      Any text. Wraps the text to fit in 68 columns.
--- a/hgext/churn.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/hgext/churn.py	Sat Nov 07 14:13:15 2009 -0600
@@ -23,14 +23,15 @@
     return t
 
 def changedlines(ui, repo, ctx1, ctx2, fns):
-    lines = 0
+    added, removed = 0, 0
     fmatch = cmdutil.matchfiles(repo, fns)
     diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
     for l in diff.split('\n'):
-        if (l.startswith("+") and not l.startswith("+++ ") or
-            l.startswith("-") and not l.startswith("--- ")):
-            lines += 1
-    return lines
+        if l.startswith("+") and not l.startswith("+++ "):
+            added += 1
+        elif l.startswith("-") and not l.startswith("--- "):
+            removed += 1
+    return (added, removed)
 
 def countrate(ui, repo, amap, *pats, **opts):
     """Calculate stats"""
@@ -47,43 +48,43 @@
             tmpl.show(ctx)
             return ui.popbuffer()
 
-    count = pct = 0
+    state = {'count': 0, 'pct': 0}
     rate = {}
     df = False
     if opts.get('date'):
         df = util.matchdate(opts['date'])
 
     m = cmdutil.match(repo, pats, opts)
-    for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, m, opts):
-        if not st == 'add':
-            continue
-
+    def prep(ctx, fns):
         rev = ctx.rev()
         if df and not df(ctx.date()[0]): # doesn't match date format
-            continue
+            return
 
         key = getkey(ctx)
         key = amap.get(key, key) # alias remap
         if opts.get('changesets'):
-            rate[key] = rate.get(key, 0) + 1
+            rate[key] = (rate.get(key, (0,))[0] + 1, 0)
         else:
             parents = ctx.parents()
             if len(parents) > 1:
                 ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
-                continue
+                return
 
             ctx1 = parents[0]
             lines = changedlines(ui, repo, ctx1, ctx, fns)
-            rate[key] = rate.get(key, 0) + lines
+            rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
 
         if opts.get('progress'):
-            count += 1
-            newpct = int(100.0 * count / max(len(repo), 1))
-            if pct < newpct:
-                pct = newpct
-                ui.write("\r" + _("generating stats: %d%%") % pct)
+            state['count'] += 1
+            newpct = int(100.0 * state['count'] / max(len(repo), 1))
+            if state['pct'] < newpct:
+                state['pct'] = newpct
+                ui.write("\r" + _("generating stats: %d%%") % state['pct'])
                 sys.stdout.flush()
 
+    for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
+        continue
+
     if opts.get('progress'):
         ui.write("\r")
         sys.stdout.flush()
@@ -143,20 +144,35 @@
     if not rate:
         return
 
-    sortkey = ((not opts.get('sort')) and (lambda x: -x[1]) or None)
+    sortkey = ((not opts.get('sort')) and (lambda x: -sum(x[1])) or None)
     rate.sort(key=sortkey)
 
     # Be careful not to have a zero maxcount (issue833)
-    maxcount = float(max(v for k, v in rate)) or 1.0
+    maxcount = float(max(sum(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)
-    width = ttywidth - maxname - 2 - 6 - 2 - 2
+    width = ttywidth - maxname - 2 - 2 - 2
 
-    for date, count in rate:
-        print "%s %6d %s" % (pad(date, maxname), count,
-                             "*" * int(count * width / maxcount))
+    if opts.get('diffstat'):
+        width -= 15
+        def format(name, (added, removed)):
+            return "%s %15s %s%s\n" % (pad(name, maxname),
+                                       '+%d/-%d' % (added, removed),
+                                       '+' * charnum(added),
+                                       '-' * charnum(removed))
+    else:
+        width -= 6
+        def format(name, count):
+            return "%s %6d %s\n" % (pad(name, maxname), sum(count),
+                                    '*' * charnum(sum(count)))
+
+    def charnum(count):
+        return int(round(count*width/maxcount))
+
+    for name, count in rate:
+        ui.write(format(name, count))
 
 
 cmdtable = {
@@ -169,6 +185,7 @@
               _('strftime-compatible format for grouping by date')),
           ('c', 'changesets', False, _('count rate by number of changesets')),
           ('s', 'sort', False, _('sort by key (default: sort by count)')),
+          ('', 'diffstat', False, _('display added/removed lines separately')),
           ('', 'aliases', '', _('file with email aliases')),
           ('', 'progress', None, _('show progress'))],
          _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
--- a/hgext/color.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/hgext/color.py	Sat Nov 07 14:13:15 2009 -0600
@@ -235,7 +235,7 @@
                  'changed': ['white'],
                  'trailingwhitespace': ['bold', 'red_background']}
 
-def uisetup(ui):
+def extsetup(ui):
     '''Initialize the extension.'''
     _setupcmd(ui, 'diff', commands.table, colordiff, _diff_effects)
     _setupcmd(ui, 'incoming', commands.table, None, _diff_effects)
@@ -249,15 +249,17 @@
         _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
+        mq = None
 
     try:
         rec = extensions.find('record')
         _setupcmd(ui, 'record', rec.cmdtable, colordiff, _diff_effects)
     except KeyError:
-        # The record extension is not enabled
-        pass
+        rec = None
+
+    if mq and rec:
+        _setupcmd(ui, 'qrecord', rec.cmdtable, colordiff, _diff_effects)
+
 
 def _setupcmd(ui, cmd, table, func, effectsmap):
     '''patch in command to command table and load effect map'''
--- a/hgext/convert/darcs.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/hgext/convert/darcs.py	Sat Nov 07 14:13:15 2009 -0600
@@ -118,7 +118,7 @@
             output, status = self.run('revert', all=True, repodir=self.tmppath)
             self.checkexit(status, output)
 
-    def getchanges(self, rev):        
+    def getchanges(self, rev):
         copies = {}
         changes = []
         man = None
--- a/hgext/mq.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/hgext/mq.py	Sat Nov 07 14:13:15 2009 -0600
@@ -1129,8 +1129,12 @@
             self.ui.write(_("no patches applied\n"))
             return
         qp = self.qparents(repo, top)
+        if opts.get('inverse'):
+            node1, node2 = None, qp
+        else:
+            node1, node2 = qp, None
         self._diffopts = patch.diffopts(self.ui, opts)
-        self.printdiff(repo, qp, files=pats, opts=opts)
+        self.printdiff(repo, node1, node2, files=pats, opts=opts)
 
     def refresh(self, repo, pats=None, **opts):
         if len(self.applied) == 0:
@@ -1910,11 +1914,10 @@
                      summary=opts.get('summary'))
 
 def setupheaderopts(ui, opts):
-    def do(opt, val):
-        if not opts[opt] and opts['current' + opt]:
-            opts[opt] = val
-    do('user', ui.username())
-    do('date', "%d %d" % util.makedate())
+    if not opts.get('user') and opts.get('currentuser'):
+        opts['user'] = ui.username()
+    if not opts.get('date') and opts.get('currentdate'):
+        opts['date'] = "%d %d" % util.makedate()
 
 def new(ui, repo, patch, *args, **opts):
     """create a new patch
--- a/hgext/record.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/hgext/record.py	Sat Nov 07 14:13:15 2009 -0600
@@ -315,6 +315,7 @@
             return ret
     pos, total = 0, len(chunks) - 1
     while chunks:
+        pos = total - len(chunks) + 1
         chunk = chunks.pop()
         if isinstance(chunk, header):
             # new-file mark
@@ -350,7 +351,6 @@
                 applied[chunk.filename()].append(chunk)
             else:
                 fixoffset += chunk.removed - chunk.added
-        pos = pos + 1
     return reduce(operator.add, [h for h in applied.itervalues()
                                  if h[0].special() or len(h) > 1], [])
 
@@ -531,7 +531,7 @@
 }
 
 
-def extsetup():
+def uisetup(ui):
     try:
         mq = extensions.find('mq')
     except KeyError:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext/relink.py	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,149 @@
+# Mercurial extension to provide 'hg relink' command
+#
+# Copyright (C) 2007 Brendan Cully <brendan@kublai.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+"""recreates hardlinks between repository clones"""
+
+from mercurial import cmdutil, hg, util
+from mercurial.i18n import _
+import os, stat
+
+def relink(ui, repo, origin=None, **opts):
+    """recreate hardlinks between two repositories
+
+    When repositories are cloned locally, their data files will be hardlinked
+    so that they only use the space of a single repository.
+
+    Unfortunately, subsequent pulls into either repository will break hardlinks
+    for any files touched by the new changesets, even if both repositories end
+    up pulling the same changes.
+
+    Similarly, passing --rev to "hg clone" will fail to use
+    any hardlinks, falling back to a complete copy of the source repository.
+
+    This command lets you recreate those hardlinks and reclaim that wasted
+    space.
+
+    This repository will be relinked to share space with ORIGIN, which must be
+    on the same local disk. If ORIGIN is omitted, looks for "default-relink",
+    then "default", in [paths].
+
+    Do not attempt any read operations on this repository while the command is
+    running. (Both repositories will be locked against writes.)
+    """
+    src = hg.repository(
+        cmdutil.remoteui(repo, opts),
+        ui.expandpath(origin or 'default-relink', origin or 'default'))
+    if not src.local():
+        raise util.Abort('must specify local origin repository')
+    ui.status(_('relinking %s to %s\n') % (src.store.path, repo.store.path))
+    locallock = repo.lock()
+    try:
+        remotelock = src.lock()
+        try:
+            candidates = collect(src.store.path, ui)
+            targets = prune(candidates, repo.store.path, ui)
+            do_relink(src.store.path, repo.store.path, targets, ui)
+        finally:
+            remotelock.release()
+    finally:
+        locallock.release()
+
+def collect(src, ui):
+    seplen = len(os.path.sep)
+    candidates = []
+    for dirpath, dirnames, filenames in os.walk(src):
+        relpath = dirpath[len(src) + seplen:]
+        for filename in filenames:
+            if not filename[-2:] in ('.d', '.i'):
+                continue
+            st = os.stat(os.path.join(dirpath, filename))
+            if not stat.S_ISREG(st.st_mode):
+                continue
+            candidates.append((os.path.join(relpath, filename), st))
+
+    ui.status(_('collected %d candidate storage files\n') % len(candidates))
+    return candidates
+
+def prune(candidates, dst, ui):
+    def linkfilter(dst, st):
+        try:
+            ts = os.stat(dst)
+        except OSError:
+            # Destination doesn't have this file?
+            return False
+        if st.st_ino == ts.st_ino:
+            return False
+        if st.st_dev != ts.st_dev:
+            # No point in continuing
+            raise util.Abort(
+                _('source and destination are on different devices'))
+        if st.st_size != ts.st_size:
+            return False
+        return st
+
+    targets = []
+    for fn, st in candidates:
+        tgt = os.path.join(dst, fn)
+        ts = linkfilter(tgt, st)
+        if not ts:
+            ui.debug(_('not linkable: %s\n') % fn)
+            continue
+        targets.append((fn, ts.st_size))
+
+    ui.status(_('pruned down to %d probably relinkable files\n') % len(targets))
+    return targets
+
+def do_relink(src, dst, files, ui):
+    def relinkfile(src, dst):
+        bak = dst + '.bak'
+        os.rename(dst, bak)
+        try:
+            os.link(src, dst)
+        except OSError:
+            os.rename(bak, dst)
+            raise
+        os.remove(bak)
+
+    CHUNKLEN = 65536
+    relinked = 0
+    savedbytes = 0
+
+    pos = 0
+    total = len(files)
+    for f, sz in files:
+        pos += 1
+        source = os.path.join(src, f)
+        tgt = os.path.join(dst, f)
+        sfp = file(source)
+        dfp = file(tgt)
+        sin = sfp.read(CHUNKLEN)
+        while sin:
+            din = dfp.read(CHUNKLEN)
+            if sin != din:
+                break
+            sin = sfp.read(CHUNKLEN)
+        if sin:
+            ui.debug(_('not linkable: %s\n') % f)
+            continue
+        try:
+            relinkfile(source, tgt)
+            ui.progress(_('relink'), pos, f, _(' files'), total)
+            relinked += 1
+            savedbytes += sz
+        except OSError, inst:
+            ui.warn(_('%s: %s\n') % (tgt, str(inst)))
+
+    ui.status(_('relinked %d files (%d bytes reclaimed)\n') %
+              (relinked, savedbytes))
+
+cmdtable = {
+    'relink': (
+        relink,
+        [],
+        _('[ORIGIN]')
+    )
+}
--- a/mercurial/bundlerepo.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/bundlerepo.py	Sat Nov 07 14:13:15 2009 -0600
@@ -74,12 +74,12 @@
             return False
         return rev in self.basemap
     def bundlebase(self, rev): return self.basemap[rev]
-    def chunk(self, rev, df=None, cachelen=4096):
+    def _chunk(self, rev):
         # Warning: in case of bundle, the diff is against bundlebase,
         # not against rev - 1
         # XXX: could use some caching
         if not self.bundle(rev):
-            return revlog.revlog.chunk(self, rev, df)
+            return revlog.revlog._chunk(self, rev)
         self.bundlefile.seek(self.start(rev))
         return self.bundlefile.read(self.length(rev))
 
@@ -89,7 +89,7 @@
             # hot path for bundle
             revb = self.rev(self.bundlebase(rev2))
             if revb == rev1:
-                return self.chunk(rev2)
+                return self._chunk(rev2)
         elif not self.bundle(rev1) and not self.bundle(rev2):
             return revlog.revlog.revdiff(self, rev1, rev2)
 
@@ -116,7 +116,7 @@
             text = revlog.revlog.revision(self, iter_node)
 
         while chain:
-            delta = self.chunk(chain.pop())
+            delta = self._chunk(chain.pop())
             text = mdiff.patches(text, [delta])
 
         p1, p2 = self.parents(node)
--- a/mercurial/byterange.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/byterange.py	Sat Nov 07 14:13:15 2009 -0600
@@ -261,6 +261,8 @@
         host, port = splitport(host)
         if port is None:
             port = ftplib.FTP_PORT
+        else:
+            port = int(port)
 
         # username/password handling
         user, host = splituser(host)
--- a/mercurial/changelog.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/changelog.py	Sat Nov 07 14:13:15 2009 -0600
@@ -198,7 +198,7 @@
         return (manifest, user, (time, timezone), files, desc, extra)
 
     def add(self, manifest, files, desc, transaction, p1, p2,
-                  user, date=None, extra={}):
+                  user, date=None, extra=None):
         user = user.strip()
         # An empty username or a username with a "\n" will make the
         # revision text contain two "\n\n" sequences -> corrupt
--- a/mercurial/cmdutil.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/cmdutil.py	Sat Nov 07 14:13:15 2009 -0600
@@ -1022,24 +1022,26 @@
 
 def finddate(ui, repo, date):
     """Find the tipmost changeset that matches the given date spec"""
+
     df = util.matchdate(date)
-    get = util.cachefunc(lambda r: repo[r])
     m = matchall(repo)
     results = {}
-    for st, rev, fns in walkchangerevs(ui, repo, m, get, {'rev':None}):
-        if st == 'add':
-            d = get(rev).date()
-            if df(d[0]):
-                results[rev] = d
-        elif st == 'iter':
-            if rev in results:
-                ui.status(_("Found revision %s from %s\n") %
-                          (rev, util.datestr(results[rev])))
-                return str(rev)
+
+    def prep(ctx, fns):
+        d = ctx.date()
+        if df(d[0]):
+            results[ctx.rev()] = d
+
+    for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
+        rev = ctx.rev()
+        if rev in results:
+            ui.status(_("Found revision %s from %s\n") %
+                      (rev, util.datestr(results[rev])))
+            return str(rev)
 
     raise util.Abort(_("revision matching date not found"))
 
-def walkchangerevs(ui, repo, match, opts):
+def walkchangerevs(repo, match, opts, prepare):
     '''Iterate over files and the revs in which they changed.
 
     Callers most commonly need to iterate backwards over the history
@@ -1050,15 +1052,9 @@
     window, we first walk forwards to gather data, then in the desired
     order (usually backwards) to display it.
 
-    This function returns an iterator. The iterator yields 3-tuples.
-    They will be of one of the following forms:
-
-    "add", rev, fns: out-of-order traversal of the given filenames
-    fns, which changed during revision rev - use to gather data for
-    possible display
-
-    "iter", rev, None: in-order traversal of the revs earlier iterated
-    over with "add" - use to display data'''
+    This function returns an iterator yielding contexts. Before
+    yielding each context, the iterator will first call the prepare
+    function on each context in the window in forward order.'''
 
     def increasing_windows(start, end, windowsize=8, sizelimit=512):
         if start < end:
@@ -1093,6 +1089,7 @@
         # No files, no patterns.  Display all revs.
         wanted = set(revs)
     copies = []
+
     if not slowpath:
         # Only files, no patterns.  Check the history of each file.
         def filerevgen(filelog, node):
@@ -1129,8 +1126,6 @@
                     slowpath = True
                     break
                 else:
-                    ui.warn(_('%s:%s copy source revision cannot be found!\n')
-                            % (file_, short(node)))
                     continue
             for rev, copied in filerevgen(filelog, node):
                 if rev <= maxrev:
@@ -1215,6 +1210,7 @@
                 return rev in wanted
 
         for i, window in increasing_windows(0, len(revs)):
+            change = util.cachefunc(repo.changectx)
             nrevs = [rev for rev in revs[i:i+window] if want(rev)]
             for rev in sorted(nrevs):
                 fns = fncache.get(rev)
@@ -1225,9 +1221,9 @@
                             if match(f):
                                 yield f
                     fns = fns_generator()
-                yield 'add', ctx, fns
+                prepare(ctx, fns)
             for rev in nrevs:
-                yield 'iter', change(rev), None
+                yield change(rev)
     return iterate()
 
 def commit(ui, repo, commitfunc, pats, opts):
--- a/mercurial/commands.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/commands.py	Sat Nov 07 14:13:15 2009 -0600
@@ -8,8 +8,8 @@
 from node import hex, nullid, nullrev, short
 from lock import release
 from i18n import _, gettext
-import os, re, sys, subprocess, difflib, time, tempfile
-import hg, util, revlog, bundlerepo, extensions, copies, context, error
+import os, re, sys, difflib, time, tempfile
+import hg, util, revlog, bundlerepo, extensions, copies, error
 import patch, help, mdiff, url, encoding
 import archival, changegroup, cmdutil, sshserver, hbisect
 from hgweb import server
@@ -31,7 +31,6 @@
     """
 
     bad = []
-    exacts = {}
     names = []
     m = cmdutil.match(repo, pats, opts)
     oldbad = m.bad
@@ -371,14 +370,14 @@
 
     # update state
     node = repo.lookup(rev or '.')
-    if good:
-        state['good'].append(node)
-    elif bad:
-        state['bad'].append(node)
-    elif skip:
-        state['skip'].append(node)
-
-    hbisect.save_state(repo, state)
+    if good or bad or skip:
+        if good:
+            state['good'].append(node)
+        elif bad:
+            state['bad'].append(node)
+        elif skip:
+            state['skip'].append(node)
+        hbisect.save_state(repo, state)
 
     if not check_state(state):
         return
@@ -450,8 +449,7 @@
     """
 
     hexfunc = ui.debugflag and hex or short
-    activebranches = [encoding.tolocal(repo[n].branch())
-                            for n in repo.heads()]
+    activebranches = [repo[n].branch() for n in repo.heads()]
     def testactive(tag, node):
         realhead = tag in activebranches
         open = node in repo.branchheads(tag, closed=False)
@@ -462,8 +460,9 @@
 
     for isactive, node, tag in branches:
         if (not active) or isactive:
+            encodedtag = encoding.tolocal(tag)
             if ui.quiet:
-                ui.write("%s\n" % tag)
+                ui.write("%s\n" % encodedtag)
             else:
                 hn = repo.lookup(node)
                 if isactive:
@@ -474,8 +473,8 @@
                     notice = ' (closed)'
                 else:
                     notice = ' (inactive)'
-                rev = str(node).rjust(31 - encoding.colwidth(tag))
-                data = tag, rev, hexfunc(hn), notice
+                rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
+                data = encodedtag, rev, hexfunc(hn), notice
                 ui.write("%s %s:%s%s\n" % data)
 
 def bundle(ui, repo, fname, dest=None, **opts):
@@ -591,22 +590,36 @@
     The location of the source is added to the new repository's
     .hg/hgrc file, as the default to be used for future pulls.
 
-    If you use the -r/--rev option to clone up to a specific revision,
-    no subsequent revisions (including subsequent tags) will be
-    present in the cloned repository. This option implies --pull, even
-    on local repositories.
-
-    By default, clone will check out the head of the 'default' branch.
-    If the -U/--noupdate option is used, the new clone will contain
-    only a repository (.hg) and no working copy (the working copy
-    parent is the null revision).
-
     See 'hg help urls' for valid source format details.
 
     It is possible to specify an ssh:// URL as the destination, but no
     .hg/hgrc and working directory will be created on the remote side.
     Please see 'hg help urls' for important details about ssh:// URLs.
 
+    If the -U/--noupdate option is specified, the new clone will contain
+    only a repository (.hg) and no working copy (the working copy parent
+    will be the null changeset). Otherwise, clone will initially check
+    out (in order of precedence):
+
+      a) the changeset, tag or branch specified with -u/--updaterev
+      b) the changeset, tag or branch given with the first -r/--rev
+      c) the head of the default branch
+
+    Use 'hg clone -u . src dst' to checkout the source repository's
+    parent changeset (applicable for local source repositories only).
+
+    A set of changesets (tags, or branch names) to pull may be specified
+    by listing each changeset (tag, or branch name) with -r/--rev.
+    If -r/--rev is used, the cloned repository will contain only a subset
+    of the changesets of the source repository. Only the set of changesets
+    defined by all -r/--rev options (including their direct and indirect
+    parent changesets) will be pulled into the destination repository.
+    No subsequent changesets (including subsequent tags) will be present
+    in the destination.
+
+    Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
+    local source repositories.
+
     For efficiency, hardlinks are used for cloning whenever the source
     and destination are on the same filesystem (note this applies only
     to the repository data, not to the checked out files). Some
@@ -626,11 +639,14 @@
     this is not compatible with certain extensions that place their
     metadata under the .hg directory, such as mq.
     """
+    if opts.get('noupdate') and opts.get('updaterev'):
+        raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
+
     hg.clone(cmdutil.remoteui(ui, opts), source, dest,
              pull=opts.get('pull'),
              stream=opts.get('uncompressed'),
              rev=opts.get('rev'),
-             update=not opts.get('noupdate'))
+             update=opts.get('updaterev') or not opts.get('noupdate'))
 
 def commit(ui, repo, *pats, **opts):
     """commit the specified files or all outstanding changes
@@ -1013,15 +1029,12 @@
 
     # check username
     ui.status(_("Checking username...\n"))
-    user = os.environ.get("HGUSER")
-    if user is None:
-        user = ui.config("ui", "username")
-    if user is None:
-        user = os.environ.get("EMAIL")
-    if not user:
-        ui.warn(" ")
-        ui.username()
+    try:
+        user = ui.username()
+    except util.Abort, e:
+        ui.write(" %s\n" % e)
         ui.write(_(" (specify a username in your .hgrc file)\n"))
+        problems += 1
 
     if not problems:
         ui.status(_("No problems detected\n"))
@@ -1086,6 +1099,7 @@
     revs = opts.get('rev')
     change = opts.get('change')
     stat = opts.get('stat')
+    inv = opts.get('inverse')
 
     if revs and change:
         msg = _('cannot specify --rev and --change at the same time')
@@ -1096,6 +1110,9 @@
     else:
         node1, node2 = cmdutil.revpair(repo, revs)
 
+    if inv:
+        node1, node2 = node2, node1
+
     if stat:
         opts['unified'] = '0'
     diffopts = patch.diffopts(ui, opts)
@@ -1302,61 +1319,62 @@
     matchfn = cmdutil.match(repo, pats, opts)
     found = False
     follow = opts.get('follow')
-    for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts):
-        if st == 'add':
-            rev = ctx.rev()
-            pctx = ctx.parents()[0]
-            parent = pctx.rev()
-            matches.setdefault(rev, {})
-            matches.setdefault(parent, {})
-            files = revfiles.setdefault(rev, [])
-            for fn in fns:
-                flog = getfile(fn)
+
+    def prep(ctx, fns):
+        rev = ctx.rev()
+        pctx = ctx.parents()[0]
+        parent = pctx.rev()
+        matches.setdefault(rev, {})
+        matches.setdefault(parent, {})
+        files = revfiles.setdefault(rev, [])
+        for fn in fns:
+            flog = getfile(fn)
+            try:
+                fnode = ctx.filenode(fn)
+            except error.LookupError:
+                continue
+
+            copied = flog.renamed(fnode)
+            copy = follow and copied and copied[0]
+            if copy:
+                copies.setdefault(rev, {})[fn] = copy
+            if fn in skip:
+                if copy:
+                    skip[copy] = True
+                continue
+            files.append(fn)
+
+            if fn not in matches[rev]:
+                grepbody(fn, rev, flog.read(fnode))
+
+            pfn = copy or fn
+            if pfn not in matches[parent]:
                 try:
-                    fnode = ctx.filenode(fn)
+                    fnode = pctx.filenode(pfn)
+                    grepbody(pfn, parent, flog.read(fnode))
                 except error.LookupError:
-                    continue
-
-                copied = flog.renamed(fnode)
-                copy = follow and copied and copied[0]
+                    pass
+
+    for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
+        rev = ctx.rev()
+        parent = ctx.parents()[0].rev()
+        for fn in sorted(revfiles.get(rev, [])):
+            states = matches[rev][fn]
+            copy = copies.get(rev, {}).get(fn)
+            if fn in skip:
                 if copy:
-                    copies.setdefault(rev, {})[fn] = copy
-                if fn in skip:
+                    skip[copy] = True
+                continue
+            pstates = matches.get(parent, {}).get(copy or fn, [])
+            if pstates or states:
+                r = display(fn, ctx, pstates, states)
+                found = found or r
+                if r and not opts.get('all'):
+                    skip[fn] = True
                     if copy:
                         skip[copy] = True
-                    continue
-                files.append(fn)
-
-                if fn not in matches[rev]:
-                    grepbody(fn, rev, flog.read(fnode))
-
-                pfn = copy or fn
-                if pfn not in matches[parent]:
-                    try:
-                        fnode = pctx.filenode(pfn)
-                        grepbody(pfn, parent, flog.read(fnode))
-                    except error.LookupError:
-                        pass
-        elif st == 'iter':
-            rev = ctx.rev()
-            parent = ctx.parents()[0].rev()
-            for fn in sorted(revfiles.get(rev, [])):
-                states = matches[rev][fn]
-                copy = copies.get(rev, {}).get(fn)
-                if fn in skip:
-                    if copy:
-                        skip[copy] = True
-                    continue
-                pstates = matches.get(parent, {}).get(copy or fn, [])
-                if pstates or states:
-                    r = display(fn, ctx, pstates, states)
-                    found = found or r
-                    if r and not opts.get('all'):
-                        skip[fn] = True
-                        if copy:
-                            skip[copy] = True
-            del matches[rev]
-            del revfiles[rev]
+        del matches[rev]
+        del revfiles[rev]
 
 def heads(ui, repo, *branchrevs, **opts):
     """show current repository heads or show branch heads
@@ -1400,21 +1418,22 @@
         heads = []
         visitedset = set()
         for branchrev in branchrevs:
-            branch = repo[branchrev].branch()
+            branch = repo[encoding.fromlocal(branchrev)].branch()
+            encodedbranch = encoding.tolocal(branch)
             if branch in visitedset:
                 continue
             visitedset.add(branch)
             bheads = repo.branchheads(branch, start, closed=closed)
             if not bheads:
                 if not opts.get('rev'):
-                    ui.warn(_("no open branch heads on branch %s\n") % branch)
+                    ui.warn(_("no open branch heads on branch %s\n") % encodedbranch)
                 elif branch != branchrev:
                     ui.warn(_("no changes on branch %s containing %s are "
                               "reachable from %s\n")
-                            % (branch, branchrev, opts.get('rev')))
+                            % (encodedbranch, branchrev, opts.get('rev')))
                 else:
                     ui.warn(_("no changes on branch %s are reachable from %s\n")
-                            % (branch, opts.get('rev')))
+                            % (encodedbranch, opts.get('rev')))
             if hideinactive:
                 bheads = [bhead for bhead in bheads if bhead in _heads]
             heads.extend(bheads)
@@ -2034,54 +2053,44 @@
     if opts["date"]:
         df = util.matchdate(opts["date"])
 
-    only_branches = opts.get('only_branch')
-
     displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn)
-    for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts):
+    def prep(ctx, fns):
         rev = ctx.rev()
-        if st == 'add':
-            parents = [p for p in repo.changelog.parentrevs(rev)
-                       if p != nullrev]
-            if opts.get('no_merges') and len(parents) == 2:
-                continue
-            if opts.get('only_merges') and len(parents) != 2:
-                continue
-
-            if only_branches and ctx.branch() not in only_branches:
-                continue
-
-            if df and not df(ctx.date()[0]):
-                continue
-
-            if opts.get('keyword'):
-                miss = 0
-                for k in [kw.lower() for kw in opts['keyword']]:
-                    if not (k in ctx.user().lower() or
-                            k in ctx.description().lower() or
-                            k in " ".join(ctx.files()).lower()):
-                        miss = 1
-                        break
-                if miss:
-                    continue
-
-            if opts['user']:
-                if not [k for k in opts['user'] if k in ctx.user()]:
-                    continue
-
-            copies = []
-            if opts.get('copies') and rev:
-                for fn in ctx.files():
-                    rename = getrenamed(fn, rev)
-                    if rename:
-                        copies.append((fn, rename[0]))
-
-            displayer.show(ctx, copies=copies)
-
-        elif st == 'iter':
-            if count == limit: break
-
-            if displayer.flush(rev):
-                count += 1
+        parents = [p for p in repo.changelog.parentrevs(rev)
+                   if p != nullrev]
+        if opts.get('no_merges') and len(parents) == 2:
+            return
+        if opts.get('only_merges') and len(parents) != 2:
+            return
+        if opts.get('only_branch') and ctx.branch() not in opts['only_branch']:
+            return
+        if df and not df(ctx.date()[0]):
+            return
+        if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
+            return
+        if opts.get('keyword'):
+            for k in [kw.lower() for kw in opts['keyword']]:
+                if (k in ctx.user().lower() or
+                    k in ctx.description().lower() or
+                    k in " ".join(ctx.files()).lower()):
+                    break
+            else:
+                return
+
+        copies = []
+        if opts.get('copies') and rev:
+            for fn in ctx.files():
+                rename = getrenamed(fn, rev)
+                if rename:
+                    copies.append((fn, rename[0]))
+
+        displayer.show(ctx, copies=copies)
+
+    for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
+        if count == limit:
+            break
+        if displayer.flush(ctx.rev()):
+            count += 1
 
 def manifest(ui, repo, node=None, rev=None):
     """output the current or given revision of the project manifest
@@ -2446,13 +2455,15 @@
     """retry file merges from a merge or update
 
     This command can cleanly retry unresolved file merges using file
-    revisions preserved from the last update or merge. To attempt to
-    resolve all unresolved files, use the -a/--all switch.
+    revisions preserved from the last update or merge.
 
     If a conflict is resolved manually, please note that the changes
     will be overwritten if the merge is retried with resolve. The
     -m/--mark switch should be used to mark the file as resolved.
 
+    You can specify a set of files to operate on, or use the -a/-all
+    switch to select all unresolved files.
+
     This command also allows listing resolved files and manually
     indicating whether or not files are resolved. All files must be
     marked as resolved before a commit is permitted.
@@ -3129,30 +3140,32 @@
     """update working directory
 
     Update the repository's working directory to the specified
-    revision, or the tip of the current branch if none is specified.
-    Use null as the revision to remove the working copy (like 'hg
+    changeset.
+
+    If no changeset is specified, attempt to update to the head of the
+    current branch. If this head is a descendant of the working
+    directory's parent, update to it, otherwise abort.
+
+    The following rules apply when the working directory contains
+    uncommitted changes:
+
+    1. If neither -c/--check nor -C/--clean is specified, uncommitted
+       changes are merged into the requested changeset, and the merged result
+       is left uncommitted. Updating and merging will occur only if the
+       requested changeset is an ancestor or descendant of the parent
+       changeset. Otherwise, the update is aborted and the uncommitted changes
+       are preserved.
+
+    2. With the -c/--check option, the update is aborted and the
+       uncommitted changes are preserved.
+
+    3. With the -C/--clean option, uncommitted changes are discarded and
+       the working directory is updated to the requested changeset.
+
+    Use null as the changeset to remove the working directory (like 'hg
     clone -U').
 
-    When the working directory contains no uncommitted changes, it
-    will be replaced by the state of the requested revision from the
-    repository. When the requested revision is on a different branch,
-    the working directory will additionally be switched to that
-    branch.
-
-    When there are uncommitted changes, use option -C/--clean to
-    discard them, forcibly replacing the state of the working
-    directory with the requested revision. Alternately, use -c/--check
-    to abort.
-
-    When there are uncommitted changes and option -C/--clean is not
-    used, and the parent revision and requested revision are on the
-    same branch, and one of them is an ancestor of the other, then the
-    new working directory will contain the requested revision merged
-    with the uncommitted changes. Otherwise, the update will fail with
-    a suggestion to use 'merge' or 'update -C' instead.
-
-    If you want to update just one file to an older revision, use
-    revert.
+    If you want to update just one file to an older changeset, use 'hg revert'.
 
     See 'hg help dates' for a list of formats valid for -d/--date.
     """
@@ -3220,7 +3233,7 @@
     ('', 'encoding', encoding.encoding, _('set the charset encoding')),
     ('', 'encodingmode', encoding.encodingmode,
      _('set the charset encoding mode')),
-    ('', 'traceback', None, _('print traceback on exception')),
+    ('', 'traceback', None, _('always print a traceback on exception')),
     ('', 'time', None, _('time how long the command takes')),
     ('', 'profile', None, _('print command execution profile')),
     ('', 'version', None, _('output version information and exit')),
@@ -3270,6 +3283,7 @@
 
 diffopts2 = [
     ('p', 'show-function', None, _('show which function each change is in')),
+    ('', 'inverse', None, _('produce a diff that undoes the changes')),
     ('w', 'ignore-all-space', None,
      _('ignore white space when comparing lines')),
     ('b', 'ignore-space-change', None,
@@ -3364,6 +3378,8 @@
         (clone,
          [('U', 'noupdate', None,
           _('the clone will only contain a repository (no working copy)')),
+          ('u', 'updaterev', '',
+           _('revision, tag or branch to check out')),
           ('r', 'rev', [],
            _('a changeset you would like to have after cloning')),
           ('', 'pull', None, _('use pull protocol to copy metadata')),
@@ -3587,7 +3603,7 @@
          _('[OPTION]... SOURCE... DEST')),
     "resolve":
         (resolve,
-         [('a', 'all', None, _('remerge all unresolved files')),
+         [('a', 'all', None, _('select all unresolved files')),
           ('l', 'list', None, _('list state of files needing merge')),
           ('m', 'mark', None, _('mark files as resolved')),
           ('u', 'unmark', None, _('unmark files as resolved')),
@@ -3672,11 +3688,11 @@
          _('[-u] FILE...')),
     "^update|up|checkout|co":
         (update,
-         [('C', 'clean', None, _('overwrite locally modified files (no backup)')),
+         [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
           ('c', 'check', None, _('check for uncommitted changes')),
           ('d', 'date', '', _('tipmost revision matching date')),
           ('r', 'rev', '', _('revision'))],
-         _('[-C] [-d DATE] [[-r] REV]')),
+         _('[-c] [-C] [-d DATE] [[-r] REV]')),
     "verify": (verify, []),
     "version": (version_, []),
 }
--- a/mercurial/context.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/context.py	Sat Nov 07 14:13:15 2009 -0600
@@ -451,6 +451,15 @@
         find the common ancestor file context, if any, of self, and fc2
         """
 
+        actx = self.changectx().ancestor(fc2.changectx())
+
+        # the trivial case: changesets are unrelated, files must be too
+        if not actx:
+            return None
+
+        # the easy case: no (relevant) renames
+        if fc2.path() == self.path() and self.path() in actx:
+            return actx[self.path()]
         acache = {}
 
         # prime the ancestor cache for the working directory
--- a/mercurial/dirstate.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/dirstate.py	Sat Nov 07 14:13:15 2009 -0600
@@ -9,7 +9,7 @@
 from i18n import _
 import util, ignore, osutil, parsers
 import struct, os, stat, errno
-import cStringIO, sys
+import cStringIO
 
 _unknown = ('?', 0, 0, 0)
 _format = ">cllll"
--- a/mercurial/dispatch.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/dispatch.py	Sat Nov 07 14:13:15 2009 -0600
@@ -194,8 +194,6 @@
 
         args = shlex.split(self.definition)
         cmd = args.pop(0)
-        opts = []
-        help = ''
 
         try:
             self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
@@ -358,17 +356,7 @@
     extensions.loadall(lui)
     exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
 
-    # (uisetup is handled in extensions.loadall)
-
-    for name, module in exts:
-        extsetup = getattr(module, 'extsetup', None)
-        if extsetup:
-            try:
-                extsetup(ui)
-            except TypeError:
-                if extsetup.func_code.co_argcount != 0:
-                    raise
-                extsetup() # old extsetup with no ui argument
+    # (uisetup and extsetup are handled in extensions.loadall)
 
     for name, module in exts:
         cmdtable = getattr(module, 'cmdtable', {})
--- a/mercurial/extensions.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/extensions.py	Sat Nov 07 14:13:15 2009 -0600
@@ -93,6 +93,16 @@
         if uisetup:
             uisetup(ui)
 
+    for name in _order[newindex:]:
+        extsetup = getattr(_extensions[name], 'extsetup', None)
+        if extsetup:
+            try:
+                extsetup(ui)
+            except TypeError:
+                if extsetup.func_code.co_argcount != 0:
+                    raise
+                extsetup() # old extsetup with no ui argument
+
 def wrapcommand(table, command, wrapper):
     aliases, entry = cmdutil.findcmd(command, table)
     for alias, e in table.iteritems():
@@ -171,7 +181,6 @@
     '''return a dict of {name: desc} of extensions, and the max name length'''
     exts = {}
     maxlength = 0
-    exthelps = []
     for ename, ext in extensions():
         doc = (gettext(ext.__doc__) or _('(no help text available)'))
         ename = ename.split('.')[-1]
--- a/mercurial/filemerge.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/filemerge.py	Sat Nov 07 14:13:15 2009 -0600
@@ -186,6 +186,7 @@
     env = dict(HG_FILE=fd,
                HG_MY_NODE=short(mynode),
                HG_OTHER_NODE=str(fco.changectx()),
+               HG_BASE_NODE=str(fca.changectx()),
                HG_MY_ISLINK='l' in fcd.flags(),
                HG_OTHER_ISLINK='l' in fco.flags(),
                HG_BASE_ISLINK='l' in fca.flags())
--- a/mercurial/graphmod.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/graphmod.py	Sat Nov 07 14:13:15 2009 -0600
@@ -48,7 +48,7 @@
         parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
         rev = fctx.rev()
         if rev <= start:
-            yield (rev, CHANGESET, fctx, sorted(parents))
+            yield (rev, CHANGESET, fctx.changectx(), sorted(parents))
         if rev <= stop:
             break
         filerev -= 1
--- a/mercurial/help.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/help.py	Sat Nov 07 14:13:15 2009 -0600
@@ -7,7 +7,7 @@
 
 from i18n import gettext, _
 import sys, os
-import extensions, util
+import extensions
 
 
 def moduledoc(file):
--- a/mercurial/hg.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hg.py	Sat Nov 07 14:13:15 2009 -0600
@@ -309,6 +309,8 @@
             if update:
                 if update is not True:
                     checkout = update
+                    if src_repo.local():
+                        checkout = src_repo.lookup(update)
                 for test in (checkout, 'default', 'tip'):
                     if test is None:
                         continue
--- a/mercurial/hgweb/common.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hgweb/common.py	Sat Nov 07 14:13:15 2009 -0600
@@ -31,8 +31,8 @@
     responses = BaseHTTPRequestHandler.responses
     return responses.get(code, ('Error', 'Unknown error'))[0]
 
-def statusmessage(code):
-    return '%d %s' % (code, _statusmessage(code))
+def statusmessage(code, message=None):
+    return '%d %s' % (code, message or _statusmessage(code))
 
 def get_mtime(repo_path):
     store_path = os.path.join(repo_path, ".hg")
--- a/mercurial/hgweb/hgweb_mod.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hgweb/hgweb_mod.py	Sat Nov 07 14:13:15 2009 -0600
@@ -151,6 +151,10 @@
                 if args:
                     req.form['file'] = args
 
+            ua = req.env.get('HTTP_USER_AGENT', '')
+            if cmd == 'rev' and 'mercurial' in ua:
+                req.form['style'] = ['raw']
+
             if cmd == 'archive':
                 fn = req.form['node'][0]
                 for type_, spec in self.archive_specs.iteritems():
--- a/mercurial/hgweb/hgwebdir_mod.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hgweb/hgwebdir_mod.py	Sat Nov 07 14:13:15 2009 -0600
@@ -20,7 +20,7 @@
     return [(util.pconvert(name).strip('/'), path) for name, path in items]
 
 def findrepos(paths):
-    repos = {}
+    repos = []
     for prefix, root in cleannames(paths):
         roothead, roottail = os.path.split(root)
         # "foo = /bar/*" makes every subrepo of /bar/ to be
@@ -30,7 +30,7 @@
         try:
             recurse = {'*': False, '**': True}[roottail]
         except KeyError:
-            repos[prefix] = root
+            repos.append((prefix, root))
             continue
         roothead = os.path.normpath(roothead)
         for path in util.walkrepos(roothead, followsym=True, recurse=recurse):
@@ -38,8 +38,8 @@
             name = util.pconvert(path[len(roothead):]).strip('/')
             if prefix:
                 name = prefix + '/' + name
-            repos[name] = path
-    return repos.items()
+            repos.append((name, path))
+    return repos
 
 class hgwebdir(object):
     refreshinterval = 20
@@ -89,7 +89,6 @@
                     name = name[len(prefix):]
                 self.repos.append((name.lstrip('/'), repo))
 
-        self.repos.sort()
         self.lastrefresh = time.time()
 
     def run(self):
@@ -196,7 +195,7 @@
                     yield {"type" : i[0], "extension": i[1],
                            "node": nodeid, "url": url}
 
-        sortdefault = 'name', False
+        sortdefault = None, False
         def entries(sortcolumn="", descending=False, subdir="", **map):
 
             rows = []
--- a/mercurial/hgweb/protocol.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hgweb/protocol.py	Sat Nov 07 14:13:15 2009 -0600
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2, incorporated herein by reference.
 
-import cStringIO, zlib, tempfile, errno, os, sys, urllib
+import cStringIO, zlib, tempfile, errno, os, sys, urllib, copy
 from mercurial import util, streamclone
 from mercurial.node import bin, hex
 from mercurial import changegroup as changegroupmod
@@ -21,6 +21,7 @@
 ]
 
 HGTYPE = 'application/mercurial-0.1'
+basecaps = 'lookup changegroupsubset branchmap'.split()
 
 def lookup(repo, req):
     try:
@@ -109,7 +110,7 @@
     yield z.flush()
 
 def capabilities(repo, req):
-    caps = ['lookup', 'changegroupsubset', 'branchmap']
+    caps = copy.copy(basecaps)
     if repo.ui.configbool('server', 'uncompressed', untrusted=True):
         caps.append('stream=%d' % repo.changelog.version)
     if changegroupmod.bundlepriority:
@@ -181,18 +182,19 @@
         except ValueError, inst:
             raise ErrorResponse(HTTP_OK, inst)
         except (OSError, IOError), inst:
-            filename = getattr(inst, 'filename', '')
-            # Don't send our filesystem layout to the client
-            if filename.startswith(repo.root):
-                filename = filename[len(repo.root)+1:]
-            else:
-                filename = ''
             error = getattr(inst, 'strerror', 'Unknown error')
             if inst.errno == errno.ENOENT:
                 code = HTTP_NOT_FOUND
             else:
                 code = HTTP_SERVER_ERROR
-            raise ErrorResponse(code, '%s: %s' % (error, filename))
+            filename = getattr(inst, 'filename', '')
+            # Don't send our filesystem layout to the client
+            if filename and filename.startswith(repo.root):
+                filename = filename[len(repo.root)+1:]
+                text = '%s: %s' % (error, filename)
+            else:
+                text = error.replace(repo.root + os.path.sep, '')
+            raise ErrorResponse(code, text)
     finally:
         fp.close()
         os.unlink(tempname)
--- a/mercurial/hgweb/request.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hgweb/request.py	Sat Nov 07 14:13:15 2009 -0600
@@ -77,7 +77,7 @@
 
             if isinstance(status, ErrorResponse):
                 self.header(status.headers)
-                status = statusmessage(status.code)
+                status = statusmessage(status.code, status.message)
             elif status == 200:
                 status = '200 Script output follows'
             elif isinstance(status, int):
--- a/mercurial/hook.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/hook.py	Sat Nov 07 14:13:15 2009 -0600
@@ -106,10 +106,14 @@
 def hook(ui, repo, name, throw=False, **args):
     r = False
 
+    oldstdout = -1
     if _redirect:
-        # temporarily redirect stdout to stderr
-        oldstdout = os.dup(sys.__stdout__.fileno())
-        os.dup2(sys.__stderr__.fileno(), sys.__stdout__.fileno())
+        stdoutno = sys.__stdout__.fileno()
+        stderrno = sys.__stderr__.fileno()
+        # temporarily redirect stdout to stderr, if possible
+        if stdoutno >= 0 and stderrno >= 0:
+            oldstdout = os.dup(stdoutno)
+            os.dup2(stderrno, stdoutno)
 
     try:
         for hname, cmd in ui.configitems('hooks'):
@@ -128,8 +132,8 @@
             else:
                 r = _exthook(ui, repo, hname, cmd, args, throw) or r
     finally:
-        if _redirect:
-            os.dup2(oldstdout, sys.__stdout__.fileno())
+        if _redirect and oldstdout >= 0:
+            os.dup2(oldstdout, stdoutno)
             os.close(oldstdout)
 
     return r
--- a/mercurial/httprepo.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/httprepo.py	Sat Nov 07 14:13:15 2009 -0600
@@ -106,8 +106,9 @@
                 proto.startswith('text/plain') or
                 proto.startswith('application/hg-changegroup')):
             self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu))
-            raise error.RepoError(_("'%s' does not appear to be an hg repository")
-                                  % safeurl)
+            raise error.RepoError(_("'%s' does not appear to be an hg repository:\n"
+                                    "---%%<--- (%s)\n%s\n---%%<---\n")
+                                  % (safeurl, proto, resp.read()))
 
         if proto.startswith('application/mercurial-'):
             try:
--- a/mercurial/keepalive.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/keepalive.py	Sat Nov 07 14:13:15 2009 -0600
@@ -23,6 +23,9 @@
 #  - import md5 function from a local util module
 # Modified by Martin Geisler:
 #  - moved md5 function from local util module to this module
+# Modified by Augie Fackler:
+#  - add safesend method and use it to prevent broken pipe errors
+#    on large POST requests
 
 """An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
 
@@ -108,10 +111,11 @@
 
 # $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $
 
-import urllib2
+import errno
 import httplib
 import socket
 import thread
+import urllib2
 
 DEBUG = None
 
@@ -495,10 +499,76 @@
                 break
         return list
 
+def safesend(self, str):
+    """Send `str' to the server.
+
+    Shamelessly ripped off from httplib to patch a bad behavior.
+    """
+    # _broken_pipe_resp is an attribute we set in this function
+    # if the socket is closed while we're sending data but
+    # the server sent us a response before hanging up.
+    # In that case, we want to pretend to send the rest of the
+    # outgoing data, and then let the user use getresponse()
+    # (which we wrap) to get this last response before
+    # opening a new socket.
+    if getattr(self, '_broken_pipe_resp', None) is not None:
+        return
+
+    if self.sock is None:
+        if self.auto_open:
+            self.connect()
+        else:
+            raise httplib.NotConnected()
+
+    # send the data to the server. if we get a broken pipe, then close
+    # the socket. we want to reconnect when somebody tries to send again.
+    #
+    # NOTE: we DO propagate the error, though, because we cannot simply
+    #       ignore the error... the caller will know if they can retry.
+    if self.debuglevel > 0:
+        print "send:", repr(str)
+    try:
+        blocksize=8192
+        if hasattr(str,'read') :
+            if self.debuglevel > 0: print "sendIng a read()able"
+            data=str.read(blocksize)
+            while data:
+                self.sock.sendall(data)
+                data=str.read(blocksize)
+        else:
+            self.sock.sendall(str)
+    except socket.error, v:
+        reraise = True
+        if v[0] == errno.EPIPE:      # Broken pipe
+            if self._HTTPConnection__state == httplib._CS_REQ_SENT:
+                self._broken_pipe_resp = None
+                self._broken_pipe_resp = self.getresponse()
+                reraise = False
+            self.close()
+        if reraise:
+            raise
+
+def wrapgetresponse(cls):
+    """Wraps getresponse in cls with a broken-pipe sane version.
+    """
+    def safegetresponse(self):
+        # In safesend() we might set the _broken_pipe_resp
+        # attribute, in which case the socket has already
+        # been closed and we just need to give them the response
+        # back. Otherwise, we use the normal response path.
+        r = getattr(self, '_broken_pipe_resp', None)
+        if r is not None:
+            return r
+        return cls.getresponse(self)
+    safegetresponse.__doc__ = cls.getresponse.__doc__
+    return safegetresponse
 
 class HTTPConnection(httplib.HTTPConnection):
     # use the modified response class
     response_class = HTTPResponse
+    send = safesend
+    getresponse = wrapgetresponse(httplib.HTTPConnection)
+
 
 #########################################################################
 #####   TEST FUNCTIONS
--- a/mercurial/localrepo.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/localrepo.py	Sat Nov 07 14:13:15 2009 -0600
@@ -98,8 +98,7 @@
         self._tags = None
         self._tagtypes = None
 
-        self.branchcache = None
-        self._ubranchcache = None  # UTF-8 version of branchcache
+        self._branchcache = None  # in UTF-8
         self._branchcachetip = None
         self.nodetagscache = None
         self.filterpats = {}
@@ -321,31 +320,22 @@
 
     def branchmap(self):
         tip = self.changelog.tip()
-        if self.branchcache is not None and self._branchcachetip == tip:
-            return self.branchcache
+        if self._branchcache is not None and self._branchcachetip == tip:
+            return self._branchcache
 
         oldtip = self._branchcachetip
         self._branchcachetip = tip
-        if self.branchcache is None:
-            self.branchcache = {} # avoid recursion in changectx
-        else:
-            self.branchcache.clear() # keep using the same dict
         if oldtip is None or oldtip not in self.changelog.nodemap:
             partial, last, lrev = self._readbranchcache()
         else:
             lrev = self.changelog.rev(oldtip)
-            partial = self._ubranchcache
+            partial = self._branchcache
 
         self._branchtags(partial, lrev)
         # this private cache holds all heads (not just tips)
-        self._ubranchcache = partial
+        self._branchcache = partial
 
-        # the branch cache is stored on disk as UTF-8, but in the local
-        # charset internally
-        for k, v in partial.iteritems():
-            self.branchcache[encoding.tolocal(k)] = v
-        return self.branchcache
-
+        return self._branchcache
 
     def branchtags(self):
         '''return a dict where branch names map to the tipmost head of
@@ -566,7 +556,7 @@
 
         # abort here if the journal already exists
         if os.path.exists(self.sjoin("journal")):
-            raise error.RepoError(_("journal already exists - run hg recover"))
+            raise error.RepoError(_("abandoned transaction found - run hg recover"))
 
         # save dirstate for rollback
         try:
@@ -631,8 +621,7 @@
         self._tags = None
         self._tagtypes = None
         self.nodetagscache = None
-        self.branchcache = None
-        self._ubranchcache = None
+        self._branchcache = None # in UTF-8
         self._branchcachetip = None
 
     def _lock(self, lockname, wait, releasefn, acquirefn, desc):
@@ -914,7 +903,7 @@
             self.changelog.finalize(trp)
             tr.close()
 
-            if self.branchcache:
+            if self._branchcache:
                 self.branchtags()
 
             self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
--- a/mercurial/lock.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/lock.py	Sat Nov 07 14:13:15 2009 -0600
@@ -105,7 +105,7 @@
             return locker
         try:
             pid = int(pid)
-        except:
+        except ValueError:
             return locker
         if util.testpid(pid):
             return locker
@@ -122,13 +122,14 @@
     def release(self):
         if self.held > 1:
             self.held -= 1
-        elif self.held is 1:
+        elif self.held == 1:
             self.held = 0
             if self.releasefn:
                 self.releasefn()
             try:
                 os.unlink(self.f)
-            except: pass
+            except OSError:
+                pass
 
 def release(*locks):
     for lock in locks:
--- a/mercurial/mail.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/mail.py	Sat Nov 07 14:13:15 2009 -0600
@@ -169,7 +169,7 @@
     try:
         acc, dom = addr.split('@')
         acc = acc.encode('ascii')
-        dom = dom.encode('idna')
+        dom = dom.decode(encoding.encoding).encode('idna')
         addr = '%s@%s' % (acc, dom)
     except UnicodeDecodeError:
         raise util.Abort(_('invalid email address: %s') % addr)
--- a/mercurial/merge.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/merge.py	Sat Nov 07 14:13:15 2009 -0600
@@ -397,11 +397,38 @@
     """
     Perform a merge between the working directory and the given node
 
+    node = the node to update to, or None if unspecified
     branchmerge = whether to merge between branches
     force = whether to force branch merging or file overwriting
     partial = a function to filter file lists (dirstate not updated)
+
+    The table below shows all the behaviors of the update command
+    given the -c and -C or no options, whether the working directory
+    is dirty, whether a revision is specified, and the relationship of
+    the parent rev to the target rev (linear, on the same named
+    branch, or on another named branch).
+
+    This logic is tested by test-update-branches.
+
+    -c  -C  dirty  rev  |  linear   same  cross
+     n   n    n     n   |    ok     (1)     x
+     n   n    n     y   |    ok     ok     ok
+     n   n    y     *   |   merge   (2)    (2)
+     n   y    *     *   |    ---  discard  ---
+     y   n    y     *   |    ---    (3)    ---
+     y   n    n     *   |    ---    ok     ---
+     y   y    *     *   |    ---    (4)    ---
+
+    x = can't happen
+    * = don't-care
+    1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
+    2 = abort: crosses branches (use 'hg merge' to merge or
+                 use 'hg update -C' to discard changes)
+    3 = abort: uncommitted local changes
+    4 = incompatible options (checked in commands.py)
     """
 
+    onode = node
     wlock = repo.wlock()
     try:
         wc = repo[None]
@@ -439,17 +466,14 @@
         elif not overwrite:
             if pa == p1 or pa == p2: # linear
                 pass # all good
-            elif p1.branch() == p2.branch():
-                if wc.files() or wc.deleted():
-                    raise util.Abort(_("crosses branches (use 'hg merge' or "
-                                       "'hg update -C' to discard changes)"))
-                raise util.Abort(_("crosses branches (use 'hg merge' "
-                                   "or 'hg update -C')"))
             elif wc.files() or wc.deleted():
-                raise util.Abort(_("crosses named branches (use "
-                                   "'hg update -C' to discard changes)"))
+                raise util.Abort(_("crosses branches (use 'hg merge' to merge "
+                                 "or use 'hg update -C' to discard changes)"))
+            elif onode is None:
+                raise util.Abort(_("crosses branches (use 'hg merge' or use "
+                                   "'hg update -c')"))
             else:
-                # Allow jumping branches if there are no changes
+                # Allow jumping branches if clean and specific rev given
                 overwrite = True
 
         ### calculate phase
--- a/mercurial/minirst.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/minirst.py	Sat Nov 07 14:13:15 2009 -0600
@@ -16,19 +16,23 @@
 
 It only supports a small subset of reStructuredText:
 
+- sections
+
 - paragraphs
 
-- definition lists (must use '  ' to indent definitions)
+- literal blocks
+
+- definition lists
 
-- lists (items must start with '-')
+- bullet lists (items must start with '-')
+
+- enumerated lists (no autonumbering)
 
 - field lists (colons cannot be escaped)
 
-- literal blocks
-
 - option lists (supports only long options without arguments)
 
-- inline markup is not recognized at all.
+- inline literals (no other inline markup is not recognized)
 """
 
 import re, sys, textwrap
@@ -94,9 +98,10 @@
             # correct for this here while we still have the original
             # information on the indentation of the subsequent literal
             # blocks available.
-            if blocks[i]['lines'][0].startswith('- '):
-                indent += 2
-                adjustment -= 2
+            m = _bulletre.match(blocks[i]['lines'][0])
+            if m:
+                indent += m.end()
+                adjustment -= m.end()
 
             # Mark the following indented blocks.
             while i+1 < len(blocks) and blocks[i+1]['indent'] > indent:
@@ -106,6 +111,53 @@
         i += 1
     return blocks
 
+_bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)) ')
+_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)?  +)(.*)$')
+_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)')
+_definitionre = re.compile(r'[^ ]')
+
+def splitparagraphs(blocks):
+    """Split paragraphs into lists."""
+    # Tuples with (list type, item regexp, single line items?). Order
+    # matters: definition lists has the least specific regexp and must
+    # come last.
+    listtypes = [('bullet', _bulletre, True),
+                 ('option', _optionre, True),
+                 ('field', _fieldre, True),
+                 ('definition', _definitionre, False)]
+
+    def match(lines, i, itemre, singleline):
+        """Does itemre match an item at line i?
+
+        A list item can be followed by an idented line or another list
+        item (but only if singleline is True).
+        """
+        line1 = lines[i]
+        line2 = i+1 < len(lines) and lines[i+1] or ''
+        if not itemre.match(line1):
+            return False
+        if singleline:
+            return line2 == '' or line2[0] == ' ' or itemre.match(line2)
+        else:
+            return line2.startswith(' ')
+
+    i = 0
+    while i < len(blocks):
+        if blocks[i]['type'] == 'paragraph':
+            lines = blocks[i]['lines']
+            for type, itemre, singleline in listtypes:
+                if match(lines, 0, itemre, singleline):
+                    items = []
+                    for j, line in enumerate(lines):
+                        if match(lines, j, itemre, singleline):
+                            items.append(dict(type=type, lines=[],
+                                              indent=blocks[i]['indent']))
+                        items[-1]['lines'].append(line)
+                    blocks[i:i+1] = items
+                    break
+        i += 1
+    return blocks
+
 
 def findsections(blocks):
     """Finds sections.
@@ -127,139 +179,6 @@
     return blocks
 
 
-def findbulletlists(blocks):
-    """Finds bullet lists.
-
-    The blocks must have a 'type' field, i.e., they should have been
-    run through findliteralblocks first.
-    """
-    i = 0
-    while i < len(blocks):
-        # Searching for a paragraph that looks like this:
-        #
-        # +------+-----------------------+
-        # | "- " | list item             |
-        # +------| (body elements)+      |
-        #        +-----------------------+
-        if (blocks[i]['type'] == 'paragraph' and
-            blocks[i]['lines'][0].startswith('- ')):
-            items = []
-            for line in blocks[i]['lines']:
-                if line.startswith('- '):
-                    items.append(dict(type='bullet', lines=[],
-                                      indent=blocks[i]['indent']))
-                    line = line[2:]
-                items[-1]['lines'].append(line)
-            blocks[i:i+1] = items
-            i += len(items) - 1
-        i += 1
-    return blocks
-
-
-_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)?  +)(.*)$')
-def findoptionlists(blocks):
-    """Finds option lists.
-
-    The blocks must have a 'type' field, i.e., they should have been
-    run through findliteralblocks first.
-    """
-    i = 0
-    while i < len(blocks):
-        # Searching for a paragraph that looks like this:
-        #
-        # +----------------------------+-------------+
-        # | "--" option "  "           | description |
-        # +-------+--------------------+             |
-        #         | (body elements)+                 |
-        #         +----------------------------------+
-        if (blocks[i]['type'] == 'paragraph' and
-            _optionre.match(blocks[i]['lines'][0])):
-            options = []
-            for line in blocks[i]['lines']:
-                m = _optionre.match(line)
-                if m:
-                    option, arg, rest = m.groups()
-                    width = len(option) + len(arg)
-                    options.append(dict(type='option', lines=[],
-                                        indent=blocks[i]['indent'],
-                                        width=width))
-                options[-1]['lines'].append(line)
-            blocks[i:i+1] = options
-            i += len(options) - 1
-        i += 1
-    return blocks
-
-
-_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)')
-def findfieldlists(blocks):
-    """Finds fields lists.
-
-    The blocks must have a 'type' field, i.e., they should have been
-    run through findliteralblocks first.
-    """
-    i = 0
-    while i < len(blocks):
-        # Searching for a paragraph that looks like this:
-        #
-        #
-        # +--------------------+----------------------+
-        # | ":" field name ":" | field body           |
-        # +-------+------------+                      |
-        #         | (body elements)+                  |
-        #         +-----------------------------------+
-        if (blocks[i]['type'] == 'paragraph' and
-            _fieldre.match(blocks[i]['lines'][0])):
-            indent = blocks[i]['indent']
-            fields = []
-            for line in blocks[i]['lines']:
-                m = _fieldre.match(line)
-                if m:
-                    key, spaces, rest = m.groups()
-                    width = 2 + len(key) + len(spaces)
-                    fields.append(dict(type='field', lines=[],
-                                       indent=indent, width=width))
-                    # Turn ":foo: bar" into "foo   bar".
-                    line = '%s  %s%s' % (key, spaces, rest)
-                fields[-1]['lines'].append(line)
-            blocks[i:i+1] = fields
-            i += len(fields) - 1
-        i += 1
-    return blocks
-
-
-def finddefinitionlists(blocks):
-    """Finds definition lists.
-
-    The blocks must have a 'type' field, i.e., they should have been
-    run through findliteralblocks first.
-    """
-    i = 0
-    while i < len(blocks):
-        # Searching for a paragraph that looks like this:
-        #
-        # +----------------------------+
-        # | term                       |
-        # +--+-------------------------+--+
-        #    | definition                 |
-        #    | (body elements)+           |
-        #    +----------------------------+
-        if (blocks[i]['type'] == 'paragraph' and
-            len(blocks[i]['lines']) > 1 and
-            not blocks[i]['lines'][0].startswith('  ') and
-            blocks[i]['lines'][1].startswith('  ')):
-            definitions = []
-            for line in blocks[i]['lines']:
-                if not line.startswith('  '):
-                    definitions.append(dict(type='definition', lines=[],
-                                            indent=blocks[i]['indent']))
-                definitions[-1]['lines'].append(line)
-                definitions[-1]['hang'] = len(line) - len(line.lstrip())
-            blocks[i:i+1] = definitions
-            i += len(definitions) - 1
-        i += 1
-    return blocks
-
-
 def inlineliterals(blocks):
     for b in blocks:
         if b['type'] == 'paragraph':
@@ -291,30 +210,41 @@
     indent = ' ' * block['indent']
     if block['type'] == 'margin':
         return ''
-    elif block['type'] == 'literal':
+    if block['type'] == 'literal':
         indent += '  '
         return indent + ('\n' + indent).join(block['lines'])
-    elif block['type'] == 'section':
+    if block['type'] == 'section':
         return indent + ('\n' + indent).join(block['lines'])
-    elif block['type'] == 'definition':
+    if block['type'] == 'definition':
         term = indent + block['lines'][0]
-        defindent = indent + block['hang'] * ' '
+        hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
+        defindent = indent + hang * ' '
         text = ' '.join(map(str.strip, block['lines'][1:]))
         return "%s\n%s" % (term, textwrap.fill(text, width=width,
                                                initial_indent=defindent,
                                                subsequent_indent=defindent))
-    else:
-        initindent = subindent = indent
-        text = ' '.join(map(str.strip, block['lines']))
-        if block['type'] == 'bullet':
-            initindent = indent + '- '
-            subindent = indent + '  '
-        elif block['type'] in ('option', 'field'):
-            subindent = indent + block['width'] * ' '
+    initindent = subindent = indent
+    if block['type'] == 'bullet':
+        m = _bulletre.match(block['lines'][0])
+        if m:
+            subindent = indent + m.end() * ' '
+    elif block['type'] == 'field':
+        m = _fieldre.match(block['lines'][0])
+        if m:
+            key, spaces, rest = m.groups()
+            # Turn ":foo: bar" into "foo   bar".
+            block['lines'][0] = '%s  %s%s' % (key, spaces, rest)
+            subindent = indent + (2 + len(key) + len(spaces)) * ' '
+    elif block['type'] == 'option':
+        m = _optionre.match(block['lines'][0])
+        if m:
+            option, arg, rest = m.groups()
+            subindent = indent + (len(option) + len(arg)) * ' '
 
-        return textwrap.fill(text, width=width,
-                             initial_indent=initindent,
-                             subsequent_indent=subindent)
+    text = ' '.join(map(str.strip, block['lines']))
+    return textwrap.fill(text, width=width,
+                         initial_indent=initindent,
+                         subsequent_indent=subindent)
 
 
 def format(text, width, indent=0):
@@ -324,11 +254,8 @@
         b['indent'] += indent
     blocks = findliteralblocks(blocks)
     blocks = inlineliterals(blocks)
+    blocks = splitparagraphs(blocks)
     blocks = findsections(blocks)
-    blocks = findbulletlists(blocks)
-    blocks = findoptionlists(blocks)
-    blocks = findfieldlists(blocks)
-    blocks = finddefinitionlists(blocks)
     blocks = addmargins(blocks)
     return '\n'.join(formatblock(b, width) for b in blocks)
 
@@ -346,10 +273,7 @@
     text = open(sys.argv[1]).read()
     blocks = debug(findblocks, text)
     blocks = debug(findliteralblocks, blocks)
+    blocks = debug(splitparagraphs, blocks)
     blocks = debug(findsections, blocks)
-    blocks = debug(findbulletlists, blocks)
-    blocks = debug(findoptionlists, blocks)
-    blocks = debug(findfieldlists, blocks)
-    blocks = debug(finddefinitionlists, blocks)
     blocks = debug(addmargins, blocks)
     print '\n'.join(formatblock(b, 30) for b in blocks)
--- a/mercurial/patch.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/patch.py	Sat Nov 07 14:13:15 2009 -0600
@@ -300,7 +300,7 @@
         finally:
             fp.close()
 
-    def writelines(self, fname, lines):        
+    def writelines(self, fname, lines):
         # Ensure supplied data ends in fname, being a regular file or
         # a symlink. updatedir() will -too magically- take care of
         # setting it to the proper type afterwards.
@@ -342,11 +342,7 @@
         # result is a list of line numbers sorted based on distance
         # from linenum
 
-        try:
-            cand = self.hash[l]
-        except:
-            return []
-
+        cand = self.hash.get(l, [])
         if len(cand) > 1:
             # resort our list of potentials forward then back.
             cand.sort(key=lambda x: abs(x - linenum))
@@ -484,6 +480,8 @@
         self.hunk = [ desc ]
         self.a = []
         self.b = []
+        self.starta = self.lena = None
+        self.startb = self.lenb = None
         if context:
             self.read_context_hunk(lr)
         else:
@@ -1007,12 +1005,12 @@
         return -1
     return err
 
-def diffopts(ui, opts={}, untrusted=False):
+def diffopts(ui, opts=None, untrusted=False):
     def get(key, name=None, getter=ui.configbool):
-        return (opts.get(key) or
+        return ((opts and opts.get(key)) or
                 getter('diff', name or key, None, untrusted=untrusted))
     return mdiff.diffopts(
-        text=opts.get('text'),
+        text=opts and opts.get('text'),
         git=get('git'),
         nodates=get('nodates'),
         showfunc=get('show_function', 'showfunc'),
@@ -1098,10 +1096,12 @@
                          util.explain_exit(code)[0])
     return fuzz
 
-def internalpatch(patchobj, ui, strip, cwd, files={}, eolmode='strict'):
+def internalpatch(patchobj, ui, strip, cwd, files=None, eolmode='strict'):
     """use builtin patch to apply <patchobj> to the working directory.
     returns whether patch was applied with fuzz factor."""
 
+    if files is None:
+        files = {}
     if eolmode is None:
         eolmode = ui.config('patch', 'eol', 'strict')
     try:
@@ -1125,7 +1125,7 @@
         raise PatchError
     return ret > 0
 
-def patch(patchname, ui, strip=1, cwd=None, files={}, eolmode='strict'):
+def patch(patchname, ui, strip=1, cwd=None, files=None, eolmode='strict'):
     """Apply <patchname> to the working directory.
 
     'eolmode' specifies how end of lines should be handled. It can be:
@@ -1139,6 +1139,8 @@
     """
     patcher = ui.config('ui', 'patch')
     args = []
+    if files is None:
+        files = {}
     try:
         if patcher:
             return externalpatch(patcher, args, patchname, ui, strip, cwd,
@@ -1214,7 +1216,7 @@
     if opts is None:
         opts = mdiff.defaultopts
 
-    if not node1:
+    if not node1 and not node2:
         node1 = repo.dirstate.parents()[0]
 
     def lrugetfilectx():
@@ -1225,7 +1227,7 @@
             if f not in cache:
                 if len(cache) > 20:
                     del cache[order.pop(0)]
-                cache[f] = fctx._filelog
+                cache[f] = fctx.filelog()
             else:
                 order.remove(f)
             order.append(f)
--- a/mercurial/revlog.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/revlog.py	Sat Nov 07 14:13:15 2009 -0600
@@ -466,7 +466,7 @@
         if i:
             try:
                 d = self._io.parseindex(f, i, self._inline)
-            except (ValueError, IndexError), e:
+            except (ValueError, IndexError):
                 raise RevlogError(_("index %s is corrupted") % (self.indexfile))
             self.index, self.nodemap, self._chunkcache = d
             if not self._chunkcache:
--- a/mercurial/sshserver.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/sshserver.py	Sat Nov 07 14:13:15 2009 -0600
@@ -9,9 +9,12 @@
 from i18n import _
 from node import bin, hex
 import streamclone, util, hook
-import os, sys, tempfile, urllib
+import os, sys, tempfile, urllib, copy
 
 class sshserver(object):
+
+    caps = 'unbundle lookup changegroupsubset branchmap'.split()
+
     def __init__(self, ui, repo):
         self.ui = ui
         self.repo = repo
@@ -85,8 +88,7 @@
 
         capabilities: space separated list of tokens
         '''
-
-        caps = ['unbundle', 'lookup', 'changegroupsubset', 'branchmap']
+        caps = copy.copy(self.caps)
         if self.ui.configbool('server', 'uncompressed'):
             caps.append('stream=%d' % self.repo.changelog.version)
         self.respond("capabilities: %s\n" % (' '.join(caps),))
@@ -179,11 +181,9 @@
         self.respond('')
 
         # write bundle data to temporary file because it can be big
-        tempname = fp = None
+        fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
+        fp = os.fdopen(fd, 'wb+')
         try:
-            fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
-            fp = os.fdopen(fd, 'wb+')
-
             count = int(self.fin.readline())
             while count:
                 fp.write(self.fin.read(count))
@@ -210,10 +210,8 @@
                     self.lock.release()
                     self.lock = None
         finally:
-            if fp is not None:
-                fp.close()
-            if tempname is not None:
-                os.unlink(tempname)
+            fp.close()
+            os.unlink(tempname)
 
     def do_stream_out(self):
         try:
--- a/mercurial/subrepo.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/subrepo.py	Sat Nov 07 14:13:15 2009 -0600
@@ -27,7 +27,7 @@
     if '.hgsubstate' in ctx:
         try:
             for l in ctx['.hgsubstate'].data().splitlines():
-                revision, path = l.split()
+                revision, path = l.split(" ", 1)
                 rev[path] = revision
         except IOError, err:
             if err.errno != errno.ENOENT:
--- a/mercurial/tags.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/tags.py	Sat Nov 07 14:13:15 2009 -0600
@@ -10,7 +10,6 @@
 # Eventually, it could take care of updating (adding/removing/moving)
 # tags too.
 
-import os
 from node import nullid, bin, hex, short
 from i18n import _
 import encoding
--- a/mercurial/templatefilters.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/templatefilters.py	Sat Nov 07 14:13:15 2009 -0600
@@ -40,10 +40,13 @@
         return 'in the future'
 
     delta = max(1, int(now - then))
+    if delta > agescales[0][1] * 2:
+        return util.shortdate(date)
+
     for t, s in agescales:
         n = delta // s
         if n >= 2 or s == 1:
-            return fmt(t, n)
+            return '%s ago' % fmt(t, n)
 
 para_re = None
 space_re = None
--- a/mercurial/transaction.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/transaction.py	Sat Nov 07 14:13:15 2009 -0600
@@ -28,14 +28,14 @@
         if o or not unlink:
             try:
                 opener(f, 'a').truncate(o)
-            except:
+            except IOError:
                 report(_("failed to truncate %s\n") % f)
                 raise
         else:
             try:
                 fn = opener(f).name
                 os.unlink(fn)
-            except IOError, inst:
+            except (IOError, OSError), inst:
                 if inst.errno != errno.ENOENT:
                     raise
     os.unlink(journal)
@@ -59,8 +59,7 @@
 
     def __del__(self):
         if self.journal:
-            if self.entries: self._abort()
-            self.file.close()
+            self._abort()
 
     @active
     def startgroup(self):
@@ -126,7 +125,7 @@
         self.entries = []
         if self.after:
             self.after()
-        else:
+        if os.path.isfile(self.journal):
             os.unlink(self.journal)
         self.journal = None
 
@@ -141,7 +140,10 @@
         self.count = 0
         self.file.close()
 
-        if not self.entries: return
+        if not self.entries:
+            if self.journal:
+                os.unlink(self.journal)
+            return
 
         self.report(_("transaction abort!\n"))
 
--- a/mercurial/ui.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/ui.py	Sat Nov 07 14:13:15 2009 -0600
@@ -377,7 +377,7 @@
 
         if total:
             pct = 100.0 * pos / total
-            ui.debug('%s:%s %s/%s%s (%4.2g%%)\n'
+            self.debug('%s:%s %s/%s%s (%4.2g%%)\n'
                      % (topic, item, pos, total, unit, pct))
         else:
-            ui.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
+            self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
--- a/mercurial/url.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/url.py	Sat Nov 07 14:13:15 2009 -0600
@@ -408,10 +408,14 @@
         self.close_all()
 
 if has_https:
-    class httpsconnection(httplib.HTTPSConnection):
+    class BetterHTTPS(httplib.HTTPSConnection):
+        send = keepalive.safesend
+
+    class httpsconnection(BetterHTTPS):
         response_class = keepalive.HTTPResponse
         # must be able to send big bundle as stream.
-        send = _gen_sendfile(httplib.HTTPSConnection)
+        send = _gen_sendfile(BetterHTTPS)
+        getresponse = keepalive.wrapgetresponse(httplib.HTTPSConnection)
 
     class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
         def __init__(self, ui):
--- a/mercurial/util.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/util.py	Sat Nov 07 14:13:15 2009 -0600
@@ -1116,6 +1116,7 @@
         seen_dirs = []
         _add_dir_if_not_there(seen_dirs, path)
     for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
+        dirs.sort()
         if '.hg' in dirs:
             yield root # found a repository
             qroot = os.path.join(root, '.hg', 'patches')
@@ -1223,11 +1224,11 @@
                 return array.array('h', arri)[1]
             except ValueError:
                 pass
-            except IOError, e: 
-                if e[0] == errno.EINVAL: 
-                    pass 
-                else: 
-                    raise 
+            except IOError, e:
+                if e[0] == errno.EINVAL:
+                    pass
+                else:
+                    raise
     except ImportError:
         pass
     return 80
--- a/mercurial/verify.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/mercurial/verify.py	Sat Nov 07 14:13:15 2009 -0600
@@ -7,6 +7,7 @@
 
 from node import nullid, short
 from i18n import _
+import os
 import revlog, util, error
 
 def verify(repo):
@@ -105,6 +106,9 @@
         seen[n] = i
         return lr
 
+    if os.path.exists(repo.sjoin("journal")):
+        ui.warn(_("abandoned transaction found - run hg recover\n"))
+
     revlogv1 = cl.version != revlog.REVLOGV0
     if ui.verbose or not revlogv1:
         ui.status(_("repository uses revlog format %d\n") %
--- a/templates/gitweb/changelogentry.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/gitweb/changelogentry.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -1,5 +1,5 @@
 <div>
-<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|age} ago</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
+<a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}"><span class="age">{date|age}</span>{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a>
 </div>
 <div class="title_text">
 <div class="log_link">
--- a/templates/gitweb/changeset.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/gitweb/changeset.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -29,7 +29,7 @@
 <div class="title_text">
 <table cellspacing="0">
 <tr><td>author</td><td>{author|obfuscate}</td></tr>
-<tr><td></td><td>{date|date} ({date|age} ago)</td></tr>
+<tr><td></td><td>{date|date} ({date|age})</td></tr>
 {branch%changesetbranch}
 <tr><td>changeset {rev}</td><td style="font-family:monospace">{node|short}</td></tr>
 {parent%changesetparent}
--- a/templates/gitweb/fileannotate.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/gitweb/fileannotate.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -36,7 +36,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td></td>
- <td>{date|date} ({date|age} ago)</td></tr>
+ <td>{date|date} ({date|age})</td></tr>
 {branch%filerevbranch}
 <tr>
  <td>changeset {rev}</td>
--- a/templates/gitweb/filerevision.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/gitweb/filerevision.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -36,7 +36,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td></td>
- <td>{date|date} ({date|age} ago)</td></tr>
+ <td>{date|date} ({date|age})</td></tr>
 {branch%filerevbranch}
 <tr>
  <td>changeset {rev}</td>
--- a/templates/gitweb/map	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/gitweb/map	Sat Nov 07 14:13:15 2009 -0600
@@ -150,7 +150,7 @@
 tags = tags.tmpl
 tagentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age} ago</i></td>
+    <td class="age"><i>{date|age}</i></td>
     <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
     <td class="link">
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
@@ -161,7 +161,7 @@
 branches = branches.tmpl
 branchentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age} ago</i></td>
+    <td class="age"><i>{date|age}</i></td>
     <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td>
     <td class="{status}">{branch|escape}</td>
     <td class="link">
@@ -204,7 +204,7 @@
 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
 shortlogentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age} ago</i></td>
+    <td class="age"><i>{date|age}</i></td>
     <td><i>{author|person}</i></td>
     <td>
       <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
@@ -219,7 +219,7 @@
   </tr>'
 filelogentry = '
   <tr class="parity{parity}">
-    <td class="age"><i>{date|age} ago</i></td>
+    <td class="age"><i>{date|age}</i></td>
     <td>
       <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
         <b>{desc|strip|firstline|escape|nonempty}</b>
@@ -238,7 +238,7 @@
     </td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age} ago</td>
+    <td class="age">{lastchange|age}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
     <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td>
   </tr>\n'
--- a/templates/monoblue/changelogentry.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/monoblue/changelogentry.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -1,6 +1,6 @@
 <h3 class="changelog"><a class="title" href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}<span class="logtags"> {inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3>
 <ul class="changelog-entry">
-    <li class="age">{date|age} ago</li>
+    <li class="age">{date|age}</li>
     <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li>
     <li class="description">{desc|strip|escape|addbreaks|nonempty}</li>
 </ul>
--- a/templates/monoblue/changeset.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/monoblue/changeset.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -36,7 +36,7 @@
     <h2 class="no-link no-border">changeset</h2>
 
     <h3 class="changeset"><a href="{url}raw-rev/{node|short}">{desc|strip|escape|firstline|nonempty} <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></h3>
-    <p class="changeset-age"><span>{date|age} ago</span></p>
+    <p class="changeset-age"><span>{date|age}</span></p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/templates/monoblue/fileannotate.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/monoblue/fileannotate.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -38,7 +38,7 @@
 
     <h2 class="no-link no-border">{file|escape}@{node|short} (annotated)</h2>
     <h3 class="changeset">{file|escape}</h3>
-    <p class="changeset-age"><span>{date|age} ago</span></p>
+    <p class="changeset-age"><span>{date|age}</span></p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/templates/monoblue/filerevision.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/monoblue/filerevision.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -38,7 +38,7 @@
 
     <h2 class="no-link no-border">{file|escape}@{node|short}</h2>
     <h3 class="changeset">{file|escape}</h3>
-    <p class="changeset-age"><span>{date|age} ago</span></p>
+    <p class="changeset-age"><span>{date|age}</span></p>
 
     <dl class="overview">
         <dt>author</dt>
--- a/templates/monoblue/map	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/monoblue/map	Sat Nov 07 14:13:15 2009 -0600
@@ -127,7 +127,7 @@
 tags = tags.tmpl
 tagentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age} ago</td>
+    <td class="nowrap">{date|age}</td>
     <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
     <td class="nowrap">
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
@@ -138,7 +138,7 @@
 branches = branches.tmpl
 branchentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age} ago</td>
+    <td class="nowrap">{date|age}</td>
     <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
     <td class="{status}">{branch|escape}</td>
     <td class="nowrap">
@@ -170,7 +170,7 @@
 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
 shortlogentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age} ago</td>
+    <td class="nowrap">{date|age}</td>
     <td>{author|person}</td>
     <td>
       <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
@@ -185,7 +185,7 @@
   </tr>'
 filelogentry = '
   <tr class="parity{parity}">
-    <td class="nowrap">{date|age} ago</td>
+    <td class="nowrap">{date|age}</td>
     <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
     <td class="nowrap">
       <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
@@ -198,7 +198,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td>{lastchange|age} ago</td>
+    <td>{lastchange|age}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
     <td>
       <div class="rss_logo">
--- a/templates/paper/changeset.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/paper/changeset.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -45,7 +45,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age} ago)</td></tr>
+ <td class="date">{date|date} ({date|age})</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author">{parent%changesetparent}</td>
--- a/templates/paper/fileannotate.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/paper/fileannotate.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -22,6 +22,7 @@
 </ul>
 <ul>
 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
 <li class="active">annotate</li>
 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
@@ -49,7 +50,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age} ago)</td>
+ <td class="date">{date|date} ({date|age})</td>
 </tr>
 <tr>
  <th class="author">parents</th>
--- a/templates/paper/filediff.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/paper/filediff.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -21,6 +21,7 @@
 </ul>
 <ul>
 <li><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
 <li class="active">diff</li>
 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
@@ -48,7 +49,7 @@
 </tr>
 <tr>
  <th>date</th>
- <td>{date|date} ({date|age} ago)</td>
+ <td>{date|date} ({date|age})</td>
 </tr>
 <tr>
  <th>parents</th>
--- a/templates/paper/filerevision.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/paper/filerevision.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -21,6 +21,7 @@
 </ul>
 <ul>
 <li class="active">file</li>
+<li><a href="{url}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
 <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
 <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
 <li><a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
@@ -48,7 +49,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">{date|date} ({date|age} ago)</td>
+ <td class="date">{date|date} ({date|age})</td>
 </tr>
 <tr>
  <th class="author">parents</th>
--- a/templates/paper/map	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/paper/map	Sat Nov 07 14:13:15 2009 -0600
@@ -176,7 +176,7 @@
     <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
     <td>{description}</td>
     <td>{contact|obfuscate}</td>
-    <td class="age">{lastchange|age} ago</td>
+    <td class="age">{lastchange|age}</td>
     <td class="indexlinks">{archives%indexarchiveentry}</td>
   </tr>\n'
 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
--- a/templates/spartan/changelogentry.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/spartan/changelogentry.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -1,6 +1,6 @@
 <table class="logEntry parity{parity}">
  <tr>
-  <th class="age">{date|age} ago:</th>
+  <th class="age">{date|age}:</th>
   <th class="firstline">{desc|strip|firstline|escape|nonempty}</th>
  </tr>
  <tr>
--- a/templates/spartan/changeset.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/spartan/changeset.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -30,7 +30,7 @@
 </tr>
 <tr>
  <th class="date">date:</th>
- <td class="date">{date|date} ({date|age} ago)</td>
+ <td class="date">{date|date} ({date|age})</td>
 </tr>
 <tr>
  <th class="files">files:</th>
--- a/templates/spartan/fileannotate.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/spartan/fileannotate.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -29,7 +29,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td class="metatag">date:</td>
- <td>{date|date} ({date|age} ago)</td>
+ <td>{date|date} ({date|age})</td>
 </tr>
 <tr>
  <td class="metatag">permissions:</td>
--- a/templates/spartan/filelogentry.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/spartan/filelogentry.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -1,6 +1,6 @@
 <table class="logEntry parity{parity}">
  <tr>
-  <th class="age">{date|age} ago:</th>
+  <th class="age">{date|age}:</th>
   <th class="firstline"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></th>
  </tr>
  <tr>
--- a/templates/spartan/filerevision.tmpl	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/spartan/filerevision.tmpl	Sat Nov 07 14:13:15 2009 -0600
@@ -29,7 +29,7 @@
  <td>{author|obfuscate}</td></tr>
 <tr>
  <td class="metatag">date:</td>
- <td>{date|date} ({date|age} ago)</td></tr>
+ <td>{date|date} ({date|age})</td></tr>
 <tr>
  <td class="metatag">permissions:</td>
  <td>{permissions|permissions}</td></tr>
--- a/templates/static/style-paper.css	Wed Nov 04 22:14:26 2009 +0100
+++ b/templates/static/style-paper.css	Sat Nov 07 14:13:15 2009 -0600
@@ -161,7 +161,7 @@
   border-bottom: 1px solid #999;
 }
 .bigtable tr { border: none; }
-.bigtable .age { width: 6em; }
+.bigtable .age { width: 7em; }
 .bigtable .author { width: 12em; }
 .bigtable .description { }
 .bigtable .node { width: 5em; font-family: monospace;}
--- a/tests/get-with-headers.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/get-with-headers.py	Sat Nov 07 14:13:15 2009 -0600
@@ -22,7 +22,6 @@
         print "%s: %s" % (h, response.getheader(h))
 print
 data = response.read()
-data = re.sub('\d+ years', 'many years', data)
 sys.stdout.write(data)
 
 if 200 <= response.status <= 299:
--- a/tests/hghave	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/hghave	Sat Nov 07 14:13:15 2009 -0600
@@ -121,8 +121,8 @@
     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')
+    return matchoutput('rst2html --version 2>&1', r'^rst2html \(Docutils') or \
+        matchoutput('rst2html.py --version 2>&1', r'^rst2html.py \(Docutils')
 
 def has_svn():
     #return matchoutput('svn --version 2>&1', r'^svn, version') and \
--- a/tests/run-tests.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/run-tests.py	Sat Nov 07 14:13:15 2009 -0600
@@ -93,8 +93,13 @@
     parser.add_option("-k", "--keywords",
         help="run tests matching keywords")
     parser.add_option("--keep-tmpdir", action="store_true",
-        help="keep temporary directory after running tests"
-             " (best used with --tmpdir)")
+        help="keep temporary directory after running tests")
+    parser.add_option("--tmpdir", type="string",
+        help="run tests in the given temporary directory"
+             " (implies --keep-tmpdir)")
+    parser.add_option("-d", "--debug", action="store_true",
+        help="debug mode: write output of test scripts to console"
+             " rather than capturing and diff'ing it (disables timeout)")
     parser.add_option("-R", "--restart", action="store_true",
         help="restart at last error")
     parser.add_option("-p", "--port", type="int",
@@ -109,8 +114,6 @@
     parser.add_option("-t", "--timeout", type="int",
         help="kill errant tests after TIMEOUT seconds"
              " (default: $%s or %d)" % defaults['timeout'])
-    parser.add_option("--tmpdir", type="string",
-        help="run tests in the given temporary directory")
     parser.add_option("-v", "--verbose", action="store_true",
         help="output verbose messages")
     parser.add_option("-n", "--nodiff", action="store_true",
@@ -168,22 +171,25 @@
             for m in msg:
                 print m,
             print
+            sys.stdout.flush()
     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:
         parser.error('--jobs must be positive')
     if options.interactive and options.jobs > 1:
         print '(--interactive overrides --jobs)'
         options.jobs = 1
+    if options.interactive and options.debug:
+        parser.error("-i/--interactive and -d/--debug are incompatible")
+    if options.debug:
+        if options.timeout != defaults['timeout']:
+            sys.stderr.write(
+                'warning: --timeout option ignored with --debug\n')
+        options.timeout = 0
     if options.py3k_warnings:
         if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
             parser.error('--py3k-warnings can only be used on Python 2.6+')
@@ -379,8 +385,13 @@
 
 def run(cmd, options):
     """Run command in a sub-process, capturing the output (stdout and stderr).
-    Return the exist code, and output."""
+    Return a tuple (exitcode, output).  output is None in debug mode."""
     # TODO: Use subprocess.Popen if we're running on Python 2.4
+    if options.debug:
+        proc = subprocess.Popen(cmd, shell=True)
+        ret = proc.wait()
+        return (ret, None)
+
     if os.name == 'nt' or sys.platform.startswith('java'):
         tochild, fromchild = os.popen4(cmd)
         tochild.close()
@@ -492,16 +503,24 @@
     mark = '.'
 
     skipped = (ret == SKIPPED_STATUS)
-    # If reference output file exists, check test output against it
-    if os.path.exists(ref):
+    # If we're not in --debug mode and reference output file exists,
+    # check test output against it.
+    if options.debug:
+        refout = None                   # to match out == None
+    elif os.path.exists(ref):
         f = open(ref, "r")
         refout = splitnewlines(f.read())
         f.close()
     else:
         refout = []
+
     if skipped:
         mark = 's'
-        missing, failed = parsehghaveoutput(out)
+        if out is None:                 # debug mode: nothing to parse
+            missing = ['unknown']
+            failed = None
+        else:
+            missing, failed = parsehghaveoutput(out)
         if not missing:
             missing = ['irrelevant']
         if failed:
@@ -526,7 +545,7 @@
         sys.stdout.write(mark)
         sys.stdout.flush()
 
-    if ret != 0 and not skipped:
+    if ret != 0 and not skipped and not options.debug:
         # Save errors to a file for diagnosis
         f = open(err, "wb")
         for line in out:
@@ -765,8 +784,24 @@
 
     global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
     TESTDIR = os.environ["TESTDIR"] = os.getcwd()
-    HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.',
-                                                   options.tmpdir))
+    if options.tmpdir:
+        options.keep_tmpdir = True
+        tmpdir = options.tmpdir
+        if os.path.exists(tmpdir):
+            # Meaning of tmpdir has changed since 1.3: we used to create
+            # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
+            # tmpdir already exists.
+            sys.exit("error: temp dir %r already exists" % tmpdir)
+
+            # Automatically removing tmpdir sounds convenient, but could
+            # really annoy anyone in the habit of using "--tmpdir=/tmp"
+            # or "--tmpdir=$HOME".
+            #vlog("# Removing temp dir", tmpdir)
+            #shutil.rmtree(tmpdir)
+        os.makedirs(tmpdir)
+    else:
+        tmpdir = tempfile.mkdtemp('', 'hgtests.')
+    HGTMP = os.environ['HGTMP'] = os.path.realpath(tmpdir)
     DAEMON_PIDS = None
     HGRCPATH = None
 
--- a/tests/test-archive.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-archive.out	Sat Nov 07 14:13:15 2009 -0600
@@ -5,20 +5,20 @@
 % gz allowed should give 200
 200 Script output follows
 % tar.bz2 and zip disallowed should both give 403
-403 Forbidden
-403 Forbidden
+403 Archive type not allowed: bz2
+403 Archive type not allowed: zip
 % bz2 allowed should give 200
 200 Script output follows
 % zip and tar.gz disallowed should both give 403
-403 Forbidden
-403 Forbidden
+403 Archive type not allowed: zip
+403 Archive type not allowed: gz
 % zip allowed should give 200
 200 Script output follows
 % tar.gz and tar.bz2 disallowed should both give 403
-403 Forbidden
-403 Forbidden
+403 Archive type not allowed: gz
+403 Archive type not allowed: bz2
 % invalid arch type should give 404
-404 Not Found
+404 Unsupported archive type: None
 
 test-archive-TIP/.hg_archival.txt
 test-archive-TIP/bar
--- a/tests/test-bisect	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-bisect	Sat Nov 07 14:13:15 2009 -0600
@@ -87,7 +87,7 @@
 
 echo % test invalid command
 hg bisect -r
-hg bisect --command 'foobar'
+hg bisect --command './foobar' 2>&1 | sed 's|\(/bin/sh: \./foobar:\).*|\1 not found|'
 
 echo % test bisecting command
 cat > script.py <<EOF
--- a/tests/test-bisect.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-bisect.out	Sat Nov 07 14:13:15 2009 -0600
@@ -304,8 +304,8 @@
 summary:     msg 6
 
 % test invalid command
-/bin/sh: foobar: command not found
-abort: failed to execute foobar
+/bin/sh: ./foobar: not found
+abort: failed to execute ./foobar
 % test bisecting command
 Testing changeset 15:e7fa0811edb0 (31 changesets remaining, ~4 tests)
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branchmap	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+hgserve()
+{
+    hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@ \
+        | sed -e 's/:[0-9][0-9]*//g' -e 's/http:\/\/[^/]*\//http:\/\/localhost\//'
+    cat hg.pid >> "$DAEMON_PIDS"
+}
+
+hg init a
+hg --encoding utf-8 -R a branch æ
+echo foo > a/foo
+hg -R a ci -Am foo
+
+hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
+hg clone http://localhost:$HGPORT1 b
+hg --encoding utf-8 -R b log
+echo bar >> b/foo
+hg -R b ci -m bar
+hg --encoding utf-8 -R b push | sed "s/$HGPORT1/PORT/"
+hg -R a --encoding utf-8 log
+
+kill `cat hg.pid`
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-branchmap.out	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,36 @@
+marked working directory as branch æ
+adding foo
+listening at http://localhost/ (bound to 127.0.0.1)
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+updating working directory
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+changeset:   0:867c11ce77b8
+branch:      æ
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     foo
+
+pushing to http://localhost:PORT
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+changeset:   1:58e7c90d67cb
+branch:      æ
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     bar
+
+changeset:   0:867c11ce77b8
+branch:      æ
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     foo
+
--- a/tests/test-churn	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-churn	Sat Nov 07 14:13:15 2009 -0600
@@ -50,6 +50,14 @@
 echo % churn by hour
 hg churn -f '%H' -s
 
+echo % churn with separated added/removed lines
+hg rm d/g/f2.txt
+hg ci -Am "removed d/g/f2.txt" -u user1 -d 14:00 d/g/f2.txt
+hg churn --diffstat
+
+echo % changeset number churn
+hg churn -c
+
 cd ..
 
 # issue 833: ZeroDivisionError
--- a/tests/test-churn.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-churn.out	Sat Nov 07 14:13:15 2009 -0600
@@ -10,7 +10,7 @@
 user2      2 ******************************************
 % churn up to rev 2
 user2      2 ***************************************************************
-user1      1 *******************************
+user1      1 ********************************
 % churn with aliases
 alias3      3 **************************************************************
 alias1      3 **************************************************************
@@ -24,9 +24,17 @@
 user1      3 ***********************
 user2      2 ***************
 % churn by hour
-06      1 ****************
+06      1 *****************
 09      2 *********************************
 12      4 ******************************************************************
-13      1 ****************
+13      1 *****************
+% churn with separated added/removed lines
+user1           +3/-1 +++++++++++++++++++++++++++++++++++++++++--------------
+user3           +3/-0 +++++++++++++++++++++++++++++++++++++++++
+user2           +2/-0 +++++++++++++++++++++++++++
+% changeset number churn
+user1      4 ***************************************************************
+user3      3 ***********************************************
+user2      2 ********************************
 adding foo
 test      0 
--- a/tests/test-clone	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-clone	Sat Nov 07 14:13:15 2009 -0600
@@ -67,4 +67,136 @@
 hg clone ../a .
 cd ..
 
+echo
+echo
+echo % "*** tests for option -u ***"
+echo
+
+
+echo
+echo % "adding some more history to repo a"
+cd a
+echo % "tag ref1"
+hg tag ref1
+echo the quick brown fox >a
+hg ci -m "hacked default"
+echo % "updating back to ref1"
+hg up ref1
+echo
+echo % "add branch 'stable' to repo a for later tests"
+hg branch stable
+echo some text >a
+hg ci -m "starting branch stable"
+echo % "tag ref2"
+hg tag ref2
+echo some more text >a
+hg ci -m "another change for branch stable"
+echo
+echo % "updating back to ref2"
+hg up ref2
+echo
+echo % "parents of repo a"
+hg parents
+echo
+echo % "repo a has two heads"
+hg heads
+cd ..
+
+echo
+echo % "testing clone -U -u 1 a ua (must abort)"
+hg clone -U -u 1 a ua
+
+echo
+echo % "testing clone -u . a ua"
+hg clone -u . a ua
+echo
+echo % "repo ua has both heads"
+hg -R ua heads
+echo
+echo % "same revision checked out in repo a and ua"
+hg -R a parents --template "{node|short}\n"
+hg -R ua parents --template "{node|short}\n"
+rm -r ua
+
+echo
+echo % "testing clone --pull -u . a ua"
+hg clone --pull -u . a ua
+echo
+echo % "repo ua has both heads"
+hg -R ua heads
+echo
+echo % "same revision checked out in repo a and ua"
+hg -R a parents --template "{node|short}\n"
+hg -R ua parents --template "{node|short}\n"
+rm -r ua
+
+echo
+echo % "testing clone -u stable a ua"
+hg clone -u stable a ua
+echo
+echo % "repo ua has both heads"
+hg -R ua heads
+echo
+echo % "branch stable is checked out"
+hg -R ua parents
+rm -r ua
+
+echo
+echo % "testing clone a ua"
+hg clone a ua
+echo
+echo % "repo ua has both heads"
+hg -R ua heads
+echo
+echo % "branch default is checked out"
+hg -R ua parents
+rm -r ua
+
+echo
+echo % "testing clone -u . a#stable ua"
+hg clone -u . a#stable ua
+echo
+echo % "repo ua has only branch stable"
+hg -R ua heads
+echo
+echo % "same revision checked out in repo a and ua"
+hg -R a parents --template "{node|short}\n"
+hg -R ua parents --template "{node|short}\n"
+rm -r ua
+
+echo
+echo % "testing clone -u . -r stable a ua"
+hg clone -u . -r stable a ua
+echo
+echo % "repo ua has only branch stable"
+hg -R ua heads
+echo
+echo % "same revision checked out in repo a and ua"
+hg -R a parents --template "{node|short}\n"
+hg -R ua parents --template "{node|short}\n"
+rm -r ua
+
+echo
+echo % "testing clone -r stable a ua"
+hg clone -r stable a ua
+echo
+echo % "repo ua has only branch stable"
+hg -R ua heads
+echo
+echo % "branch stable is checked out"
+hg -R ua parents
+rm -r ua
+
+echo
+echo % "testing clone -u . -r stable -r default a ua"
+hg clone -u . -r stable -r default a ua
+echo
+echo % "repo ua has two heads"
+hg -R ua heads
+echo
+echo % "same revision checked out in repo a and ua"
+hg -R a parents --template "{node|short}\n"
+hg -R ua parents --template "{node|short}\n"
+rm -r ua
+
 exit 0
--- a/tests/test-clone.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-clone.out	Sat Nov 07 14:13:15 2009 -0600
@@ -54,3 +54,246 @@
 % clone to .
 updating to branch default
 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+% *** tests for option -u ***
+
+
+% adding some more history to repo a
+% tag ref1
+% updating back to ref1
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+% add branch 'stable' to repo a for later tests
+marked working directory as branch stable
+created new head
+% tag ref2
+
+% updating back to ref2
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+% parents of repo a
+changeset:   13:e8ece76546a6
+branch:      stable
+tag:         ref2
+parent:      10:a7949464abda
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     starting branch stable
+
+
+% repo a has two heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% testing clone -U -u 1 a ua (must abort)
+abort: cannot specify both --noupdate and --updaterev
+
+% testing clone -u . a ua
+updating to branch stable
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has both heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% same revision checked out in repo a and ua
+e8ece76546a6
+e8ece76546a6
+
+% testing clone --pull -u . a ua
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 16 changesets with 16 changes to 3 files (+1 heads)
+updating to branch stable
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has both heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% same revision checked out in repo a and ua
+e8ece76546a6
+e8ece76546a6
+
+% testing clone -u stable a ua
+updating to branch stable
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has both heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% branch stable is checked out
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+
+% testing clone a ua
+updating to branch default
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has both heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% branch default is checked out
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% testing clone -u . a#stable ua
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 14 changesets with 14 changes to 3 files
+updating to branch stable
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has only branch stable
+changeset:   13:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+
+% same revision checked out in repo a and ua
+e8ece76546a6
+e8ece76546a6
+
+% testing clone -u . -r stable a ua
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 14 changesets with 14 changes to 3 files
+updating to branch stable
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has only branch stable
+changeset:   13:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+
+% same revision checked out in repo a and ua
+e8ece76546a6
+e8ece76546a6
+
+% testing clone -r stable a ua
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 14 changesets with 14 changes to 3 files
+updating to branch stable
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has only branch stable
+changeset:   13:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+
+% branch stable is checked out
+changeset:   13:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+
+% testing clone -u . -r stable -r default a ua
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 16 changesets with 16 changes to 3 files (+1 heads)
+updating to branch stable
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+% repo ua has two heads
+changeset:   15:0aae7cf88f0d
+branch:      stable
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     another change for branch stable
+
+changeset:   12:f21241060d6a
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     hacked default
+
+
+% same revision checked out in repo a and ua
+e8ece76546a6
+e8ece76546a6
--- a/tests/test-debugcomplete.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-debugcomplete.out	Sat Nov 07 14:13:15 2009 -0600
@@ -165,9 +165,9 @@
 % Show all commands + options
 add: include, exclude, dry-run
 annotate: rev, follow, text, user, date, number, changeset, line-number, include, exclude
-clone: noupdate, rev, pull, uncompressed, ssh, remotecmd
+clone: noupdate, updaterev, rev, pull, uncompressed, ssh, remotecmd
 commit: addremove, close-branch, include, exclude, message, logfile, date, user
-diff: rev, change, text, git, nodates, show-function, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude
+diff: rev, change, text, git, nodates, show-function, inverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude
 export: output, switch-parent, text, git, nodates
 forget: include, exclude
 init: ssh, remotecmd
--- a/tests/test-diff-color	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-diff-color	Sat Nov 07 14:13:15 2009 -0600
@@ -51,3 +51,14 @@
 y
 EOF
 echo
+
+echo "[extensions]" >> $HGRCPATH
+echo "mq=" >> $HGRCPATH
+
+hg rollback
+echo % qrecord
+hg qrecord --color=always -m moda patch <<EOF
+y
+y
+EOF
+echo
--- a/tests/test-diff-color.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-diff-color.out	Sat Nov 07 14:13:15 2009 -0600
@@ -41,3 +41,19 @@
  a
  c
 record this change to 'a'? [Ynsfdaq?] 
+rolling back last transaction
+% qrecord
+diff --git a/a b/a
+old mode 100644
+new mode 100755
+1 hunks, 2 lines changed
+examine changes to 'a'? [Ynsfdaq?] @@ -2,7 +2,7 @@
+ c
+ a
+ a
+-b
++dd
+ a
+ a
+ c
+record this change to 'a'? [Ynsfdaq?] 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-diff-inverse	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+hg init
+cat > a <<EOF
+a
+b
+c
+EOF
+hg ci -Am adda
+
+cat > a <<EOF
+d
+e
+f
+EOF
+hg ci -m moda
+
+hg diff --inverse -r0 -r1
+
+cat >> a <<EOF
+g
+h
+EOF
+hg diff --inverse --nodates
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-diff-inverse.out	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,20 @@
+adding a
+diff -r 2855cdcfcbb7 -r 8e1805a3cf6e a
+--- a/a	Thu Jan 01 00:00:00 1970 +0000
++++ b/a	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,3 +1,3 @@
+-d
+-e
+-f
++a
++b
++c
+diff -r 2855cdcfcbb7 a
+--- a/a
++++ b/a
+@@ -1,5 +1,3 @@
+ d
+ e
+ f
+-g
+-h
--- a/tests/test-extension	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-extension	Sat Nov 07 14:13:15 2009 -0600
@@ -75,6 +75,20 @@
 # command with no output, we just want to see the extensions loaded
 hg paths
 
+# check hgweb's load order
+echo '% hgweb.cgi'
+cat > hgweb.cgi <<EOF
+#!/usr/bin/env python
+from mercurial import demandimport; demandimport.enable()
+from mercurial.hgweb import hgweb
+from mercurial.hgweb import wsgicgi
+
+application = hgweb('.', 'test repo')
+wsgicgi.launch(application)
+EOF
+SCRIPT_NAME='/' SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
+    | grep '^[[:digit:]]) [[:alnum:] ]*$'  # ignores HTML output
+
 echo 'foo = !' >> $HGRCPATH
 echo 'bar = !' >> $HGRCPATH
 
--- a/tests/test-extension.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-extension.out	Sat Nov 07 14:13:15 2009 -0600
@@ -24,6 +24,17 @@
 3) bar extsetup
 4) foo reposetup
 4) bar reposetup
+% hgweb.cgi
+1) foo imported
+1) bar imported
+2) foo uisetup
+2) bar uisetup
+3) foo extsetup
+3) bar extsetup
+4) foo reposetup
+4) bar reposetup
+4) foo reposetup
+4) bar reposetup
 empty extension - empty cmdtable
 
 no commands defined
@@ -54,7 +65,7 @@
     --debugger        start debugger
     --encoding        set the charset encoding (default: ascii)
     --encodingmode    set the charset encoding mode (default: strict)
-    --traceback       print traceback on exception
+    --traceback       always print a traceback on exception
     --time            time how long the command takes
     --profile         print command execution profile
     --version         output version information and exit
@@ -84,7 +95,7 @@
     --debugger        start debugger
     --encoding        set the charset encoding (default: ascii)
     --encodingmode    set the charset encoding mode (default: strict)
-    --traceback       print traceback on exception
+    --traceback       always print a traceback on exception
     --time            time how long the command takes
     --profile         print command execution profile
     --version         output version information and exit
--- a/tests/test-glog	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-glog	Sat Nov 07 14:13:15 2009 -0600
@@ -165,6 +165,9 @@
 hg commit -mmore
 hg glog two
 
+echo "% file log with explicit style (issue 1896)"
+hg glog --style=default one
+
 echo % incoming and outgoing
 cd ..
 hg clone -U -r31 repo repo2
--- a/tests/test-glog.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-glog.out	Sat Nov 07 14:13:15 2009 -0600
@@ -575,6 +575,12 @@
    date:        Thu Jan 01 00:00:00 1970 +0000
    summary:     two
 
+% file log with explicit style (issue 1896)
+o  changeset:   0:3d578b4a1f53
+   user:        test
+   date:        Thu Jan 01 00:00:00 1970 +0000
+   summary:     one
+
 % incoming and outgoing
 requesting all changes
 adding changesets
--- a/tests/test-help.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-help.out	Sat Nov 07 14:13:15 2009 -0600
@@ -237,6 +237,7 @@
  -g --git                  use git extended diff format
     --nodates              don't include dates in diff headers
  -p --show-function        show which function each change is in
+    --inverse              produce a diff that undoes the changes
  -w --ignore-all-space     ignore white space when comparing lines
  -b --ignore-space-change  ignore changes in the amount of white space
  -B --ignore-blank-lines   ignore changes whose lines are all blank
--- a/tests/test-hgweb-commands.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgweb-commands.out	Sat Nov 07 14:13:15 2009 -0600
@@ -210,17 +210,17 @@
   <th class="description">description</th>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> </td>
  </tr>
  <tr class="parity1">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> </td>
  </tr>
@@ -291,7 +291,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author"></td>
@@ -394,6 +394,7 @@
 </ul>
 <ul>
 <li class="active">file</li>
+<li><a href="/file/tip/foo">latest</a></li>
 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
@@ -421,7 +422,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th class="author">parents</th>
@@ -522,7 +523,7 @@
 <table cellspacing="0">
 
 <tr class="parity0">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
 <td class="open">stable</td>
 <td class="link">
@@ -532,7 +533,7 @@
 </td>
 </tr>
 <tr class="parity1">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
 <td class="inactive">default</td>
 <td class="link">
@@ -607,7 +608,7 @@
 <table cellspacing="0">
 
 <tr class="parity0">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><i>test</i></td>
 <td>
 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
@@ -621,7 +622,7 @@
 </td>
 </tr>
 <tr class="parity1">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><i>test</i></td>
 <td>
 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
@@ -635,7 +636,7 @@
 </td>
 </tr>
 <tr class="parity0">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><i>test</i></td>
 <td>
 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
@@ -655,7 +656,7 @@
 <table cellspacing="0">
 
 <tr class="parity0">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
 <td class="link">
 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
@@ -670,7 +671,7 @@
 <table cellspacing="0">
 
 <tr class="parity0">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
 <td class="">stable</td>
 <td class="link">
@@ -680,7 +681,7 @@
 </td>
 </tr>
 <tr class="parity1">
-<td class="age"><i>many years ago</i></td>
+<td class="age"><i>1970-01-01</i></td>
 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
 <td class="">default</td>
 <td class="link">
@@ -763,7 +764,7 @@
 <script>
 <!-- hide script content
 
-var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "many years", ["stable", true], ["tip"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "many years", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "many years", ["default", false], ["1.0"]]];
+var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"]]];
 var graph = new Graph();
 graph.scale(39);
 
@@ -875,7 +876,7 @@
 
 1
 % failing unbundle, requires POST request
-405 Method Not Allowed
+405 push requires POST request
 
 0
 push requires POST request
--- a/tests/test-hgweb-diffs	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgweb-diffs	Sat Nov 07 14:13:15 2009 -0600
@@ -38,5 +38,11 @@
 echo % diff removed file
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/a'
 
+cd ..
+echo % test import rev as raw-rev
+hg clone -r0 test test1
+cd test1
+hg import -q --exact http://localhost:$HGPORT/rev/1
+
 echo % errors
-cat errors.log
+cat ../test/errors.log
--- a/tests/test-hgweb-diffs.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgweb-diffs.out	Sat Nov 07 14:13:15 2009 -0600
@@ -59,7 +59,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author"></td>
@@ -149,6 +149,7 @@
 </ul>
 <ul>
 <li><a href="/file/78e4ebad7cdf/a">file</a></li>
+<li><a href="/file/tip/a">latest</a></li>
 <li class="active">diff</li>
 <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li>
 <li><a href="/log/78e4ebad7cdf/a">file log</a></li>
@@ -176,7 +177,7 @@
 </tr>
 <tr>
  <th>date</th>
- <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th>parents</th>
@@ -263,7 +264,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author"></td>
@@ -357,6 +358,7 @@
 </ul>
 <ul>
 <li><a href="/file/78e4ebad7cdf/a">file</a></li>
+<li><a href="/file/tip/a">latest</a></li>
 <li class="active">diff</li>
 <li><a href="/annotate/78e4ebad7cdf/a">annotate</a></li>
 <li><a href="/log/78e4ebad7cdf/a">file log</a></li>
@@ -384,7 +386,7 @@
 </tr>
 <tr>
  <th>date</th>
- <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th>parents</th>
@@ -415,4 +417,12 @@
 </body>
 </html>
 
+% test import rev as raw-rev
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 2 changes to 2 files
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 % errors
--- a/tests/test-hgweb-filelog.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgweb-filelog.out	Sat Nov 07 14:13:15 2009 -0600
@@ -148,12 +148,12 @@
   <th class="description">description</th>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/01de2d66a28d">second a</a></td>
  </tr>
  <tr class="parity1">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/5ed941583260">first a</a></td>
  </tr>
@@ -231,12 +231,12 @@
   <th class="description">description</th>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/01de2d66a28d">second a</a></td>
  </tr>
  <tr class="parity1">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/5ed941583260">first a</a></td>
  </tr>
@@ -314,7 +314,7 @@
   <th class="description">description</th>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/5ed941583260">first a</a></td>
  </tr>
@@ -392,7 +392,7 @@
   <th class="description">description</th>
  </tr>
  <tr class="parity0">
-  <td class="age">many years</td>
+  <td class="age">1970-01-01</td>
   <td class="author">test</td>
   <td class="description"><a href="/rev/5ed941583260">first a</a></td>
  </tr>
@@ -499,7 +499,7 @@
 
 <table class="logEntry parity0">
  <tr>
-  <th class="age">many years ago:</th>
+  <th class="age">1970-01-01:</th>
   <th class="firstline"><a href="/rev/38d962e6234d?style=spartan">change c</a></th>
  </tr>
  <tr>
@@ -524,7 +524,7 @@
 
 <table class="logEntry parity1">
  <tr>
-  <th class="age">many years ago:</th>
+  <th class="age">1970-01-01:</th>
   <th class="firstline"><a href="/rev/a3b6a9e4507e?style=spartan">mv b</a></th>
  </tr>
  <tr>
--- a/tests/test-hgweb-removed.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgweb-removed.out	Sat Nov 07 14:13:15 2009 -0600
@@ -57,7 +57,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td></tr>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td></tr>
 <tr>
  <th class="author">parents</th>
  <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
@@ -121,6 +121,7 @@
 </ul>
 <ul>
 <li><a href="/file/c78f6c5cbea9/a">file</a></li>
+<li><a href="/file/tip/a">latest</a></li>
 <li class="active">diff</li>
 <li><a href="/annotate/c78f6c5cbea9/a">annotate</a></li>
 <li><a href="/log/c78f6c5cbea9/a">file log</a></li>
@@ -148,7 +149,7 @@
 </tr>
 <tr>
  <th>date</th>
- <td>Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td>Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th>parents</th>
--- a/tests/test-hgwebdir.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-hgwebdir.out	Sat Nov 07 14:13:15 2009 -0600
@@ -29,6 +29,7 @@
 200 Script output follows
 
 
+/t/a/
 /b/
 /coll/a/
 /coll/a/.hg/patches/
@@ -39,7 +40,6 @@
 /rcoll/b/
 /rcoll/b/d/
 /rcoll/c/
-/t/a/
 
 200 Script output follows
 
@@ -64,7 +64,7 @@
 
 <table class="bigtable">
     <tr>
-        <th><a href="?sort=-name">Name</a></th>
+        <th><a href="?sort=name">Name</a></th>
         <th><a href="?sort=description">Description</a></th>
         <th><a href="?sort=contact">Contact</a></th>
         <th><a href="?sort=lastchange">Last change</a></th>
@@ -72,7 +72,7 @@
     </tr>
     
 <tr class="parity0">
-<td><a href="/b/?style=paper">b</a></td>
+<td><a href="/t/a/?style=paper">t/a</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -80,7 +80,7 @@
 </tr>
 
 <tr class="parity1">
-<td><a href="/coll/a/?style=paper">coll/a</a></td>
+<td><a href="/b/?style=paper">b</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -88,7 +88,7 @@
 </tr>
 
 <tr class="parity0">
-<td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td>
+<td><a href="/coll/a/?style=paper">coll/a</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -96,7 +96,7 @@
 </tr>
 
 <tr class="parity1">
-<td><a href="/coll/b/?style=paper">coll/b</a></td>
+<td><a href="/coll/a/.hg/patches/?style=paper">coll/a/.hg/patches</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -104,7 +104,7 @@
 </tr>
 
 <tr class="parity0">
-<td><a href="/coll/c/?style=paper">coll/c</a></td>
+<td><a href="/coll/b/?style=paper">coll/b</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -112,7 +112,7 @@
 </tr>
 
 <tr class="parity1">
-<td><a href="/rcoll/a/?style=paper">rcoll/a</a></td>
+<td><a href="/coll/c/?style=paper">coll/c</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -120,7 +120,7 @@
 </tr>
 
 <tr class="parity0">
-<td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td>
+<td><a href="/rcoll/a/?style=paper">rcoll/a</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -128,7 +128,7 @@
 </tr>
 
 <tr class="parity1">
-<td><a href="/rcoll/b/?style=paper">rcoll/b</a></td>
+<td><a href="/rcoll/a/.hg/patches/?style=paper">rcoll/a/.hg/patches</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -136,7 +136,7 @@
 </tr>
 
 <tr class="parity0">
-<td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td>
+<td><a href="/rcoll/b/?style=paper">rcoll/b</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -144,7 +144,7 @@
 </tr>
 
 <tr class="parity1">
-<td><a href="/rcoll/c/?style=paper">rcoll/c</a></td>
+<td><a href="/rcoll/b/d/?style=paper">rcoll/b/d</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -152,7 +152,7 @@
 </tr>
 
 <tr class="parity0">
-<td><a href="/t/a/?style=paper">t/a</a></td>
+<td><a href="/rcoll/c/?style=paper">rcoll/c</a></td>
 <td>unknown</td>
 <td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td>
 <td class="age">seconds ago</td>
@@ -200,7 +200,7 @@
 
 <table class="bigtable">
     <tr>
-        <th><a href="?sort=-name">Name</a></th>
+        <th><a href="?sort=name">Name</a></th>
         <th><a href="?sort=description">Description</a></th>
         <th><a href="?sort=contact">Contact</a></th>
         <th><a href="?sort=lastchange">Last change</a></th>
--- a/tests/test-highlight.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-highlight.out	Sat Nov 07 14:13:15 2009 -0600
@@ -33,6 +33,7 @@
 </ul>
 <ul>
 <li class="active">file</li>
+<li><a href="/file/tip/primes.py">latest</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>
@@ -60,7 +61,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th class="author">parents</th>
@@ -152,6 +153,7 @@
 </ul>
 <ul>
 <li><a href="/file/853dcd4de2a6/primes.py">file</a></li>
+<li><a href="/file/tip/primes.py">latest</a></li>
 <li><a href="/diff/853dcd4de2a6/primes.py">diff</a></li>
 <li class="active">annotate</li>
 <li><a href="/log/853dcd4de2a6/primes.py">file log</a></li>
@@ -179,7 +181,7 @@
 </tr>
 <tr>
  <th class="date">date</th>
- <td class="date">Thu Jan 01 00:00:00 1970 +0000 (many years ago)</td>
+ <td class="date">Thu Jan 01 00:00:00 1970 +0000 (1970-01-01)</td>
 </tr>
 <tr>
  <th class="author">parents</th>
--- a/tests/test-install	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-install	Sat Nov 07 14:13:15 2009 -0600
@@ -1,3 +1,10 @@
 #!/bin/sh
 
+echo '% hg debuginstall'
 hg debuginstall
+
+echo '% hg debuginstall with no username'
+HGUSER= hg debuginstall
+
+# Happy End
+true
--- a/tests/test-install.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-install.out	Sat Nov 07 14:13:15 2009 -0600
@@ -1,3 +1,4 @@
+% hg debuginstall
 Checking encoding (ascii)...
 Checking extensions...
 Checking templates...
@@ -5,3 +6,13 @@
 Checking commit editor...
 Checking username...
 No problems detected
+% hg debuginstall with no username
+Checking encoding (ascii)...
+Checking extensions...
+Checking templates...
+Checking patch...
+Checking commit editor...
+Checking username...
+ Please specify a username.
+ (specify a username in your .hgrc file)
+1 problems detected, please check your install!
--- a/tests/test-journal-exists	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-journal-exists	Sat Nov 07 14:13:15 2009 -0600
@@ -3,6 +3,7 @@
 hg init
 echo a > a
 hg ci -Am0
+hg -q clone . foo
 
 touch .hg/store/journal
 
@@ -10,3 +11,10 @@
 hg ci -Am0
 
 hg recover
+
+echo % check that zero-size journals are correctly aborted
+hg bundle -qa repo.hg
+chmod -w foo/.hg/store/00changelog.i
+hg -R foo unbundle repo.hg 2>&1 | sed 's/\(abort: Permission denied\).*/\1/'
+if test -f foo/.hg/store/journal; then echo 'journal exists :-('; fi
+exit 0
--- a/tests/test-journal-exists.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-journal-exists.out	Sat Nov 07 14:13:15 2009 -0600
@@ -1,8 +1,11 @@
 adding a
-abort: journal already exists - run hg recover!
+abort: abandoned transaction found - run hg recover!
 rolling back interrupted transaction
 checking changesets
 checking manifests
 crosschecking files in changesets and manifests
 checking files
 1 files, 1 changesets, 1 total revisions
+% check that zero-size journals are correctly aborted
+adding changesets
+abort: Permission denied
--- a/tests/test-merge5.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-merge5.out	Sat Nov 07 14:13:15 2009 -0600
@@ -2,6 +2,6 @@
 removing b
 created new head
 % should abort
-abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
+abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes)
 % should succeed
-abort: crosses branches (use 'hg merge' or 'hg update -C')
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-minirst.py	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-minirst.py	Sat Nov 07 14:13:15 2009 -0600
@@ -12,28 +12,13 @@
 paragraphs = """
 This is some text in the first paragraph.
 
-  An indented paragraph
-  with just two lines.
-
-
-The third paragraph. It is followed by some
-random lines with spurious spaces.
+  A small indented paragraph.
+  It is followed by some lines
+  containing random whitespace.
  
   
    
-  
- 
-No indention
- here, despite
-the uneven left
- margin.
-
-      Only the
-    left-most line
-  (this line!)
-    is significant
-      for the indentation
-
+The third and final paragraph.
 """
 
 debugformat('paragraphs', paragraphs, 60)
@@ -108,6 +93,15 @@
 
   Literal block with no indentation (apart from
   the two spaces added to all literal blocks).
+
+1. This is an enumerated list (first item).
+2. Continuing with the second item.
+
+(1) foo
+(2) bar
+
+1) Another
+2) List
 """
 
 debugformat('lists', lists, 60)
--- a/tests/test-minirst.py.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-minirst.py.out	Sat Nov 07 14:13:15 2009 -0600
@@ -2,15 +2,10 @@
 ----------------------------------------------------------------------
 This is some text in the first paragraph.
 
-  An indented paragraph with just two lines.
-
-The third paragraph. It is followed by some random lines
-with spurious spaces.
+  A small indented paragraph. It is followed by some lines
+  containing random whitespace.
 
-No indention here, despite the uneven left margin.
-
-  Only the left-most line (this line!) is significant for
-  the indentation
+The third and final paragraph.
 ----------------------------------------------------------------------
 
 paragraphs formatted to fit within 30 characters:
@@ -18,19 +13,12 @@
 This is some text in the first
 paragraph.
 
-  An indented paragraph with
-  just two lines.
-
-The third paragraph. It is
-followed by some random lines
-with spurious spaces.
+  A small indented paragraph.
+  It is followed by some lines
+  containing random
+  whitespace.
 
-No indention here, despite the
-uneven left margin.
-
-  Only the left-most line
-  (this line!) is significant
-  for the indentation
+The third and final paragraph.
 ----------------------------------------------------------------------
 
 definitions formatted to fit within 60 characters:
@@ -125,6 +113,13 @@
 
   Literal block with no indentation (apart from
   the two spaces added to all literal blocks).
+
+1. This is an enumerated list (first item).
+2. Continuing with the second item.
+(1) foo
+(2) bar
+1) Another
+2) List
 ----------------------------------------------------------------------
 
 lists formatted to fit within 30 characters:
@@ -153,6 +148,15 @@
 
   Literal block with no indentation (apart from
   the two spaces added to all literal blocks).
+
+1. This is an enumerated list
+   (first item).
+2. Continuing with the second
+   item.
+(1) foo
+(2) bar
+1) Another
+2) List
 ----------------------------------------------------------------------
 
 options formatted to fit within 60 characters:
--- a/tests/test-mq-qdiff	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-mq-qdiff	Sat Nov 07 14:13:15 2009 -0600
@@ -55,5 +55,8 @@
 echo % qdiff -U 1 -B
 hg qdiff --nodates -U 1 -B
 
-echo qdiff -w
+echo % qdiff -w
 hg qdiff --nodates -w
+
+echo % qdiff --inverse
+hg qdiff --nodates --inverse
--- a/tests/test-mq-qdiff.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-mq-qdiff.out	Sat Nov 07 14:13:15 2009 -0600
@@ -76,7 +76,7 @@
 +hello  world
 +     goodbye world
  7
-qdiff -w
+% qdiff -w
 diff -r 35fb829491c1 lines
 --- a/lines
 +++ b/lines
@@ -86,3 +86,21 @@
  1
  2
  3
+% qdiff --inverse
+diff -r 35fb829491c1 lines
+--- a/lines
++++ b/lines
+@@ -1,11 +1,9 @@
+-
+-
+ 1
+ 2
+ 3
+ 4
+-hello  world
+-     goodbye world
++hello world
++goodbye world
+ 7
+ 8
+ 9
--- a/tests/test-mq-qnew	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-mq-qnew	Sat Nov 07 14:13:15 2009 -0600
@@ -54,3 +54,7 @@
 hg st
 hg qnew -g -f p
 cat ../.hg/patches/p
+
+echo '% qnew -u with no username configured'
+HGUSER= hg qnew -u blue red
+cat ../.hg/patches/red
--- a/tests/test-mq-qnew.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-mq-qnew.out	Sat Nov 07 14:13:15 2009 -0600
@@ -32,3 +32,6 @@
 @@ -1,1 +1,2 @@
  b
 +b
+% qnew -u with no username configured
+From: blue
+
--- a/tests/test-patchbomb	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-patchbomb	Sat Nov 07 14:13:15 2009 -0600
@@ -170,3 +170,10 @@
 echo "% test multiple flags for multiple patches"
 hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
  -c bar -s test -r 0:1 | fixheaders
+
+echo "% test multi-byte domain parsing"
+UUML=`printf '\374'`
+export HGENCODING=iso-8859-1
+hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t "bar@${UUML}nicode.com" \
+  -s test -r 0
+cat tmp.mbox | fixheaders
--- a/tests/test-patchbomb.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-patchbomb.out	Sat Nov 07 14:13:15 2009 -0600
@@ -1469,3 +1469,34 @@
 @@ -0,0 +1,1 @@
 +b
 
+% test multi-byte domain parsing
+This patch series consists of 1 patches.
+
+
+Writing [PATCH] test ...
+From quux Tue Jan  1 00:01:01 1980
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH] test
+X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
+Message-Id: <8580ff50825a50c8f716.315532860@
+User-Agent: Mercurial-patchbomb
+Date: Tue, 01 Jan 1980 00:01:00 +0000
+From: quux
+To: bar@xn--nicode-2ya.com
+
+# HG changeset patch
+# User test
+# Date 1 0
+# Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
+# Parent  0000000000000000000000000000000000000000
+a
+
+diff -r 000000000000 -r 8580ff50825a a
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/a	Thu Jan 01 00:00:01 1970 +0000
+@@ -0,0 +1,1 @@
++a
+
+
--- a/tests/test-repair-strip.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-repair-strip.out	Sat Nov 07 14:13:15 2009 -0600
@@ -10,6 +10,7 @@
 rollback failed - please run hg recover
 abort: Permission denied .hg/store/data/b.i
 % after update 0, strip 2
+abandoned transaction found - run hg recover
 checking changesets
 checking manifests
 crosschecking files in changesets and manifests
@@ -59,6 +60,7 @@
 rollback failed - please run hg recover
 abort: Permission denied .hg/store/00manifest.i
 % after update 0, strip 2
+abandoned transaction found - run hg recover
 checking changesets
 checking manifests
  manifest@?: rev 2 points to nonexistent changeset 2
--- a/tests/test-up-local-change.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-up-local-change.out	Sat Nov 07 14:13:15 2009 -0600
@@ -111,7 +111,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     2
 
-abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
+abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes)
 failed
 abort: outstanding uncommitted changes (use 'hg status' to list changes)
 failed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-update-branches	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+# Construct the following history tree:
+#
+# @  5:e1bb631146ca  b1
+# |
+# o  4:a4fdb3b883c4 0:b608b9236435  b1
+# |
+# | o  3:4b57d2520816 1:44592833ba9f
+# | |
+# | | o  2:063f31070f65
+# | |/
+# | o  1:44592833ba9f
+# |/
+# o  0:b608b9236435
+
+hg init
+echo foo > foo
+echo zero > a
+hg ci -qAm0
+echo one > a ; hg ci -m1
+echo two > a ; hg ci -m2
+hg up -q 1
+echo three > a ; hg ci -qm3
+hg up -q 0
+hg branch -q b1
+echo four > a ; hg ci -qm4
+echo five > a ; hg ci -qm5
+
+echo % initial repo state
+echo
+hg --config 'extensions.graphlog=' \
+    glog --template '{rev}:{node|short} {parents} {branches}\n'
+
+# Test helper functions.
+
+revtest () {
+    msg=$1
+    dirtyflag=$2   # 'clean' or 'dirty'
+    startrev=$3
+    targetrev=$4
+    opt=$5
+    echo % revtest $msg $startrev $targetrev
+    hg up -qC $startrev
+    test $dirtyflag = dirty && echo dirty > foo
+    hg up $opt $targetrev
+    hg parent --template 'parent={rev}\n'
+    hg stat
+}    
+
+norevtest () {
+    msg=$1
+    dirtyflag=$2   # 'clean' or 'dirty'
+    startrev=$3
+    opt=$4
+    echo % norevtest $msg $startrev
+    hg up -qC $startrev
+    test $dirtyflag = dirty && echo dirty > foo
+    hg up $opt
+    hg parent --template 'parent={rev}\n'
+    hg stat
+}    
+
+# Test cases are documented in a table in the update function of merge.py.
+# Cases are run as shown in that table, row by row.
+
+norevtest 'none clean linear' clean 4
+norevtest 'none clean same'   clean 2
+
+revtest 'none clean linear' clean 1 2
+revtest 'none clean same'   clean 2 3
+revtest 'none clean cross'  clean 3 4
+
+revtest 'none dirty linear' dirty 1 2
+revtest 'none dirty same'   dirty 2 3
+revtest 'none dirty cross'  dirty 3 4
+
+revtest '-C dirty linear'   dirty 1 2 -C
+revtest '-c dirty linear'   dirty 1 2 -c
+norevtest '-c clean same'   clean 2 -c
+revtest '-cC dirty linear'  dirty 1 2 -cC
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-update-branches.out	Sat Nov 07 14:13:15 2009 -0600
@@ -0,0 +1,55 @@
+% initial repo state
+
+@  5:e1bb631146ca  b1
+|
+o  4:a4fdb3b883c4 0:b608b9236435  b1
+|
+| o  3:4b57d2520816 1:44592833ba9f
+| |
+| | o  2:063f31070f65
+| |/
+| o  1:44592833ba9f
+|/
+o  0:b608b9236435
+
+% norevtest none clean linear 4
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=5
+% norevtest none clean same 2
+abort: crosses branches (use 'hg merge' or use 'hg update -c')
+parent=2
+% revtest none clean linear 1 2
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=2
+% revtest none clean same 2 3
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=3
+% revtest none clean cross 3 4
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=4
+% revtest none dirty linear 1 2
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=2
+M foo
+% revtest none dirty same 2 3
+abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes)
+parent=2
+M foo
+% revtest none dirty cross 3 4
+abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes)
+parent=3
+M foo
+% revtest -C dirty linear 1 2
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=2
+% revtest -c dirty linear 1 2
+abort: uncommitted local changes
+parent=1
+M foo
+% norevtest -c clean same 2
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+parent=3
+% revtest -cC dirty linear 1 2
+abort: cannot specify both -c/--check and -C/--clean
+parent=1
+M foo
--- a/tests/test-verify	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-verify	Sat Nov 07 14:13:15 2009 -0600
@@ -14,6 +14,12 @@
 hg verify
 
 echo
+echo % verify with journal
+touch .hg/store/journal
+hg verify
+rm .hg/store/journal
+
+echo
 echo % introduce some bugs in repo
 cd .hg/store/data
 mv _f_o_o.txt.i X_f_o_o.txt.i
--- a/tests/test-verify.out	Wed Nov 04 22:14:26 2009 +0100
+++ b/tests/test-verify.out	Sat Nov 07 14:13:15 2009 -0600
@@ -10,6 +10,14 @@
 checking files
 3 files, 1 changesets, 3 total revisions
 
+% verify with journal
+abandoned transaction found - run hg recover
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+3 files, 1 changesets, 3 total revisions
+
 % introduce some bugs in repo
 
 % verify